Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / api / ttv / ttv_API_reports.c
1 #include STM_H
2 #include TTV_H
3 #include MLU_H
4 #include MUT_H
5 #include INF_H
6 #include EFG_H
7 #include TAS_H
8 #include TRC_H
9 #include YAG_H
10 #include MCC_H
11 #include STB_H
12
13 #include AVT_H
14 #define API_USE_REAL_TYPES
15 #include "ttv_API_LOCAL.h"
16 #include "ttv_API.h"
17 #include "ttv_API_display.h"
18 #include "ttv_API_util.h"
19 #include "../stb/stb_LOCAL.h"
20 #include "../genius/api_common_structures.h"
21 #include "../ctk/ctk_api_local.h"
22 #include "../ctk/ctk_API.h"
23
24 #define CTK_DIFF_MODE
25
26 //extern long ____stbpatchdelta(ttvpath_list *pth);
27 static int SIMULATE_MODE='n', TTV_API_NOSUPINFO_DETAIL=1 ;
28 static char *LP="";
29 double DISPLAY_time_unit=1e9, DISPLAY_capa_unit=1e12;
30 char *DISPLAY_time_string="ns", *DISPLAY_capa_string="pf", *DISPLAY_time_format="%.3f", *DISPLAY_signed_time_format="%+.3f", *DISPLAY_capa_format=NULL;
31 char DISPLAY_number_justify='r';
32 int DISPLAY_nodemode=1, DISPLAY_time_digits=-1, DISPLAY_hiderc=0;
33 char DISPLAY_errormode=1, probemode=1;
34 char DISPLAY_simdiffmode=0;
35 int ffdebug=0;
36
37 long detail_forced_mode=0;
38
39 typedef struct configentry {
40 char *show;
41 char *code;
42 int column;
43 int father;
44 char *son[5];
45 } configentry;
46
47 char PL_CONFIG_SHOW[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
48
49 configentry PL_CONFIG[]=
50 {
51 {&PL_CONFIG_SHOW[COL_INDEX], "pl.index", COL_INDEX, -1, {NULL, NULL, NULL, NULL, NULL}},
52 {&PL_CONFIG_SHOW[COL_STARTTIME], "pl.starttime", COL_STARTTIME, -1, {NULL, NULL, NULL, NULL, NULL}},
53 {&PL_CONFIG_SHOW[COL_STARTSLOPE], "pl.startslope", COL_STARTSLOPE, -1, {NULL, NULL, NULL, NULL, NULL}},
54 {&PL_CONFIG_SHOW[COL_PATHDELAY], "pl.pathdelay", COL_PATHDELAY, -1, {NULL, NULL, NULL, NULL, NULL}},
55 {&PL_CONFIG_SHOW[COL_TOTALDELAY], "pl.totaldelay", COL_TOTALDELAY, -1, {NULL, NULL, NULL, NULL, NULL}},
56 {&PL_CONFIG_SHOW[COL_DATALAG], "pl.datalag", COL_DATALAG, -1, {NULL, NULL, NULL, NULL, NULL}},
57 {&PL_CONFIG_SHOW[COL_ENDSLOPE], "pl.endslope", COL_ENDSLOPE, -1, {NULL, NULL, NULL, NULL, NULL}},
58 {&PL_CONFIG_SHOW[COL_STARTNODE], "pl.startnode", COL_STARTNODE, -1, {NULL, NULL, NULL, NULL, NULL}},
59 {&PL_CONFIG_SHOW[COL_ENDNODE], "pl.endnode", COL_ENDNODE, -1, {NULL, NULL, NULL, NULL, NULL}}
60 };
61
62
63 char DT_CONFIG_SHOW[]={1,1,1,1,1, 1,1,1,1,1, 1, 1, 1, 1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 0,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1};
64
65 configentry DT_CONFIG[]=
66 {
67 {&DT_CONFIG_SHOW[COL_SIM_ACC], "dt.simacc", COL_SIM_ACC, GLOBAL_COL_SIM, {NULL, NULL, NULL, NULL, NULL}},
68 {&DT_CONFIG_SHOW[COL_SIM_DELTA], "dt.simdelta", COL_SIM_DELTA, GLOBAL_COL_SIM, {NULL, NULL, NULL, NULL, NULL}},
69 {&DT_CONFIG_SHOW[COL_SIM_SLOPE], "dt.simslope", COL_SIM_SLOPE, GLOBAL_COL_SIM, {NULL, NULL, NULL, NULL, NULL}},
70 {&DT_CONFIG_SHOW[COL_SIM_ERROR], "dt.simerror", COL_SIM_ERROR, GLOBAL_COL_SIM, {NULL, NULL, NULL, NULL, NULL}},
71
72 {&DT_CONFIG_SHOW[COL_REF_ACC], "dt.refacc", COL_REF_ACC, GLOBAL_COL_REF, {NULL, NULL, NULL, NULL, NULL}},
73 {&DT_CONFIG_SHOW[COL_REF_DELTA], "dt.refdelta", COL_REF_DELTA, GLOBAL_COL_REF, {NULL, NULL, NULL, NULL, NULL}},
74 {&DT_CONFIG_SHOW[COL_REF_SLOPE], "dt.refslope", COL_REF_SLOPE, GLOBAL_COL_REF, {NULL, NULL, NULL, NULL, NULL}},
75 {&DT_CONFIG_SHOW[COL_REF_LAG_ACC], "dt.reflagacc", COL_REF_LAG_ACC, GLOBAL_COL_REF, {NULL, NULL, NULL, NULL, NULL}},
76 {&DT_CONFIG_SHOW[COL_REF_LAG_DELTA], "dt.reflagdelta", COL_REF_LAG_DELTA, GLOBAL_COL_REF, {NULL, NULL, NULL, NULL, NULL}},
77
78 {&DT_CONFIG_SHOW[COL_CTK_ACC], "dt.ctkacc", COL_CTK_ACC, GLOBAL_COL_CTK, {NULL, NULL, NULL, NULL, NULL}},
79 {&DT_CONFIG_SHOW[COL_CTK_DELTA], "dt.ctkdelta", COL_CTK_DELTA, GLOBAL_COL_CTK, {NULL, NULL, NULL, NULL, NULL}},
80 {&DT_CONFIG_SHOW[COL_CTK_SLOPE], "dt.ctkslope", COL_CTK_SLOPE, GLOBAL_COL_CTK, {NULL, NULL, NULL, NULL, NULL}},
81 {&DT_CONFIG_SHOW[COL_CTK_LAG_ACC], "dt.ctklagacc", COL_CTK_LAG_ACC, GLOBAL_COL_CTK, {NULL, NULL, NULL, NULL, NULL}},
82 {&DT_CONFIG_SHOW[COL_CTK_LAG_DELTA], "dt.ctklagdelta", COL_CTK_LAG_DELTA,GLOBAL_COL_CTK, {NULL, NULL, NULL, NULL, NULL}},
83
84 {&DT_CONFIG_SHOW[COL_CAPA], "dt.capa", COL_CAPA, -1, {NULL, NULL, NULL, NULL, NULL}},
85 {&DT_CONFIG_SHOW[COL_NODETYPE], "dt.nodetype", COL_NODETYPE, -1, {NULL, NULL, NULL, NULL, NULL}},
86 {&DT_CONFIG_SHOW[COL_NODENAME], "dt.nodename", COL_NODENAME, -1, {NULL, NULL, NULL, NULL, NULL}},
87 {&DT_CONFIG_SHOW[COL_NETNAME], "dt.netname", COL_NETNAME, -1, {NULL, NULL, NULL, NULL, NULL}},
88 {&DT_CONFIG_SHOW[COL_LINETYPE], "dt.linetype", COL_LINETYPE, -1, {NULL, NULL, NULL, NULL, NULL}},
89 {&DT_CONFIG_SHOW[COL_TRANSISTORS], "dt.transistors", COL_TRANSISTORS, -1, {NULL, NULL, NULL, NULL, NULL}},
90 {&DT_CONFIG_SHOW[INFO_CMD], "dt.clockinfo", INFO_CMD, -1, {NULL, NULL, NULL, NULL, NULL}},
91
92 {&DT_CONFIG_SHOW[GLOBAL_COL_REF], "", GLOBAL_COL_REF, -1, {&DT_CONFIG_SHOW[COL_REF_ACC],
93 &DT_CONFIG_SHOW[COL_REF_DELTA],
94 &DT_CONFIG_SHOW[COL_REF_SLOPE],
95 NULL,
96 NULL}},
97
98 {&DT_CONFIG_SHOW[GLOBAL_COL_REFLAG], "", GLOBAL_COL_REFLAG, -1, {&DT_CONFIG_SHOW[COL_REF_LAG_ACC],
99 &DT_CONFIG_SHOW[COL_REF_LAG_DELTA],
100 NULL,
101 NULL,
102 NULL}},
103
104 {&DT_CONFIG_SHOW[GLOBAL_COL_CTK], "", GLOBAL_COL_CTK, -1, {&DT_CONFIG_SHOW[COL_CTK_ACC],
105 &DT_CONFIG_SHOW[COL_CTK_DELTA],
106 &DT_CONFIG_SHOW[COL_CTK_SLOPE],
107 NULL,
108 NULL}},
109
110 {&DT_CONFIG_SHOW[GLOBAL_COL_CTKLAG], "", GLOBAL_COL_CTKLAG, -1, {&DT_CONFIG_SHOW[COL_CTK_LAG_ACC],
111 &DT_CONFIG_SHOW[COL_CTK_LAG_DELTA],
112 NULL,
113 NULL,
114 NULL}},
115
116 {&DT_CONFIG_SHOW[GLOBAL_COL_SIM], "", GLOBAL_COL_SIM, -1, {&DT_CONFIG_SHOW[COL_SIM_ACC],
117 &DT_CONFIG_SHOW[COL_SIM_DELTA],
118 &DT_CONFIG_SHOW[COL_SIM_SLOPE],
119 &DT_CONFIG_SHOW[COL_SIM_ERROR],
120 NULL}}
121
122 };
123
124 char STAB_CONFIG_SHOW[]={1,0,1,0,1, 1,1,1,1,1};
125
126 configentry STAB_CONFIG[]=
127 {
128 {&STAB_CONFIG_SHOW[COL_START], "stab.from", COL_START, -1, {NULL, NULL, NULL, NULL, NULL}},
129 {&STAB_CONFIG_SHOW[COL_LATCH], "stab.thru", COL_LATCH, -1, {NULL, NULL, NULL, NULL, NULL}},
130 };
131
132
133 PATH_MORE_INFO_TYPE PATH_MORE_INFO={0, {{0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0},
134 {0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0}, {0, NULL, 0}}};
135
136 void ttv_DumpHeader(FILE *f, ttvfig_list *tvf)
137 {
138 struct tm tms;
139 char buf[1024], thedate[128];
140 time_t mytime;
141
142 if (tvf==NULL) return;
143
144 tms.tm_sec=tvf->INFO->TTVSEC;
145 tms.tm_min=tvf->INFO->TTVMIN;
146 tms.tm_hour=tvf->INFO->TTVHOUR;
147 tms.tm_mday=tvf->INFO->TTVDAY;
148 tms.tm_mon=(tvf->INFO->TTVMONTH-1);
149 tms.tm_year=tvf->INFO->TTVYEAR-1900;
150 tms.tm_isdst=-1;
151
152 mytime=mktime(&tms);
153
154 #ifdef Solaris
155 ctime_r(&mytime, thedate, 52);
156 #else
157 ctime_r(&mytime, thedate);
158 #endif
159 thedate[strlen(thedate)-1] = '\0';
160 sprintf(buf,
161 "Timing figure: %s generated on %s\n"
162 " supply: %g temperature: %g\n"
163 " slope thresholds : %g / %g\n"
164 " delay threshold : %g\n",
165 tvf->INFO->FIGNAME, thedate,
166 tvf->INFO->VDD, tvf->INFO->TEMP,
167 tvf->INFO->STHLOW, tvf->INFO->STHHIGH,
168 tvf->INFO->DTH
169 );
170
171 avt_printExecInfo(f, "#", buf, "");
172 }
173
174 static void settimeformat(int nb)
175 {
176 char buf[20];
177
178 sprintf(buf,"%%.%df",nb);
179 DISPLAY_time_format=sensitive_namealloc(buf);
180 sprintf(buf,"%%+.%df",nb);
181 DISPLAY_signed_time_format=sensitive_namealloc(buf);
182 }
183
184 void _ttv_Board_SetValue(char *tab, int scol, Board *B, int col, char *val)
185 {
186 if (tab[scol]) Board_SetValue(B, col, val);
187 }
188
189 void _ttv_Board_SetSize(char *tab, int scol, Board *B, int col, int size, char align)
190 {
191 if (tab[scol]) Board_SetSize(B, col, size, align);
192 }
193
194 void _ttv_Board_SetSep(char *tab, int scol, Board *B, int col)
195 {
196 if (tab[scol]) Board_SetSep(B, col);
197 }
198
199 void ttv_SetupReport(char *val)
200 {
201 char buf[1024];
202 char *tok, *c;
203
204 strcpy(buf, val);
205 tok=strtok_r(buf, " ", &c);
206 while (tok!=NULL)
207 {
208 if (strcasecmp(tok,"ps")==0)
209 {
210 DISPLAY_time_unit=1e12;
211 DISPLAY_time_string="ps";
212 if (DISPLAY_time_digits==-1) settimeformat(1);
213 }
214 else if (strcasecmp(tok,"ns")==0)
215 {
216 DISPLAY_time_unit=1e9;
217 DISPLAY_time_string="ns";
218 if (DISPLAY_time_digits==-1) settimeformat(3);
219 }
220 else if (strcasecmp(tok,"pf")==0) {DISPLAY_capa_unit=1e12; DISPLAY_capa_string="pf";DISPLAY_capa_format=NULL;}
221 else if (strcasecmp(tok,"ff")==0) {DISPLAY_capa_unit=1e15; DISPLAY_capa_string="ff";DISPLAY_capa_format="%.2f";}
222 else if (strcasecmp(tok,"justifyright")==0) {DISPLAY_number_justify='r';}
223 else if (strcasecmp(tok,"justifyleft")==0) {DISPLAY_number_justify='l';}
224 else if (strcasecmp(tok,"onlynetname")==0) {DISPLAY_nodemode=0;}
225 else if (strcasecmp(tok,"nodename")==0) {DISPLAY_nodemode=1;}
226 else if (strcasecmp(tok,"hiderc")==0) {DISPLAY_hiderc=1;}
227 else if (strcasecmp(tok,"showrc")==0) {DISPLAY_hiderc=0;}
228 else if (strcasecmp(tok,"pathcomp")==0) DISPLAY_simdiffmode=1;
229 else if (strcasecmp(tok,"!pathcomp")==0) DISPLAY_simdiffmode=0;
230 else if (strcasecmp(tok,"!debug")==0) ffdebug=0;
231 else if (strcasecmp(tok,"debug")==0) ffdebug=1;
232 else if (strcasecmp(tok,"!supdetail")==0) TTV_API_NOSUPINFO_DETAIL=1;
233 else if (strcasecmp(tok,"supdetail")==0) TTV_API_NOSUPINFO_DETAIL=0;
234 else if (strcasecmp(&tok[1],"digits")==0)
235 {
236 int nb=tok[0]-'0';
237 if (nb<0 || nb>6)
238 {
239 nb=3;
240 avt_errmsg(TTV_API_ERRMSG, "037", AVT_ERROR, nb);
241 // avt_error("ttvapi", 502, AVT_ERR, "ttv_SetReportUnit: error, setting digits to %d\n", nb);
242 }
243 DISPLAY_time_digits=nb;
244 settimeformat(DISPLAY_time_digits);
245 }
246 else if (strcasecmp(tok,"localerror")==0) {DISPLAY_errormode=0;}
247 // ----- HIDDEN : FOR DEBUG PURPOSE ----
248 else if (strcasecmp(tok,"probe-noprop")==0) {probemode=0;}
249 else if (strcasecmp(tok,"probe-prop")==0) {probemode=1;}
250 //----
251 else //avt_error("ttvapi", 502, AVT_ERR, "ttv_SetReportUnit: unknown unit/setup '%s'\n", tok);
252 avt_errmsg(TTV_API_ERRMSG, "038", AVT_ERROR, tok);
253
254 tok=strtok_r(NULL, " ", &c);
255 }
256 }
257
258 char *ttv_GetFullSignalName_COND(ttvfig_list *tf, ttvsig_list *sg)
259 {
260 if (DISPLAY_nodemode) return ttv_GetFullSignalName(tf, sg);
261 else return ttv_GetFullSignalNetName(tf, sg);
262 }
263
264 char *ttv_GetDetailSignalName_COND(ttvcritic_list *tc)
265 {
266 if (DISPLAY_nodemode) return ttv_GetDetailNodeName(tc);
267 else return ttv_GetDetailSignalName(tc);
268 }
269
270 void ttv_SetReportUnit(char *val)
271 {
272 avt_errmsg(TTV_API_ERRMSG, "039", AVT_WARNING);
273 // fprintf (stderr, "warning, ttv_SetReportUnit is obsolete, use ttv_SetupReport\n");
274 ttv_SetupReport(val);
275 }
276
277 void ttvapi_setprefix(char *val)
278 {
279 LP=val;
280 }
281
282 void ttvapi_setdislaytab(int nb)
283 {
284 switch (nb)
285 {
286 case 0: LP=""; break;
287 case 1: LP=" "; break;
288 case 2: LP=" "; break;
289 case 3: LP=" "; break;
290 default:
291 case 4: LP=" "; break;
292 }
293 }
294
295 static char dirconv(char dir)
296 {
297 if (dir=='u') return 'R';
298 else if (dir=='d') return 'F';
299 exit(5);
300 }
301
302 static int isclock(ttvsig_list *ts)
303 {
304 if (getptype(ts->USER, TTV_SIG_CLOCK)!=NULL) return 1;
305 return 0;
306 }
307
308 static char *typeconv(char *type, long sigtype, char *buf)
309 {
310 int i=0;
311
312 if (((sigtype & TTV_SIG_CZ) == TTV_SIG_CZ)
313 || ((sigtype & TTV_SIG_CT) == TTV_SIG_CT))
314 {
315 buf[i++]='S'; buf[i++]='Z';
316 }
317 else
318 if ((sigtype & TTV_SIG_CO) == TTV_SIG_CO) buf[i++]='S';
319
320 if (strstr(type,"latch")!=NULL) buf[i++]='L';
321 if (strstr(type,"precharge")!=NULL) buf[i++]='N';
322 if (strstr(type,"flip-flop")!=NULL) buf[i++]='F';
323 if (strstr(type,"breakpoint")!=NULL) buf[i++]='B';
324 if (strstr(type,"command")!=NULL) buf[i++]='K';
325 buf[i++]='\0';
326 return buf;
327 }
328
329 char *FormaT(double val, char *buf, char *formatnum)
330 {
331 if (formatnum==NULL)
332 sprintf(buf,"%.3f",val);
333 else
334 sprintf(buf,formatnum,val);
335 return buf;
336 }
337
338 void ttv_DisplayConfig(FILE *f, chain_list *tpl)
339 {
340 ttvpath_list *tp;
341 if (tpl==NULL || f==NULL) return;
342 tp=(ttvpath_list *)tpl->DATA;
343
344 if (ftello(f)==0)
345 ttv_DumpHeader(f,tp->FIG);
346
347 // avt_fprintf(f, " Process : ?\n");
348 avt_fprintf(f, " Voltage : %gV\n", ttv_GetTimingFigureSupply(tp->FIG));
349 avt_fprintf(f, " Temperature : %g degree C\n\n", ttv_GetTimingFigureTemperature(tp->FIG));
350 }
351
352 void ttv_DisplayActivateSimulation(char mode)
353 {
354 mode=tolower(mode);
355 if (mode!='y' && mode!='n')
356 {
357 avt_errmsg(TTV_API_ERRMSG, "040", AVT_ERROR);
358 // avt_error("ttvapi", 500, AVT_ERR, "ttv_DisplaySimulation: valid values for mode are 'y' or 'n'\n");
359 return;
360 }
361
362 SIMULATE_MODE=mode;
363 }
364
365 void ttv_DisplayLegend(FILE *f)
366 {
367 if (f==NULL) return;
368 avt_fprintf(f, "Node type Index:\n");
369 avt_fprintf(f, " (C) : Clock node (L) : Latch node (F) : Flip-flop node\n");
370 avt_fprintf(f, " (B) : Breakpoint node (K) : Latch command node (S) : Output connector node\n");
371 avt_fprintf(f, " (SZ): Output HZ connector (N) : Precharge node\n\n");
372 }
373
374
375
376
377 static void _ttv_DisplayPath(int number, ttvpath_list *tp, Board *b)
378 {
379 double delay, slope, starttime, startslope, datalag;
380 char *startsig, *endsig;
381 ttvsig_list *sg;
382 char startdir, enddir;
383 char buf[20];
384
385 sg=ttv_GetPathStartSignal(tp);
386 startsig=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(sg), sg);
387
388 sg=ttv_GetPathEndSignal(tp);
389 endsig=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(sg), sg);
390
391 startdir=dirconv(ttv_GetPathStartDirection(tp));
392 enddir=dirconv(ttv_GetPathEndDirection(tp));
393 delay=ttv_GetPathDelay(tp)*DISPLAY_time_unit;
394 slope=ttv_GetPathSlope(tp)*DISPLAY_time_unit;
395 startslope=ttv_GetPathStartSlope(tp)*DISPLAY_time_unit;
396 starttime=ttv_GetPathStartTime(tp)*DISPLAY_time_unit;
397 datalag=ttv_GetPathDataLag(tp)*DISPLAY_time_unit;
398
399 sprintf(buf,"%d",number);
400 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_INDEX, b, COL_INDEX, buf);
401 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_STARTTIME, FormaT(starttime, buf, DISPLAY_time_format));
402 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_STARTSLOPE, FormaT(startslope, buf, DISPLAY_time_format));
403 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATHDELAY, FormaT(delay, buf, DISPLAY_time_format));
404 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_TOTALDELAY, FormaT(delay+datalag, buf, DISPLAY_time_format));
405 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_DATALAG, b, COL_DATALAG, FormaT(datalag, buf, DISPLAY_time_format));
406 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_ENDSLOPE, FormaT(slope, buf, DISPLAY_time_format));
407
408 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE, startsig);
409 sprintf(buf,"(%c)",startdir);
410 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE_DIR, buf);
411
412 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE, endsig);
413
414 buf[0]='(';
415 buf[1]=enddir;
416 if (ttv_PathIsHZ(tp)) {strcpy(&buf[2],"Z)");}
417 else {strcpy(&buf[2],")"); }
418
419 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE_DIR, buf);
420 }
421
422 void ttv_DisplayPathList(FILE *f, chain_list *tpl)
423 {
424 ttvpath_list *tp;
425 int count=1;
426 Board *b;
427
428 if (f==NULL) return;
429
430 b=Board_CreateBoard();
431
432 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_INDEX, b, COL_INDEX, 5, 'r');
433 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_STARTTIME, 7, DISPLAY_number_justify);
434 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_STARTSLOPE, 7, DISPLAY_number_justify);
435 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATHDELAY, 7, DISPLAY_number_justify);
436 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_TOTALDELAY, 7, DISPLAY_number_justify);
437 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_DATALAG, b, COL_DATALAG, 7, DISPLAY_number_justify);
438 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_ENDSLOPE, 7, DISPLAY_number_justify);
439 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE, 20, 'l');
440 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE_DIR, 3, 'l');
441 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE, 20, 'l');
442 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE_DIR, 3, 'l');
443
444 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_PATH_SEP0);
445 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_PATH_SEP1);
446 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATH_SEP2);
447 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_PATH_SEP3);
448 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_DATALAG, b, COL_PATH_SEP4);
449 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_PATH_SEP5);
450 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_PATH_SEP6);
451 _ttv_Board_SetSep(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_PATH_SEP7);
452
453
454 Board_NewLine(b);
455 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_INDEX, b, COL_INDEX, "Path");
456 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_STARTTIME, "Start");
457 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_STARTSLOPE, "Start");
458 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATHDELAY, "Path");
459 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_TOTALDELAY, "Total");
460 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_DATALAG, b, COL_DATALAG, "Data");
461 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_ENDSLOPE, "Ending");
462 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE, "Start");
463
464 Board_NewLine(b);
465
466 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_STARTTIME, "time");
467 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_STARTSLOPE, "slope");
468 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATHDELAY, "delay");
469 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_TOTALDELAY, "delay");
470 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_DATALAG, b, COL_DATALAG, "lag");
471 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_ENDSLOPE, "slope");
472 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_STARTNODE,b, COL_STARTNODE, "From_node");
473 _ttv_Board_SetValue(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE, "To_node");
474
475 Board_NewSeparation(b);
476
477 while (tpl!=NULL)
478 {
479 tp=(ttvpath_list *)tpl->DATA;
480 Board_NewLine(b);
481 _ttv_DisplayPath(count, tp, b);
482 count++;
483 tpl=tpl->NEXT;
484 }
485
486 Board_Display(f, b, LP);
487 Board_FreeBoard(b);
488
489 avt_fprintf(f, "\n");
490 fflush(f);
491 }
492 /*
493 void ttv_DisplayPath(FILE *f, int number, ttvpath_list *tp)
494 {
495 Board *b;
496
497 if (f==NULL) return;
498
499 b=Board_CreateBoard();
500
501 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_INDEX, b, COL_INDEX, 5, 'r');
502 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTTIME, b, COL_STARTTIME, 7, DISPLAY_number_justify);
503 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTSLOPE, b, COL_STARTSLOPE, 7, DISPLAY_number_justify);
504 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_PATHDELAY, b, COL_PATHDELAY, 7, DISPLAY_number_justify);
505 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_TOTALDELAY, b, COL_TOTALDELAY, 7, DISPLAY_number_justify);
506 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_DATALAG, b, COL_DATALAG, 7, DISPLAY_number_justify);
507 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDSLOPE, b, COL_ENDSLOPE, 7, DISPLAY_number_justify);
508 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE, 20, 'l');
509 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_STARTNODE, b, COL_STARTNODE_DIR, 3, 'l');
510 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE, 20, 'l');
511 _ttv_Board_SetSize(PL_CONFIG_SHOW, COL_ENDNODE, b, COL_ENDNODE_DIR, 3, 'l');
512
513 _ttv_DisplayPath(number, tp, b);
514
515 Board_Display(f, b, LP);
516 Board_FreeBoard(b);
517 }
518 */
519 static void checksetup(configentry *configtab, int nb, char *tok, int mode)
520 {
521 int i, j;
522 for (i=0; i<nb; i++)
523 {
524 if (strlen(configtab[i].code)==0)
525 {
526 *configtab[i].show=0;
527 for (j=0; j<5 && configtab[i].son[j]!=NULL; j++)
528 if (*(configtab[i].son[j])) {*configtab[i].show=1; break;}
529 }
530 else if (strcasecmp(tok,"all")==0 || mbk_TestREGEX(configtab[i].code, tok))
531 {
532 if (mode==0) *configtab[i].show=1;
533 else *configtab[i].show=0;
534 }
535 }
536 }
537
538 void __ttv_DisplayPathDetailShowColumn(char *conf, int mode)
539 {
540 char *c, *tok;
541 char buf[1024];
542 char oldsens;
543
544 oldsens=CASE_SENSITIVE;
545 CASE_SENSITIVE='N';
546
547
548 strcpy(buf, conf);
549 tok=strtok_r(buf, " ", &c);
550 while (tok!=NULL)
551 {
552 if (strcasecmp(tok,"ref")==0) tok="dt.ref*";
553 if (strcasecmp(tok,"reflag")==0) tok="dt.reflag*";
554 if (strcasecmp(tok,"ctk")==0) tok="dt.ctk*";
555 if (strcasecmp(tok,"ctklag")==0) tok="dt.ctklag*";
556 if (strcasecmp(tok,"sim")==0) tok="dt.sim*";
557 if (strcasecmp(tok,"trans")==0) tok="dt.transistors";
558 if (strcasecmp(tok,"cmdinfo")==0) tok="dt.clockinfo";
559 // if (strcasecmp(tok,"all")==0) tok="*";
560
561 checksetup(PL_CONFIG, sizeof(PL_CONFIG)/sizeof(*PL_CONFIG), tok, mode);
562 checksetup(DT_CONFIG, sizeof(DT_CONFIG)/sizeof(*DT_CONFIG), tok, mode);
563 checksetup(STAB_CONFIG, sizeof(STAB_CONFIG)/sizeof(*STAB_CONFIG), tok, mode);
564 // checksetup(C2L_CONFIG, sizeof(C2L_CONFIG)/sizeof(*C2L_CONFIG), tok, mode);
565
566 tok=strtok_r(NULL, " ", &c);
567 }
568
569 CASE_SENSITIVE=oldsens;
570 }
571
572 void ttv_DisplayPathDetailShowColumn(char *conf)
573 {
574 __ttv_DisplayPathDetailShowColumn(conf, 0);
575 }
576
577 void ttv_DisplayPathDetailHideColumn(char *conf)
578 {
579 __ttv_DisplayPathDetailShowColumn(conf, 1);
580 }
581
582
583 double stb_periodmove(char dir, stbdebug_list *dbl)
584 {
585 double val, v;
586 char tdir='u';
587 if (dbl==NULL) return 0;
588 val=dbl->UPDELTA*1e-12/TTV_UNIT;
589 v=dbl->DOWNDELTA*1e-12/TTV_UNIT;
590 if (v>val) val=v, tdir='d';
591 if (tdir!=dir) return val;
592 return 0;
593 }
594
595 double stb_getperiodmove(char dir, stbdebug_list *dbl)
596 {
597 if (dbl==NULL) return 0;
598 if (dir=='u') return dbl->UPDELTA*1e-12/TTV_UNIT;
599 if (dir=='d') return dbl->DOWNDELTA*1e-12/TTV_UNIT;
600 return 0;
601 }
602
603 void ttv_GetNodeSpecout(ttvevent_list *latch, double unit, char *unitformat, char *res, stbdebug_list *dbl, ttvpath_list *tp, int setuphold, long dec)
604 {
605 stbnode *node;
606 double u=-1, d=-1;
607 char bufu[64], bufd[64];
608 stbpair_list *instab, *originstab;
609 char index;
610 long period;
611
612 node=stb_getstbnode(latch);
613
614 strcpy(res,"");
615
616 if (node!=NULL && node->SPECOUT!=NULL)
617 {
618 if (node->CK!=NULL)
619 {
620 index = node->CK->CKINDEX;
621 period = node->CK->PERIOD;
622 }
623 else
624 {
625 index = STB_NO_INDEX;
626 period = STB_NO_TIME;
627 }
628
629 originstab = stb_nodeglobalpair (node->SPECOUT, period, node->NBINDEX, index);
630
631 if (originstab!=NULL)
632 {
633 instab=originstab;
634 if (instab!=NULL) d=instab->D;
635 while (instab!=NULL)
636 u=instab->U, instab=instab->NEXT;
637
638 u=_LONG_TO_DOUBLE(u+dec);
639 d=_LONG_TO_DOUBLE(d+dec);
640 sprintf(bufu, unitformat, u*unit);
641 sprintf(bufd, unitformat, d*unit);
642
643 if (setuphold)
644 sprintf(res,"Must be stable after %s", bufu);
645 else
646 sprintf(res,"Must be stable before %s", bufd);
647
648 stb_freestbpair (originstab);
649 }
650 }
651 }
652
653
654 void ttv_GetNodeClock(ttvevent_list *tve, ttvevent_list *latch, double unit, char *unitstring, char *unitformat, char *res, stbdebug_list *dbl, ttvpath_list *tp)
655 {
656 stbnode *node;
657 stbck *clock;
658 char bufrise[64], buffall[64], bufperiod[64], format[64];
659 double risemin, risemax, fallmin, fallmax, per;
660 int inverted;
661 char *rise="RISE", *fall="FALL";
662 stbfig_list *sb;
663
664 node=stb_getstbnode(latch);
665 strcpy(res,"");
666 if (node!=NULL)
667 {
668 clock=node->CK;
669 sb= stb_getstbfig(ttv_GetTopTimingFigure(tve->ROOT->ROOT));
670 clock=stb_getgoodclock_and_status(sb, clock, tve, latch, &inverted);
671 if (inverted) rise="FALL", fall="RISE";
672 if (clock!=NULL)
673 {
674 per=(clock->PERIOD/TTV_UNIT)*1e-12;
675 risemin=((clock->SUPMIN/TTV_UNIT)*1e-12);
676 risemax=((clock->SUPMAX/TTV_UNIT)*1e-12);
677 fallmin=((clock->SDNMIN/TTV_UNIT)*1e-12);
678 fallmax=((clock->SDNMAX/TTV_UNIT)*1e-12);
679
680 risemin+=stb_getperiodmove('u', dbl);
681 risemax+=stb_getperiodmove('u', dbl);
682 fallmin+=stb_getperiodmove('d', dbl);
683 fallmax+=stb_getperiodmove('d', dbl);
684
685 if ((tp->TYPE & TTV_FIND_MAX)!=TTV_FIND_MAX)
686 {
687 // hold
688 risemin-=per;
689 risemax-=per;
690 fallmin-=per;
691 fallmax-=per;
692 }
693
694 risemin+=stb_periodmove('u', dbl);
695 risemax+=stb_periodmove('u', dbl);
696 fallmin+=stb_periodmove('d', dbl);
697 fallmax+=stb_periodmove('d', dbl);
698
699 risemin*=unit;
700 risemax*=unit;
701 fallmin*=unit;
702 fallmax*=unit;
703
704 if (clock->PERIOD!=STB_NO_TIME)
705 {
706 sprintf(format, "PERIOD = %s", unitformat);
707 sprintf(bufperiod, format, per*unit);
708 }
709 else
710 strcpy(bufperiod, "PERIOD = NONE");
711
712 if (clock->SUPMIN!=STB_NO_TIME)
713 {
714 if (clock->SUPMIN==clock->SUPMAX)
715 {
716 sprintf(format, "%s = %s", rise, unitformat);
717 sprintf(bufrise, format, risemin);
718 }
719 else
720 {
721 sprintf(format, "%s = (%s:%s)", rise, unitformat, unitformat);
722 sprintf(bufrise, format, risemin, risemax);
723 }
724 }
725 else
726 sprintf(bufrise, "%s = NONE", rise);
727
728 if (clock->SDNMIN!=STB_NO_TIME)
729 {
730 if (clock->SDNMIN==clock->SDNMAX)
731 {
732 sprintf(format, "%s = %s", fall, unitformat);
733 sprintf(buffall, format, fallmin);
734 }
735 else
736 {
737 sprintf(format, "%s = (%s:%s)", fall, unitformat, unitformat);
738 sprintf(buffall, format, fallmin, fallmax);
739 }
740 }
741 else
742 sprintf(buffall, "%s = NONE", fall);
743
744 if (clock->SUPMIN<clock->SDNMIN)
745 sprintf(res,"%s %s ", bufrise, buffall);
746 else
747 sprintf(res,"%s %s ", buffall, bufrise);
748
749 strcat(res, bufperiod);
750 }
751 }
752 }
753
754 static void ttv_GetNodeIntrinsicInfo(ttvevent_list *tve, ttvevent_list *latch, double unit, char *unitstring, char *unitformat, char *res, int access)
755 {
756 stbnode *node;
757 stbck *clock;
758 char bufrise[64], format[64];
759 int inverted;
760 stbfig_list *sb;
761
762 node=stb_getstbnode(latch);
763 strcpy(res,"");
764 if (node!=NULL)
765 {
766 clock=node->CK;
767 sb= stb_getstbfig(ttv_GetTopTimingFigure(tve->ROOT->ROOT));
768 clock=stb_getgoodclock_and_status(sb, clock, tve, latch, &inverted);
769 if (clock!=NULL)
770 {
771 if (access)
772 {
773 if (clock->ACCESSMIN!=STB_NO_TIME)
774 {
775 sprintf(format, " ACCESS_MIN = %s", unitformat);
776 sprintf(bufrise, format, ((clock->ACCESSMIN/TTV_UNIT)*1e-12)*unit);
777 strcat(res, bufrise);
778 }
779 if (clock->ACCESSMAX!=STB_NO_TIME)
780 {
781 sprintf(format, " ACCESS_MAX = %s", unitformat);
782 sprintf(bufrise, format, ((clock->ACCESSMAX/TTV_UNIT)*1e-12)*unit);
783 strcat(res, bufrise);
784 }
785 }
786 else
787 {
788 if (clock->HOLD!=STB_NO_TIME)
789 {
790 sprintf(format, " HOLD_MARGIN = %s", unitformat);
791 sprintf(bufrise, format, ((clock->HOLD/TTV_UNIT)*1e-12)*unit);
792 strcat(res, bufrise);
793 }
794 if (clock->SETUP!=STB_NO_TIME)
795 {
796 sprintf(format, " SETUP_MARGIN = %s", unitformat);
797 sprintf(bufrise, format, ((clock->SETUP/TTV_UNIT)*1e-12)*unit);
798 strcat(res, bufrise);
799 }
800 }
801 }
802 }
803 }
804
805 int stb_fill_noise_on_detail(ttvfig_list *tvf, chain_list *detail)
806 {
807 stbfig_list *sb;
808 stb_ctk_stat *stat;
809 ttvcritic_list *tc;
810 PATH_NOISE_TYPE *pnt;
811 int idx;
812
813 if (tvf==NULL || (sb=stb_getstbfig(tvf))==NULL) return 0;
814 if ((stat = stb_ctk_get_stat(sb))==NULL) return 0;
815 while (detail!=NULL)
816 {
817 tc=(ttvcritic_list *)detail->DATA;
818 idx=ctk_GetCtkStatNodeFromEvent(sb, tc->NODE);
819 if (idx>0)
820 {
821 idx--;
822 pnt=(PATH_NOISE_TYPE *)mbkalloc(sizeof(PATH_NOISE_TYPE));
823 pnt->N=stb_ctk_get_score_noise( &stat->TAB[idx] );
824 pnt->I=stb_ctk_get_score_interval( &stat->TAB[idx] );
825 pnt->A=stb_ctk_get_score_activity( &stat->TAB[idx] );
826 pnt->T=stb_ctk_get_score_total( &stat->TAB[idx] );
827 pnt->C=stb_ctk_get_score_ctk( &stat->TAB[idx] );
828 pnt->P=stb_ctk_get_score_probability( &stat->TAB[idx] );
829 tc->USER=addptype(tc->USER, PATH_NOISE_PTYPE, pnt);
830 }
831 detail=detail->NEXT;
832 }
833 return 1;
834 }
835
836 void stb_free_noise_on_detail(chain_list *detail)
837 {
838 ptype_list *pt;
839 ttvcritic_list *tc;
840 while (detail!=NULL)
841 {
842 tc=(ttvcritic_list *)detail->DATA;
843 if ((pt=getptype(tc->USER, PATH_NOISE_PTYPE))!=NULL)
844 {
845 mbkfree(pt->DATA);
846 tc->USER=delptype(tc->USER, PATH_NOISE_PTYPE);
847 }
848 detail=detail->NEXT;
849 }
850 }
851
852 void ttv_DisplayCompletePathDetail(FILE *f, int num, ttvpath_list *tp, chain_list *detail)
853 {
854 chain_list *detailbase;
855 ttvcritic_list *tc, *tc1;
856 double capa;
857 double accsim=0, slopesim, deltasim;
858 double accref=0, sloperef, deltaref;
859 double accctk=0, slopectk, deltactk;
860 double acclag=0, deltalag;
861 double accreflag=0, deltareflag, start=0, error;
862 char nodetype[20], *nodename, *netname, dir, *delaytype="";
863 char *prevnetname=NULL, prevdir, ztag, *acclabel="Acc ", *deltalabel="Delta", *linelabel="Line";
864 char buf[4096], buf1[20], format[256], *colcode="";
865 int simerror=0;
866 int hidereflag=(DT_CONFIG_SHOW[GLOBAL_COL_REFLAG]+1)&1, hidectklag=(DT_CONFIG_SHOW[GLOBAL_COL_CTKLAG]+1)&1, hidectk=(DT_CONFIG_SHOW[GLOBAL_COL_CTK]+1)&1, hideref=(DT_CONFIG_SHOW[GLOBAL_COL_REF]+1)&1, hidesim=(DT_CONFIG_SHOW[GLOBAL_COL_SIM]+1)&1;
867 int tm, mergerc=0, addc=0, i, split=0, ideal_clock_path=1, has_stat;
868 chain_list *trlist, *clock_tree;
869 ttvevent_list *tve;
870 char searchtype;
871 ptype_list *pt=NULL, *pt_debug=NULL, *pt_more=NULL, *ptype, *idealptype=NULL;
872 Board *b;
873 double errorref, simval_cmp, tasval_cmp, start_cmp;
874 stb_clock_latency_information *scli;
875 stbfig_list *sb=NULL;
876 ttv_line_ssta_info *tlsi=NULL;
877
878 if (f==NULL) return;
879
880 if (tp!=NULL && tp->FIG!=NULL)
881 {
882 sb=stb_getstbfig(tp->FIG);
883 tlsi=ttv_ssta_get_ssta_info(tp->FIG);
884 }
885
886 if (tp!=NULL)
887 {
888 pt=getptype(tp->USER, SLACK_PTYPE);
889 pt_debug=getptype(tp->USER, DEBUG_PTYPE);
890 pt_more=getptype(tp->USER, MORE_PTYPE);
891 idealptype=getptype(tp->USER, STB_IDEAL_CLOCK);
892 }
893
894 if (num>=0) avt_fprintf(f, "%sPath (%d) : ", LP, num);
895
896 if ((detail_forced_mode & NOSUPINFO_DETAIL)==0)
897 {
898 if (pt==NULL)
899 {
900 if (tp!=NULL && tp->LATCH!=NULL && ttv_GetPathDataLag(tp)!=0)
901 {
902 avt_fprintf(f, " %sData LAG on latch %s is %s", delaytype, tp->LATCH->ROOT->NAME, FormaT(ttv_GetPathDataLag(tp)*DISPLAY_time_unit, buf, DISPLAY_time_format));
903 delaytype="// ";
904 }
905 if ((tve=ttv_GetPathAccessLatchCommand(tp))!=NULL)
906 {
907 avt_fprintf(f, " %sPath Access Command %s(%c)", delaytype, ttv_GetFullSignalName_COND(tp->FIG, tve->ROOT), dirconv(ttv_GetTimingEventDirection(tve)));
908 delaytype="// ";
909 }
910 if (strcmp(delaytype,"")!=0 || num>=0) avt_fprintf(f, "\n\n");
911 else avt_fprintf(f, "\n");
912 }
913 else
914 {
915 if (num>=0)
916 {
917 avt_fprintf(f, " Slack of %s", FormaT((((long)pt->DATA)*1e-13)*DISPLAY_time_unit, buf, DISPLAY_time_format));
918 avt_fprintf(f, "\n",LP);
919 }
920 }
921 }
922 else if (num>=0) avt_fprintf(f, "\n");
923
924 detailbase=detail;
925
926 if (detail==NULL) return;
927
928 has_stat=stb_fill_noise_on_detail(tp!=NULL?tp->FIG:NULL, detailbase);
929
930 tc=(ttvcritic_list *)detail->DATA;
931 if (ttv_GetDetailSimDelay(tc)==-1) hidesim=1;
932 if (tp==NULL) split=0;
933 else
934 {
935 // tm=(int)((ttv_GetPathDelay(tp)-ttv_GetPathRefDelay(tp))*1e12);
936 if ((sb!=NULL && sb->CTKMODE & STB_CTK)/* || (tp!=NULL && (ttv_getloadedfigtypes(tp->FIG) & TTV_FILE_CTX)==TTV_FILE_CTX)*/) split=1;
937 else split=0;
938 }
939
940 if (tp==NULL || ttv_GetPathDataLag(tp)==0) { hidectklag=1; hidereflag=1; }
941 if (!split) hideref=1, hidereflag=1;
942 #ifdef CTK_DIFF_MODE
943 else hidereflag=0;
944 #endif
945 b=Board_CreateBoard();
946
947 if (detail!=NULL && tp!=NULL)
948 clock_tree=get_clock_latency_tree(tp->NODE, tp->TYPE, NULL);
949 else
950 clock_tree=NULL;
951
952 if (clock_tree!=NULL) acclabel="Time ", deltalabel="Latency", linelabel="Period";
953
954 if (DT_CONFIG_SHOW[COL_LINETYPE]==0 || DISPLAY_hiderc) mergerc=1;
955
956 if (!hidesim)
957 {
958 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, 7, DISPLAY_number_justify);
959 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, 7, DISPLAY_number_justify);
960 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_SIM_SLOPE, b, COL_SIM_SLOPE, 7, DISPLAY_number_justify);
961 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_SIM_ERROR, b, COL_SIM_ERROR, 5, 'r');
962 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_DET_SEP_SIM);
963 }
964
965 if (!hideref)
966 {
967 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, 7, DISPLAY_number_justify);
968 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, 7, DISPLAY_number_justify);
969 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_SLOPE, b, COL_REF_SLOPE, 7, DISPLAY_number_justify);
970 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_DET_SEP_REF);
971 }
972 if (!hidereflag)
973 {
974 #ifndef CTK_DIFF_MODE
975 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, 7, DISPLAY_number_justify);
976 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, 7, DISPLAY_number_justify);
977 #else
978 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, 5, 'r');
979 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, 5, 'r');
980 #endif
981 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_DET_SEP_REF_LAG);
982 }
983
984 if (!hidectk)
985 {
986 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, 7, DISPLAY_number_justify);
987 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, 7, DISPLAY_number_justify);
988 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CTK_SLOPE, b, COL_CTK_SLOPE, 7, DISPLAY_number_justify);
989 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_DET_SEP_CTK);
990 }
991 if (!hidectklag)
992 {
993 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, 7, DISPLAY_number_justify);
994 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, 7, DISPLAY_number_justify);
995 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_DET_SEP_CTK_LAG);
996 }
997
998 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_CAPA, b, COL_CAPA, 5, DISPLAY_number_justify);
999 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_NODETYPE, 4, 'r');
1000 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_NODENAME, b, COL_NODENAME, 20, 'l');
1001 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_NETNAME, b, COL_NETNAME, 20, 'l');
1002 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, 4, 'r');
1003 if (!ffdebug)
1004 _ttv_Board_SetSize(DT_CONFIG_SHOW, COL_TRANSISTORS, b, COL_TRANSISTORS, 9, 'l');
1005 else
1006 Board_SetSize(b, COL_TRANSISTORS, 9, 'l');
1007
1008
1009 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_CAPA, b, COL_DET_SEP_CAPA);
1010 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_DET_SEP_NODETYPE);
1011 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_NODENAME, b, COL_DET_SEP_NODENAME);
1012 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_NETNAME, b, COL_DET_SEP_NETNAME);
1013 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_DET_SEP_LINETYPE);
1014 if (!ffdebug)
1015 _ttv_Board_SetSep(DT_CONFIG_SHOW, COL_TRANSISTORS, b, COL_DET_SEP_TRANSISTORS);
1016 else
1017 Board_SetSep(b, COL_DET_SEP_TRANSISTORS);
1018
1019 if (has_stat)
1020 {
1021 Board_SetSize(b, COL_CTK_SCORE_TOT, 2, 'r');
1022 Board_SetSize(b, COL_CTK_SCORE_NOISE, 2, 'r');
1023 Board_SetSize(b, COL_CTK_SCORE_CTK, 2, 'r');
1024 Board_SetSize(b, COL_CTK_SCORE_ACTIV, 2, 'r');
1025 Board_SetSize(b, COL_CTK_SCORE_INTERV, 2, 'r');
1026 Board_SetSize(b, COL_CTK_SCORE_PROBA, 2, 'r');
1027 }
1028
1029 if (tlsi!=NULL)
1030 {
1031 Board_SetSize(b, COL_SSTA_MIN, 7, 'r');
1032 Board_SetSize(b, COL_SSTA_MOY, 7, 'r');
1033 Board_SetSize(b, COL_SSTA_MAX, 7, 'r');
1034 Board_SetSize(b, COL_SSTA_SIGMA, 5, 'r');
1035 }
1036
1037 Board_NewLine(b);
1038
1039 Board_SetValue(b, COL_SSTA_MIN, "éSSTA");
1040 Board_SetValue(b, COL_SSTA_MOY, "ç");
1041 Board_SetValue(b, COL_SSTA_MAX, "èInformation");
1042 Board_SetValue(b, COL_SSTA_SIGMA, "Sigma");
1043
1044 sprintf(buf, "èDelay");
1045 sprintf(buf1, "éDelay[%s]", DISPLAY_time_string);
1046
1047 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, "éSim");
1048 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, buf);
1049 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_SLOPE, b, COL_SIM_SLOPE, "Sim_R/F");
1050 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ERROR, b, COL_SIM_ERROR, "% ");
1051
1052 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, "éDelay");
1053 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, "è");
1054
1055 if (split)
1056 {
1057 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, "éCtk");
1058 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, buf);
1059 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_SLOPE, b, COL_CTK_SLOPE, "Ctk_R/F");
1060 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, "éCtk");
1061 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, "èLAG");
1062 }
1063 else
1064 {
1065 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_CTK_ACC, "éDelay");
1066 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_CTK_DELTA, "è");
1067 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_CTK_LAG_ACC, "éLAG");
1068 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_CTK_LAG_DELTA, "è");
1069 }
1070
1071 // _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_NODETYPE, "Node");
1072 // _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, "Line");
1073 // _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_TRANSISTORS, b, COL_TRANSISTORS, "Switching");
1074
1075 #ifndef CTK_DIFF_MODE
1076 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, "éLAG");
1077 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, "è");
1078 #else
1079 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, "éCtk effect \%");
1080 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, "è");
1081 #endif
1082
1083 sprintf(buf, "time[%s]", DISPLAY_time_string);
1084 sprintf(buf1, "Cap[%s]", DISPLAY_capa_string);
1085
1086 Board_SetValue(b, COL_CTK_SCORE_TOT, "éCTK");
1087 Board_SetValue(b, COL_CTK_SCORE_NOISE, "çScores");
1088 Board_SetValue(b, COL_CTK_SCORE_CTK, "ç");
1089 Board_SetValue(b, COL_CTK_SCORE_ACTIV, "ç");
1090 Board_SetValue(b, COL_CTK_SCORE_INTERV, "ç");
1091 Board_SetValue(b, COL_CTK_SCORE_PROBA, "è");
1092
1093
1094 Board_NewLine(b);
1095
1096 Board_SetValue(b, COL_SSTA_MIN, "Min");
1097 Board_SetValue(b, COL_SSTA_MOY, "Mean");
1098 Board_SetValue(b, COL_SSTA_MAX, "Max");
1099 Board_SetValue(b, COL_SSTA_SIGMA, "Factor");
1100
1101 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODENAME, b, COL_NODENAME, "Node_Name");
1102 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NETNAME, b, COL_NETNAME, "Net_Name");
1103 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CAPA, b, COL_CAPA, buf1);
1104
1105 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, "Acc ");
1106 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, "Delta");
1107 // _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_SLOPE, b, COL_SIM_SLOPE, buf);
1108 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_SLOPE, b, COL_SIM_SLOPE, "R/F ");
1109
1110 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, "Acc ");
1111 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, "Delta");
1112 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_SLOPE, b, COL_REF_SLOPE, "R/F ");
1113
1114 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, acclabel);
1115 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, deltalabel);
1116 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_SLOPE, b, COL_CTK_SLOPE, "R/F ");
1117
1118 if (!ffdebug)
1119 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_TRANSISTORS, b, COL_TRANSISTORS, "Switching_transistors");
1120 else
1121 Board_SetValue(b, COL_TRANSISTORS, "DEBUG");
1122 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, linelabel);
1123
1124 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, acclabel);
1125 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, deltalabel);
1126 #ifndef CTK_DIFF_MODE
1127 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, "Acc ");
1128 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, "Delta");
1129 #else
1130 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, "Delay");
1131 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, "Slope");
1132 #endif
1133 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_NODETYPE, "Type");
1134
1135 Board_SetValue(b, COL_CTK_SCORE_TOT, "T");
1136 Board_SetValue(b, COL_CTK_SCORE_NOISE, "N");
1137 Board_SetValue(b, COL_CTK_SCORE_CTK, "C");
1138 Board_SetValue(b, COL_CTK_SCORE_ACTIV, "A");
1139 Board_SetValue(b, COL_CTK_SCORE_INTERV, "I");
1140 Board_SetValue(b, COL_CTK_SCORE_PROBA, "P");
1141
1142 Board_NewSeparation(b);
1143
1144 if( DISPLAY_errormode==1 )
1145 {
1146 /* if (tp!=NULL)
1147 errorref=ttv_GetPathDelay(tp);
1148 else*/
1149 {
1150 detail=detailbase;
1151 errorref=0;
1152 while (detail!=NULL)
1153 {
1154 tc=(ttvcritic_list *)detail->DATA;
1155 if (ttv_GetDetailSimDelay(tc)!=-1)
1156 errorref+=ttv_GetDetailSimDelay(tc);
1157 //ttv_GetDetailRefDelay(tc);
1158 detail=detail->NEXT;
1159 }
1160 }
1161 }
1162
1163 if (clock_tree!=NULL)
1164 {
1165 long lat=TTV_NOTIME, base=TTV_NOTIME;
1166 chain_list *cl;
1167
1168 if (tp!=NULL) base=tp->DELAYSTART;
1169 else if (detailbase!=NULL) base=((ttvcritic_list *)detailbase->DATA)->DELAY;
1170 if (base!=TTV_NOTIME)
1171 {
1172 for (cl=clock_tree; cl!=NULL && cl->NEXT!=NULL; cl=cl->NEXT) ;
1173 if (cl!=NULL)
1174 base=base-((stb_clock_latency_information *)cl->DATA)->date;
1175 }
1176 else base=0;
1177 while (clock_tree!=NULL)
1178 {
1179 scli=(stb_clock_latency_information *)clock_tree->DATA;
1180
1181 Board_NewLine(b);
1182 if (!hidectk)
1183 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, FormaT(_LONG_TO_DOUBLE(scli->date+base)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1184 if (!hidectklag)
1185 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, FormaT(_LONG_TO_DOUBLE(scli->date+base)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1186 sprintf(buf1, "%c ", dirconv(ttv_GetTimingEventDirection(scli->clock_event)));
1187 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_SLOPE, b, COL_CTK_SLOPE, buf1);
1188 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODENAME, b, COL_NODENAME, ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(scli->clock_event->ROOT), scli->clock_event->ROOT));
1189 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NETNAME, b, COL_NETNAME, ttv_GetFullSignalNetName (ttv_GetSignalTopTimingFigure(scli->clock_event->ROOT), scli->clock_event->ROOT));
1190 typeconv(ttv_GetSignalType(scli->clock_event->ROOT), scli->clock_event->ROOT->TYPE, buf);
1191 sprintf(nodetype, "(C%s)", buf);
1192 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_NODETYPE, nodetype);
1193 capa=ttv_GetSignalCapacitance(scli->clock_event->ROOT);
1194 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CAPA, b, COL_CAPA, FormaT(capa*DISPLAY_capa_unit, buf, DISPLAY_capa_format));
1195
1196 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, FormaT(_LONG_TO_DOUBLE(scli->period)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1197
1198 if (lat!=TTV_NOTIME)
1199 {
1200 if (!hidectk)
1201 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, FormaT(_LONG_TO_DOUBLE(lat)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1202 if (!hidectklag)
1203 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, FormaT(_LONG_TO_DOUBLE(lat)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1204 }
1205 lat=scli->delay;
1206 mbkfree(scli);
1207 clock_tree=delchain(clock_tree, clock_tree);
1208 }
1209
1210
1211 Board_NewSeparation(b);
1212 Board_NewLine(b);
1213 acclabel="Acc ", deltalabel="Delta", linelabel="Line";
1214 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, acclabel);
1215 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, deltalabel);
1216 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, acclabel);
1217 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, deltalabel);
1218 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, linelabel);
1219
1220 // Board_NewSeparation(b);
1221 }
1222
1223 tc1=NULL;
1224 detail=detailbase;
1225 while (detail!=NULL)
1226 {
1227 tc=(ttvcritic_list *)detail->DATA;
1228
1229 nodename=ttv_GetDetailNodeName(tc);
1230 netname=ttv_GetDetailSignalName(tc);
1231
1232 deltaref=ttv_GetDetailRefDelay(tc);
1233 sloperef=ttv_GetDetailRefSlope(tc);
1234
1235 deltactk=ttv_GetDetailDelay(tc);
1236 slopectk=ttv_GetDetailSlope(tc);
1237
1238 deltasim=ttv_GetDetailSimDelay(tc);
1239 slopesim=ttv_GetDetailSimSlope(tc);
1240
1241 if (detail==detailbase)
1242 {
1243 if ((detail_forced_mode & RELATIVE_DETAIL)==0)
1244 {
1245 double stbdecal=0;
1246 stbdebug_list *dbl;
1247 if (pt_debug!=NULL)
1248 {
1249 int dec;
1250 Setup_Hold_Computation_Detail_INFO *detail_info;
1251 dbl=(stbdebug_list *)pt_debug->DATA;
1252 if (tp->ROOT->TYPE & TTV_NODE_UP) dec=1; else dec=0;
1253 if (tp->TYPE & TTV_FIND_MAX) detail_info=&dbl->detail[dec].setup;
1254 else detail_info=&dbl->detail[dec].hold;
1255 if (detail_info->VALUE!=STB_NO_TIME) stbdecal=detail_info->datamoved+detail_info->misc+detail_info->mc_setup_period-detail_info->mc_hold_period;
1256 stbdecal*=1e-12/TTV_UNIT;
1257 }
1258 deltaref=deltactk=deltasim=ttv_GetPathStartTime(tp)+stbdecal;
1259 }
1260 else
1261 deltaref=deltactk=deltasim=0;
1262 }
1263
1264 if (deltasim==-1 || slopesim==-1) simerror=1;
1265
1266 delaytype=ttv_GetDetailType(tc);
1267
1268 if (tc1!=NULL)
1269 {
1270 deltaref+=ttv_GetDetailRefDelay(tc1);
1271 deltactk+=ttv_GetDetailDelay(tc1);
1272 deltasim+=ttv_GetDetailSimDelay(tc1);
1273 }
1274
1275 if (mergerc && strcmp(delaytype,"rc")==0 && detail->NEXT!=NULL)
1276 {
1277 tc1=tc;
1278 }
1279 else tc1=NULL;
1280
1281 if (tc1==NULL)
1282 {
1283
1284 dir=dirconv(ttv_GetDetailDirection(tc));
1285 capa=tc->CAPA*1e-15*DISPLAY_capa_unit;
1286
1287 typeconv(ttv_GetDetailSignalType(tc), tc->SIGTYPE, buf);
1288 if (mergerc && detail->NEXT!=NULL && strcmp(ttv_GetDetailType((ttvcritic_list *)detail->NEXT->DATA),"rc")==0 && detail->NEXT->NEXT!=NULL)
1289 {
1290 typeconv(ttv_GetDetailSignalType((ttvcritic_list *)detail->NEXT->DATA), ((ttvcritic_list *)detail->NEXT->DATA)->SIGTYPE, buf1);
1291 strcat(buf,buf1);
1292 }
1293
1294 if (tc->NODE_FLAG & TTV_NODE_FLAG_ISCLOCK) addc=1;
1295 if (tc->NODE_FLAG & TTV_NODE_FLAG_ISLATCH_ACCESS) { addc=0; ideal_clock_path=0; }
1296 // if ((tc->SIGTYPE & (TTV_SIG_L|TTV_SIG_R))!=0 && detail!=detailbase) addc=0;
1297 if (addc)
1298 sprintf(nodetype, "(C%s)", buf);
1299 else if (strcmp(buf,"")!=0)
1300 sprintf(nodetype, "(%s)", buf);
1301 else
1302 strcpy(nodetype,"");
1303
1304 deltalag=deltactk+ttv_GetDetailDataLag(tc);
1305 deltareflag=deltaref+ttv_GetDetailDataLag(tc);
1306
1307 if (addc && ideal_clock_path && (idealptype || (detail_forced_mode & IDEAL_CLOCK)!=0) && detail!=detailbase)
1308 deltactk=deltaref=deltalag=deltareflag=deltasim=0;
1309
1310 accctk+=deltactk;
1311 accref+=deltaref;
1312 acclag+=deltalag;
1313 accreflag+=deltareflag;
1314 if (deltasim!=-1) accsim+=deltasim;
1315
1316 if (detail==detailbase)
1317 {
1318 start=deltaref;
1319 deltactk=0;
1320 deltaref=0;
1321 deltalag=0;
1322 deltasim=deltasim!=-1?0:-1;
1323 deltareflag=0;
1324 }
1325
1326 if (strcmp(delaytype,"rc")!=0 && getenv("GATEMODE")) delaytype="gate";
1327 /* {
1328 char *gatename;
1329 int numinput;
1330 colcode="¤+";
1331 if (ttv_getgateinfo(((unsigned)tc->PROP)>>24, &gatename, &numinput))
1332 delaytype=gatename;
1333 if ((tc->SIGTYPE & TTV_SIG_L)!=0)
1334 {
1335 if (tc->PROP & TTV_SIG_FLAGS_ISMASTER) delaytype="master";
1336 else if (tc->PROP & TTV_SIG_FLAGS_ISSLAVE) delaytype="slave";
1337 }
1338 }
1339 else colcode="";*/
1340
1341 if (ttv_DetailIsHZ(tc)) ztag='Z'; else ztag=' ';
1342
1343 Board_NewLine(b);
1344
1345
1346 if (tlsi!=NULL)
1347 {
1348 ttv_line_delay_ssta_info *tldsi;
1349 int idx;
1350 if (tc->LINE!=NULL && (idx=ttv_ssta_getline_index(tc->LINE))!=-1)
1351 {
1352 double val;
1353 if (tp->TYPE & TTV_FIND_MAX)
1354 tldsi=&tlsi[idx].delaymax;
1355 else
1356 tldsi=&tlsi[idx].delaymin;
1357 Board_SetValue(b, COL_SSTA_MIN, FormaT(tldsi->min*DISPLAY_time_unit, buf, DISPLAY_time_format));
1358 Board_SetValue(b, COL_SSTA_MOY, FormaT(tldsi->moy*DISPLAY_time_unit, buf, DISPLAY_time_format));
1359 Board_SetValue(b, COL_SSTA_MAX, FormaT(tldsi->max*DISPLAY_time_unit, buf, DISPLAY_time_format));
1360 val=sqrt(tldsi->var);
1361 if (val>1e-15)
1362 val=(ttv_GetDetailDelay(tc)-tldsi->moy)/val;
1363 else
1364 val=0;
1365 sprintf(buf1, "%.1f", val);
1366 Board_SetValue(b, COL_SSTA_SIGMA, buf1);
1367 }
1368 }
1369
1370 if (!hidesim)
1371 {
1372 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_SLOPE, b, COL_SIM_SLOPE, slopesim!=-1?FormaT(slopesim*DISPLAY_time_unit, buf, DISPLAY_time_format):"/");
1373 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, deltasim!=-1?FormaT(deltasim*DISPLAY_time_unit, buf, DISPLAY_time_format):"/");
1374 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, !simerror?FormaT(accsim*DISPLAY_time_unit, buf, DISPLAY_time_format):"/");
1375
1376 if (!simerror)
1377 {
1378 if( DISPLAY_errormode==0) errorref=deltasim ;
1379
1380 if (!hidectk) error=(deltactk-deltasim)*100/errorref;
1381 else error=(deltaref-deltasim)*100/errorref;
1382 if (!finite(error)) strcpy(buf1,".....");
1383 else if (fabs(error)>9999) sprintf(buf1,"¤6.....¤.%s", colcode);
1384 else
1385 {
1386 if (fabs(error)>=50) sprintf(buf1, "¤6%+.1f¤.%s", error, colcode);
1387 else if (fabs(error)>10) sprintf(buf1, "¤4%+.1f¤.%s", error, colcode);
1388 else sprintf(buf1, "%+.1f", error);
1389 }
1390 }
1391 else
1392 sprintf(buf1, "%4s", "/ ");
1393 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ERROR, b, COL_SIM_ERROR, buf1);
1394 }
1395 if (!hideref)
1396 {
1397 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, FormaT(accref*DISPLAY_time_unit, buf, DISPLAY_time_format));
1398 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, FormaT(deltaref*DISPLAY_time_unit, buf, DISPLAY_time_format));
1399 sprintf(buf1, "%s %c%c", FormaT(sloperef*DISPLAY_time_unit, buf, DISPLAY_time_format), dir, ztag);
1400 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_SLOPE, b, COL_REF_SLOPE, buf1);
1401 }
1402 if (!hidereflag)
1403 {
1404 #ifndef CTK_DIFF_MODE
1405 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, FormaT(accreflag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1406 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, FormaT(deltareflag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1407 #else
1408 if (detail!=detailbase)
1409 {
1410 error=(deltactk-deltaref)*100/deltaref;
1411 if (finite(error)) sprintf(buf1, "%+.1f", error);
1412 else sprintf(buf1, "....");
1413 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, buf1);
1414 error=(slopectk-sloperef)*100/sloperef;
1415 if (finite(error)) sprintf(buf1, "%+.1f", error);
1416 else sprintf(buf1, "....");
1417 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, buf1);
1418 }
1419 #endif
1420 }
1421
1422 if (!hidectk)
1423 {
1424 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, FormaT(accctk*DISPLAY_time_unit, buf, DISPLAY_time_format));
1425 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, FormaT(deltactk*DISPLAY_time_unit, buf, DISPLAY_time_format));
1426 sprintf(buf1, "%s %c%c", FormaT(slopectk*DISPLAY_time_unit, buf, DISPLAY_time_format), dir, ztag);
1427 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_SLOPE, b, COL_CTK_SLOPE, buf1);
1428 }
1429 if (!hidectklag)
1430 {
1431 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, FormaT(acclag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1432 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, FormaT(deltalag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1433 }
1434
1435 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CAPA, b, COL_CAPA, FormaT(capa, buf, DISPLAY_capa_format));
1436
1437 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODETYPE, b, COL_NODETYPE, nodetype);
1438 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODENAME, b, COL_NODENAME, nodename);
1439 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NETNAME, b, COL_NETNAME, netname);
1440 if (sb!=NULL)
1441 {
1442 char buf[30];
1443 char *tag0="", *tag="";
1444 if (stb_has_filter_directive(tc->NODE)) tag="[f] ";
1445
1446 if (ffdebug && stb_getstbnode(tc->NODE)->CK!=NULL) tag0="*";
1447
1448 sprintf(buf,"%s%s%s", tag0, tag, delaytype);
1449 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, buf);
1450
1451 if (ffdebug)
1452 {
1453 long startmin, startmax, endmax, endmin, move;
1454 char filterstate;
1455 ttvevent_list *cs;
1456 char buf0[20], buf1[20], buf3[50];
1457 stbpair_list *pair, *opair;
1458 stbnode *node;
1459 strcpy(buf, "");
1460 node=stb_getstbnode(tc->NODE);
1461 pair=stb_globalstbtab(node->STBTAB,node->NBINDEX);
1462 pair=stb_globalstbpair(opair=pair);
1463 if (pair!=NULL)
1464 {
1465 sprintf(buf3," STAB[%s,%s]",
1466 FormaT(pair->D*1e-12/TTV_UNIT*DISPLAY_time_unit, buf0, DISPLAY_time_format),
1467 FormaT(pair->U*1e-12/TTV_UNIT*DISPLAY_time_unit, buf1, DISPLAY_time_format)
1468 );
1469 strcat(buf,buf3);
1470
1471 }
1472 stb_freestbpair(pair) ;
1473 stb_freestbpair(opair) ;
1474 if (stb_get_filter_directive_info(sb, tc->NODE, STB_NO_INDEX, &startmin, &startmax, &endmax, &endmin, &filterstate, &move, &cs, NULL))
1475 {
1476 sprintf(buf3," (%c %s,%s)", (cs->TYPE & TTV_NODE_UP)!=0?'U':'D',
1477 FormaT(startmin*1e-12/TTV_UNIT*DISPLAY_time_unit, buf0, DISPLAY_time_format),
1478 FormaT(endmax*1e-12/TTV_UNIT*DISPLAY_time_unit, buf1, DISPLAY_time_format)
1479 );
1480 strcat(buf,buf3);
1481 }
1482 Board_SetValue(b, COL_TRANSISTORS, buf);
1483 }
1484 }
1485 else
1486 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_LINETYPE, b, COL_LINETYPE, delaytype);
1487
1488 if (!ffdebug && DT_CONFIG_SHOW[COL_TRANSISTORS])
1489 {
1490 if (prevnetname!=NULL && tp!=NULL)
1491 {
1492 chain_list *cl;
1493 trlist=ttv_GetCrossedTransistorNames(tp->FIG, prevnetname, prevdir, netname, ttv_GetDetailDirection(tc), ztag=='Z'?1:0);
1494 strcpy(buf,"");
1495 for (cl=trlist; cl!=NULL; cl=cl->NEXT)
1496 {
1497 strcat(buf, (char *)cl->DATA);
1498 if (cl->NEXT!=NULL) strcat(buf, ", ");
1499 }
1500 freechain(trlist);
1501 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_TRANSISTORS, b, COL_TRANSISTORS, buf);
1502 }
1503
1504 prevnetname=netname;
1505 prevdir=ttv_GetDetailDirection(tc);
1506 }
1507 }
1508
1509 if ((ptype=getptype(tc->USER, PATH_NOISE_PTYPE))!=NULL)
1510 {
1511 PATH_NOISE_TYPE *pnt;
1512 pnt=(PATH_NOISE_TYPE *)ptype->DATA;
1513 sprintf(buf,"%d%%", pnt->T);
1514 Board_SetValue(b, COL_CTK_SCORE_TOT, buf);
1515 sprintf(buf,"%d", pnt->N);
1516 Board_SetValue(b, COL_CTK_SCORE_NOISE, buf);
1517 sprintf(buf,"%d", pnt->C);
1518 Board_SetValue(b, COL_CTK_SCORE_CTK, buf);
1519 sprintf(buf,"%d", pnt->A);
1520 Board_SetValue(b, COL_CTK_SCORE_ACTIV, buf);
1521 sprintf(buf,"%d", pnt->I);
1522 Board_SetValue(b, COL_CTK_SCORE_INTERV, buf);
1523 sprintf(buf,"%d", pnt->P);
1524 Board_SetValue(b, COL_CTK_SCORE_PROBA, buf);
1525 }
1526
1527 //if (tc1!=NULL) detail=detail->NEXT; // rc merged
1528 detail=detail->NEXT;
1529 }
1530
1531 if (!hidesim)
1532 {
1533 if (!hidectk) error=(accctk-accsim)*100/(accsim-start), tasval_cmp=accctk;
1534 else error=(accref-accsim)*100/(accsim-start), tasval_cmp=accref;
1535 simval_cmp=accsim;
1536 start_cmp=start;
1537 }
1538
1539 if (PATH_MORE_INFO.enabled)
1540 {
1541 for (i=0; i<10 && PATH_MORE_INFO.add[i].label!=NULL; i++)
1542 {
1543 int ssim=0;
1544 deltaref=PATH_MORE_INFO.add[i].val;
1545 deltactk=PATH_MORE_INFO.add[i].val;
1546 deltasim=PATH_MORE_INFO.add[i].val;
1547
1548 accctk+=deltactk;
1549 accref+=deltaref;
1550 acclag+=deltactk;
1551 accreflag+=deltaref;
1552
1553 if (PATH_MORE_INFO.add[i].noacc) start+=PATH_MORE_INFO.add[i].val;
1554 if (!hidesim)
1555 {
1556 tasval_cmp+=PATH_MORE_INFO.add[i].val;
1557 if (DISPLAY_simdiffmode && strcmp(PATH_MORE_INFO.add[i].label,"[PATH MARGIN]")!=0)
1558 {
1559 simval_cmp+=PATH_MORE_INFO.add[i].val, ssim=1;
1560 accsim+=deltasim;
1561 }
1562 }
1563
1564 Board_NewLine(b);
1565
1566 if (!hidesim && ssim)
1567 {
1568 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, FormaT(accsim*DISPLAY_time_unit, buf, DISPLAY_time_format));
1569 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, FormaT(deltasim*DISPLAY_time_unit, buf, DISPLAY_signed_time_format));
1570 }
1571 /*
1572 if (!hideref)
1573 {
1574 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, FormaT(accref*DISPLAY_time_unit, buf, DISPLAY_time_format));
1575 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, FormaT(deltaref*DISPLAY_time_unit, buf, DISPLAY_signed_time_format));
1576 }
1577
1578 if (!hidereflag)
1579 {
1580 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, FormaT(accreflag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1581 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, FormaT(deltaref*DISPLAY_time_unit, buf, DISPLAY_signed_time_format));
1582 }*/
1583 if (!hidectk)
1584 {
1585 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, FormaT(accctk*DISPLAY_time_unit, buf, DISPLAY_time_format));
1586 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, FormaT(deltactk*DISPLAY_time_unit, buf, DISPLAY_signed_time_format));
1587 }
1588 if (!hidectklag)
1589 {
1590 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, FormaT(acclag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1591 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, FormaT(deltactk*DISPLAY_time_unit, buf, DISPLAY_signed_time_format));
1592 }
1593 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_NODENAME, b, COL_NODENAME, PATH_MORE_INFO.add[i].label);
1594 }
1595 }
1596
1597 Board_NewSeparation(b);
1598
1599
1600 Board_NewLine(b);
1601
1602 if (!hidesim)
1603 {
1604 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ACC, b, COL_SIM_ACC, FormaT(accsim*DISPLAY_time_unit, buf, DISPLAY_time_format));
1605 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_DELTA, b, COL_SIM_DELTA, FormaT((accsim-start)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1606 if (DISPLAY_simdiffmode)
1607 {
1608 error=(tasval_cmp-simval_cmp)*100/(simval_cmp-start_cmp);
1609 }
1610 if (!finite(error)) strcpy(buf1,".....");
1611 else if (fabs(error)>9999) sprintf(buf1,"¤6.....¤.%s", colcode);
1612 else
1613 {
1614 if (fabs(error)>=50) sprintf(buf1, "¤6%+.1f¤.%s", error, colcode);
1615 else if (fabs(error)>10) sprintf(buf1, "¤4%+.1f¤.%s", error, colcode);
1616 else sprintf(buf1, "%+.1f", error);
1617 }
1618 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_SIM_ERROR, b, COL_SIM_ERROR, buf1);
1619 }
1620 if (!hideref)
1621 {
1622 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_ACC, b, COL_REF_ACC, FormaT(accref*DISPLAY_time_unit, buf, DISPLAY_time_format));
1623 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_DELTA, b, COL_REF_DELTA, FormaT((accref-start)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1624 }
1625 #ifndef CTK_DIFF_MODE
1626 if (!hidereflag)
1627 {
1628 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_ACC, b, COL_REF_LAG_ACC, FormaT(accreflag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1629 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_REF_LAG_DELTA, b, COL_REF_LAG_DELTA, FormaT((accreflag-start)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1630 }
1631 #endif
1632 if (!hidectk)
1633 {
1634 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_ACC, b, COL_CTK_ACC, FormaT(accctk*DISPLAY_time_unit, buf, DISPLAY_time_format));
1635 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_DELTA, b, COL_CTK_DELTA, FormaT((accctk-start)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1636 }
1637 if (!hidectklag)
1638 {
1639 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_ACC, b, COL_CTK_LAG_ACC, FormaT(acclag*DISPLAY_time_unit, buf, DISPLAY_time_format));
1640 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CTK_LAG_DELTA, b, COL_CTK_LAG_DELTA, FormaT((acclag-start)*DISPLAY_time_unit, buf, DISPLAY_time_format));
1641 }
1642
1643 _ttv_Board_SetValue(DT_CONFIG_SHOW, COL_CAPA, b, COL_CAPA, "(total)");
1644
1645 sprintf(buf,"%s ", LP);
1646 Board_Display(f, b, buf);
1647 Board_FreeBoard(b);
1648 avt_fprintf(f, "%s\n",LP);
1649
1650 stb_free_noise_on_detail(detailbase);
1651
1652 if (TTV_API_NOSUPINFO_DETAIL==0 && (detail_forced_mode & NOSUPINFO_DETAIL)==0)
1653 {
1654 if (tp!=NULL)
1655 {
1656 ttvevent_list *revert_tve;
1657
1658 if ((tve=ttv_GetPathCommand(tp))==NULL)
1659 if ((tp->ROOT->ROOT->TYPE & TTV_SIG_R)!=0) tve=tp->ROOT;
1660
1661 if (tve!=NULL)
1662 {
1663 if (tp->TYPE & TTV_FIND_MAX) searchtype='m'; //min
1664 else searchtype='M'; // max
1665
1666 if ((tp->ROOT->ROOT->TYPE & TTV_SIG_R)==0)
1667 revert_tve=ttv_opposite_event(tve);
1668 else
1669 {
1670 if (!ttv_PathIsHZ(tp) || searchtype=='M') revert_tve=tve;
1671 else revert_tve=ttv_opposite_event(tve);
1672 }
1673
1674 if (DT_CONFIG_SHOW[INFO_CMD] && (tp->ROOT->ROOT->TYPE & TTV_SIG_R)==0)
1675 {
1676 ttv_GetNodeIntrinsicInfo(tve, tp->ROOT, DISPLAY_time_unit, DISPLAY_time_string, DISPLAY_time_format, format, 1);
1677
1678 if (strlen(format)!=0)
1679 {
1680 avt_fprintf(f, "%s -> Intrinsic Info: %s(%c) -> %s(%c):%s\n", LP, ttv_GetFullSignalName_COND(tp->FIG, tve->ROOT), dirconv(ttv_GetTimingEventDirection(tve)), ttv_GetFullSignalName_COND(tp->FIG, tp->ROOT->ROOT), dirconv(ttv_GetTimingEventDirection(tp->ROOT)), format);
1681 }
1682 ttv_GetNodeIntrinsicInfo(tve, tp->ROOT, DISPLAY_time_unit, DISPLAY_time_string, DISPLAY_time_format, format, 0);
1683
1684 if (strlen(format)!=0)
1685 {
1686 avt_fprintf(f, "%s -> Intrinsic Info: %s(%c) -> %s(%c):%s\n", LP, ttv_GetFullSignalName_COND(tp->FIG, tp->ROOT->ROOT), dirconv(ttv_GetTimingEventDirection(tp->ROOT)), ttv_GetFullSignalName_COND(tp->FIG, revert_tve->ROOT), dirconv(ttv_GetTimingEventDirection(revert_tve)), format);
1687 }
1688
1689 }
1690
1691 if ((tp->ROOT->ROOT->TYPE & TTV_SIG_R)==0)
1692 avt_fprintf(f, "%s -> Closing Command %s(%c)\n", LP, ttv_GetFullSignalName_COND(tp->FIG, revert_tve->ROOT), dirconv(ttv_GetTimingEventDirection(revert_tve)));
1693
1694 if (DT_CONFIG_SHOW[INFO_CMD])
1695 {
1696 ttv_GetNodeClock(tve, tp->ROOT, DISPLAY_time_unit, DISPLAY_time_string, DISPLAY_time_format, format, pt_debug!=NULL?(stbdebug_list *)pt_debug->DATA:NULL, tp);
1697
1698 if (strlen(format)!=0)
1699 {
1700 avt_fprintf(f, "%s -> Closing Command Wave: %s\n", LP, format);
1701 }
1702
1703 if ((tp->ROOT->ROOT->TYPE & TTV_SIG_R)==0)
1704 {
1705 avt_fprintf(f, "%s -> Closing Clock Route: ", LP); ttv_DisplayRoute(f, revert_tve, searchtype, NULL, (tp->ROOT->ROOT->TYPE & TTV_SIG_R)!=0);
1706 avt_fprintf(f, "\n");
1707 }
1708 if (pt_more!=NULL) ((more_func)pt_more->DATA)(LP, f);
1709 }
1710 avt_fprintf(f, "%s\n",LP);
1711 }
1712 }
1713 else
1714 {
1715 // specout
1716 if (tp!=NULL)
1717 {
1718 if (tp->TYPE & TTV_FIND_MAX) tm=1; else tm=0;
1719 ttv_GetNodeSpecout(tp->ROOT, DISPLAY_time_unit, DISPLAY_time_format, format, pt_debug!=NULL?(stbdebug_list *)pt_debug->DATA:NULL, tp, tm, 0);
1720 if (strlen(format)!=0)
1721 {
1722 avt_fprintf(f, "%s -> Specification: %s\n", LP, format);
1723 }
1724 if (pt_more!=NULL) ((more_func)pt_more->DATA)(LP, f);
1725 avt_fprintf(f, "%s\n",LP);
1726 }
1727 }
1728 }
1729 fflush(f);
1730 }
1731
1732 void ttv_DisplayPathDetail(FILE *f, int num, ttvpath_list *tp)
1733 {
1734 chain_list *detail;
1735
1736 if (tp==NULL) return;
1737
1738 detail=ttv_GetPathDetail(tp);
1739 if (detail==NULL) return;
1740
1741 if (SIMULATE_MODE=='y') ttv_SimulatePath_sub(tp->FIG, tp, "", 0);
1742
1743 ttv_DisplayCompletePathDetail(f, num, tp, detail);
1744
1745 ttv_FreePathDetail(detail);
1746 freechain(detail);
1747 }
1748
1749 void ttv_DisplayPathListDetail(FILE *f, chain_list *tpl)
1750 {
1751 int count=1;
1752
1753 if (f==NULL) return;
1754
1755 ttv_DisplayConfig(f, tpl);
1756
1757 avt_fprintf(f, " *** Path list (unit:[%s]) ***\n\n", DISPLAY_time_string);
1758
1759 ttv_DisplayPathList(f, tpl);
1760
1761 ttv_DisplayLegend(f);
1762
1763 avt_fprintf(f, " *** Path details (unit:[%s]) ***\n\n", DISPLAY_time_string);
1764
1765 while (tpl!=NULL)
1766 {
1767 ttv_DisplayPathDetail(f, count, (ttvpath_list *)tpl->DATA);
1768 count++;
1769 tpl=tpl->NEXT;
1770 }
1771 }
1772
1773 void ttv_DisplayRoute(FILE *f, ttvevent_list *tve, char type, chain_list *pthlist, int prech)
1774 {
1775 chain_list *cl, *list;
1776 chain_list *detail, *detailbase;
1777 ttvcritic_list *tc;
1778 char *nodename, *col, *_type;
1779 ttvpath_list *pth;
1780 char dir[5];
1781 ttvsig_list *tvs;
1782
1783 if (f==NULL) return;
1784
1785 tvs=tve->ROOT;
1786
1787 if (!prech)
1788 sprintf(dir,"?%c",ttv_GetTimingEventDirection(tve));
1789 else
1790 strcpy(dir,"??");
1791
1792 if (pthlist==NULL)
1793 {
1794 if (type=='M') list=ttv_internal_GetCriticPath(NULL, tvs, dir, 100, 1);
1795 else list=ttv_internal_GetCriticPath(NULL, tvs, dir, 100, 0);
1796 }
1797 else
1798 list=pthlist;
1799
1800 cl=list;
1801 while (cl!=NULL)
1802 {
1803 pth=(ttvpath_list *)cl->DATA;
1804 tvs=ttv_GetPathStartSignal(pth);
1805 if (isclock(tvs))
1806 {
1807 if (!prech || (!ttv_PathIsHZ(pth) && type=='m' && tve==pth->ROOT)) break;
1808 if (type=='M' && ((!ttv_PathIsHZ(pth) && tve!=pth->ROOT) ||(ttv_PathIsHZ(pth) && tve==pth->ROOT))) break;
1809 }
1810 cl=cl->NEXT;
1811 }
1812 if (cl!=NULL)
1813 {
1814 pth=(ttvpath_list *)cl->DATA;
1815 detailbase=detail=ttv_GetPathDetail(pth);
1816 avt_fprintf(f, "(");
1817 while (detail!=NULL)
1818 {
1819 tc=(ttvcritic_list *)detail->DATA;
1820 if (detail==detailbase || !(DISPLAY_nodemode==0 && strcasecmp(ttv_GetDetailType(tc),"rc")==0))
1821 {
1822 if (detail!=detailbase) avt_fprintf(f, " - ");
1823 nodename=ttv_GetDetailSignalName_COND(tc);
1824 _type=ttv_GetDetailSignalType(tc);
1825 if (strstr(_type,"latch")!=NULL || strstr(_type,"flip-flop")!=NULL) col="¤4";
1826 else col="";
1827 avt_fprintf(f, "%s%s¤.(%c%s)", col, nodename, dirconv(ttv_GetDetailDirection(tc)), (ttv_PathIsHZ(pth) && detail->NEXT==NULL)?"Z":"");
1828 }
1829 detail=detail->NEXT;
1830 }
1831 avt_fprintf(f, ")");
1832
1833 ttv_FreePathDetail(detailbase);
1834 freechain(detailbase);
1835 }
1836 else
1837 {
1838 if (list==NULL && (tvs->TYPE & TTV_SIG_C)!=0)
1839 {
1840 nodename=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(tvs), tvs);
1841 avt_fprintf(f, "%s(%c)", nodename, dirconv(ttv_GetTimingEventDirection(tve)));
1842 }
1843 else
1844 avt_fprintf(f, "¤6<no path to clock found>¤.");
1845 }
1846
1847 if (pthlist==NULL)
1848 {
1849 ttv_FreePathList(list);
1850 freechain(list);
1851 }
1852 }
1853
1854 static ttvcritic_list *findlastgate(ttvcritic_list * c)
1855 {
1856 ttvcritic_list *lastg=c;
1857 while (c!=NULL)
1858 {
1859 if (strcmp(ttv_GetDetailType(c),"rc")!=0) lastg=c;
1860 c=c->NEXT;
1861 }
1862 return lastg;
1863 }
1864
1865 static int getpos(ttvcritic_list *start, ttvcritic_list *end)
1866 {
1867 int pos;
1868 if (ttv_GetDetailDirection(start)=='u') pos=0; else pos=2;
1869 if (ttv_GetDetailDirection(end)=='u') pos+=0; else pos+=1;
1870 return pos;
1871 }
1872
1873 char *ttv_internal_getclockliststring(ttvfig_list *tf, char *clock)
1874 {
1875 chain_list *cl, *list;
1876 char *key, *tmp;
1877 int size=4096, i, l;
1878
1879 key=(char *)mbkalloc(size+10);
1880 if (strcmp(clock,"*")==0)
1881 {
1882 list=ttv_getclocklist(tf);
1883 i=0;
1884 strcpy(key,"");
1885 for (cl=list; cl!=NULL; cl=cl->NEXT)
1886 {
1887 l=strlen((char *)cl->DATA);
1888 if (i+l>size)
1889 {
1890 tmp=(char *)mbkalloc((size*2)+10);
1891 memcpy(tmp, key, i);
1892 mbkfree(key);
1893 key=tmp;
1894 size*=2;
1895 }
1896 strcpy(&key[i], (char *)cl->DATA);
1897 i+=l;
1898 key[i++]=' ';
1899 }
1900 key[i++]='\0';
1901 freechain(list);
1902 }
1903 else
1904 strcpy(key, clock);
1905
1906 return key;
1907 }
1908
1909 static char *ttv_internal_getsigliststring(ttvfig_list *tf, chain_list *list)
1910 {
1911 chain_list *cl;
1912 char *key, *tmp;
1913 char *nm;
1914 int size=4096, i, l;
1915
1916 key=(char *)mbkalloc(size+10);
1917 i=0;
1918 strcpy(key,"");
1919 for (cl=list; cl!=NULL; cl=cl->NEXT)
1920 {
1921 nm=ttv_GetFullSignalName(tf, (ttvsig_list *)cl->DATA);
1922 l=strlen(nm);
1923 if (i+l>size)
1924 {
1925 tmp=(char *)mbkalloc((size*2)+10);
1926 memcpy(tmp, key, i);
1927 mbkfree(key);
1928 key=tmp;
1929 size*=2;
1930 }
1931 strcpy(&key[i], nm);
1932 i+=l;
1933 key[i++]=' ';
1934 }
1935 key[i++]='\0';
1936 return key;
1937 }
1938
1939 chain_list *ttv_internal_getclockpaths(ttvfig_list *tf, char *clock, char *cmd, int number, char *minmax)
1940 {
1941 chain_list *pth;
1942 char *key;
1943 long old0, old1;
1944
1945 ttv_search_mode(1, TTV_MORE_OPTIONS_MUST_BE_CLOCK);
1946
1947 key=ttv_internal_getclockliststring(tf, clock);
1948
1949 if (strcmp(key,"")!=0)
1950 {
1951 ttv_setsearchexclude(0,TTV_SIG_LSL|TTV_SIG_LL|TTV_SIG_LF|TTV_SIG_B|TTV_SIG_R|TTV_SIG_C,&old0, &old1);
1952
1953 pth=ttv_internal_GetPaths(tf, "*", key, cmd, "??", number, "critic", "path", minmax);
1954
1955 ttv_setsearchexclude(old0, old1, &old0, &old1);
1956
1957 ttv_search_mode(0, TTV_MORE_OPTIONS_MUST_BE_CLOCK);
1958 }
1959 else
1960 pth=NULL;
1961 mbkfree(key);
1962
1963 return pth;
1964 }
1965
1966 void ttv_DisplayClockPathReport(FILE *f, ttvfig_list *tf, char *clock, char *minmax, int number)
1967 {
1968 NameAllocator na;
1969 ht *all;
1970 char *nkey, key[4096], buf[20];
1971 chain_list *pth, *list, *cl, *detail, *list2, *ch;
1972 ttvpath_list *tpl;
1973 ttvcritic_list *start, *preend, *tc, **tab;
1974 struct {
1975 ttvcritic_list *critic, *first;
1976 ttvcritic_list *end;
1977 double addrc, total;
1978 } runc[4];
1979 long l;
1980 int ref, i;
1981 typedef struct
1982 {
1983 chain_list *det[4];
1984 ht *ends;
1985 } PClass;
1986 PClass *pc;
1987 Board *b;
1988
1989 if (!strcasecmp (minmax, "max")) l=1;
1990 else if (!strcasecmp (minmax, "min")) l=0;
1991 else {
1992 avt_errmsg(TTV_API_ERRMSG, "022", AVT_ERROR);
1993 // avt_error("ttvapi", 504, AVT_ERR, "ttv_DisplayClockPathReport: available values for 'minmax' are 'min' or 'max'\n");
1994 return;
1995 }
1996
1997 if (f==NULL) return;
1998
1999 if (ftello(f)==0)
2000 ttv_DumpHeader(f, tf);
2001
2002 avt_fprintf(f, " *** Clock %s Path report (unit:[%s]) ***\n", l==0?"MIN":"MAX", DISPLAY_time_string);
2003
2004 pth=ttv_internal_getclockpaths(tf, clock, "*", INT_MAX, minmax);
2005
2006 CreateNameAllocator(1024, &na, 'y');
2007 all=addht(100);
2008
2009 for (cl=pth, ref=0; cl!=NULL && (number<=0 || ref<number); cl=cl->NEXT)
2010 {
2011 tpl=(ttvpath_list *)cl->DATA;
2012 // if ((tpl->ROOT->ROOT->TYPE & TTV_SIG_Q)!=TTV_SIG_Q) continue;
2013 ref++;
2014 detail=ttv_GetPathDetail(tpl);
2015 start=(ttvcritic_list *)detail->DATA;
2016 preend=findlastgate(start);
2017 strcpy(key,"");
2018 /*for (tc=start; tc!=preend; tc=tc->NEXT)
2019 {
2020 if (tc==start || strcmp(ttv_GetDetailType(tc),"rc")!=0)
2021 strcat(key, ttv_GetDetailSignalName(tc));
2022 }*/
2023 strcat(key, ttv_GetDetailSignalName(start));
2024 strcat(key, ttv_GetDetailSignalName(preend));
2025 sprintf(buf, " %d", countchain(detail));
2026 strcat(key, buf);
2027
2028 nkey=NameAlloc(&na, key);
2029 if ((l=gethtitem(all, nkey))==EMPTYHT)
2030 {
2031 pc=(PClass *)mbkalloc(sizeof(PClass));
2032 pc->det[0]=pc->det[1]=pc->det[2]=pc->det[3]=NULL;
2033 addhtitem(all, nkey, (long)pc);
2034 pc->ends=addht(100);
2035 }
2036 else
2037 pc=(PClass *)l;
2038
2039 i=getpos(start, preend);
2040 pc->det[i]=addchain(pc->det[i], detail);
2041
2042 if (preend->NEXT!=NULL)
2043 {
2044 nkey=NameAlloc(&na, ttv_GetDetailNodeName(preend->NEXT));
2045 if ((l=gethtitem(pc->ends, nkey))==EMPTYHT)
2046 {
2047 tab=(ttvcritic_list **)mbkalloc(sizeof(ttvcritic_list *)*4);
2048 for (l=0; l<4; l++)tab[l]=NULL;
2049 addhtitem(pc->ends, nkey, (long)tab);
2050 }
2051 else
2052 tab=(ttvcritic_list **)l;
2053 tab[i]=preend->NEXT;
2054 }
2055 }
2056
2057 avt_fprintf(f, " %d/%d paths from clock '%s' reported\n\n", ref, countchain((chain_list *)pth), clock);
2058
2059 list=GetAllHTElems_sub(all, 1);
2060
2061 delht(all);
2062
2063 for (cl=list; cl!=NULL; cl=cl->NEXT)
2064 {
2065 pc=(PClass *)cl->DATA;
2066 b=Board_CreateBoard();
2067
2068 Board_SetSize(b, COL_CP_NAME, 10, 'l');
2069 ref=-1;
2070 for (l=0;l<4; l++)
2071 {
2072 if (pc->det[l]!=NULL)
2073 {
2074 Board_SetSep(b, 10+(l*COLUMN_DISTANCE)-1);
2075 Board_SetSize(b, 10+(l*COLUMN_DISTANCE)+0, 3, 'l');
2076 Board_SetSize(b, 10+(l*COLUMN_DISTANCE)+1, 7, DISPLAY_number_justify);
2077 Board_SetSize(b, 10+(l*COLUMN_DISTANCE)+2, 7, DISPLAY_number_justify);
2078 runc[l].critic=runc[l].first=(ttvcritic_list *)((chain_list *)pc->det[l]->DATA)->DATA;
2079 runc[l].end=findlastgate(runc[l].critic);
2080 runc[l].addrc=0;
2081 runc[l].total=0;
2082 if (ref==-1) ref=l;
2083 }
2084 }
2085 Board_NewLine(b);
2086 Board_SetValue(b, COL_CP_NAME, "Name");
2087 for (l=0;l<4; l++)
2088 {
2089 if (pc->det[l]!=NULL)
2090 {
2091 // sprintf(key, "Delay", DISPLAY_time_string);
2092 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+1, "Delay");
2093 // sprintf(key, "Slope", DISPLAY_time_string);
2094 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+2, "Slope");
2095 }
2096 }
2097
2098 Board_NewSeparation(b);
2099
2100 while (runc[ref].critic!=runc[ref].end->NEXT)
2101 {
2102 if (runc[ref].critic==runc[ref].first || strcmp(ttv_GetDetailType(runc[ref].critic),"rc")!=0)
2103 {
2104 Board_NewLine(b);
2105 Board_SetValue(b, COL_CP_NAME, ttv_GetDetailSignalName(runc[ref].critic));
2106 for (l=0;l<4; l++)
2107 {
2108 if (pc->det[l]!=NULL)
2109 {
2110 runc[l].total+=runc[l].addrc+ttv_GetDetailDelay(runc[l].critic);
2111 runc[l].addrc=0;
2112 sprintf(key," (%c)", dirconv(ttv_GetDetailDirection(runc[l].critic)));
2113 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+0, key);
2114 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+1, FormaT(runc[l].total*DISPLAY_time_unit, key, DISPLAY_time_format));
2115 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+2, FormaT(ttv_GetDetailSlope(runc[l].critic)*DISPLAY_time_unit, key, DISPLAY_time_format));
2116
2117 runc[l].critic=runc[l].critic->NEXT;
2118 }
2119 }
2120 }
2121 else
2122 {
2123 for (l=0; l<4; l++)
2124 {
2125 if (pc->det[l]!=NULL)
2126 {
2127 runc[l].addrc=ttv_GetDetailDelay(runc[l].critic);
2128 runc[l].critic=runc[l].critic->NEXT;
2129 }
2130 }
2131 }
2132 }
2133
2134 list2=GetAllHTElems_sub(pc->ends, 1);
2135 if (list2!=NULL)
2136 {
2137 Board_NewLine(b);
2138 Board_SetValue(b, COL_CP_NAME, " -- ending rc nodes below --");
2139 for (ch=list2; ch!=NULL; ch=ch->NEXT)
2140 {
2141 tab=(ttvcritic_list **)ch->DATA;
2142 Board_NewLine(b);
2143 for (l=0;l<4; l++)
2144 {
2145 if (tab[l]!=NULL)
2146 {
2147 ref=l;
2148 sprintf(key," (%c)", dirconv(ttv_GetDetailDirection(tab[l])));
2149 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+0, key);
2150 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+1, FormaT((runc[l].total+ttv_GetDetailDelay(tab[l]))*DISPLAY_time_unit, key, DISPLAY_time_format));
2151 Board_SetValue(b, 10+(l*COLUMN_DISTANCE)+2, FormaT(ttv_GetDetailSlope(tab[l])*DISPLAY_time_unit, key, DISPLAY_time_format));
2152 }
2153 }
2154 Board_SetValue(b, COL_CP_NAME, ttv_GetDetailNodeName(tab[ref]));
2155 mbkfree(tab);
2156 }
2157 }
2158
2159 freechain(list2);
2160 delht(pc->ends);
2161 for (l=0;l<4; l++)
2162 {
2163 for (ch=pc->det[l]; ch!=NULL; ch=ch->NEXT)
2164 {
2165 ttv_FreePathDetail((chain_list *)ch->DATA);
2166 freechain((chain_list *)ch->DATA);
2167 }
2168 freechain(pc->det[l]);
2169 }
2170 mbkfree(pc);
2171
2172 Board_Display(f, b, "");
2173 Board_FreeBoard(b);
2174 avt_fprintf(f, "\n");
2175 }
2176
2177 freechain(list);
2178
2179 DeleteNameAllocator(&na);
2180 ttv_FreePathList(pth);
2181 freechain(pth);
2182 }
2183
2184
2185
2186 #define MINCLOCKPATH_PTYPE 0xfab19105
2187 #define MAXCLOCKPATH_PTYPE 0xfac19105
2188 #define MINDATAPATH_PTYPE 0xfad19105
2189 #define MAXDATAPATH_PTYPE 0xfae19105
2190
2191
2192 /* added by Anto */
2193
2194 static stbck *
2195 ttv_GetGoodStbClock(ttvevent_list *tve, ttvevent_list *latch)
2196 {
2197 stbnode *node;
2198 stbck *clock=NULL;
2199
2200 if (tve==NULL) return NULL;
2201 node=stb_getstbnode(latch);
2202 if (node!=NULL)
2203 {
2204 for (clock=node->CK; clock!=NULL && clock->CMD!=tve; clock=clock->NEXT) ;
2205 if (clock==NULL) clock=node->CK;
2206 }
2207 return clock;
2208 }
2209 /* end added Anto */
2210
2211 static chain_list *associatepathtosig(ttvfig_list *tf, char *ck, char *in, char *out, char *minmax, long ptypenum, char enddir, char *path)
2212 {
2213 chain_list *lst, *cl, *extr=NULL;
2214 ttvpath_list *tp;
2215 ttvsig_list *sig;
2216 ptype_list *pt;
2217 char dir[4]="??";
2218
2219 dir[1]=enddir;
2220 lst=ttv_internal_GetPaths(tf, ck, in, out, dir, INT_MAX, "critic", path, minmax);
2221
2222 for (cl=lst; cl!=NULL; cl=cl->NEXT)
2223 {
2224 tp=(ttvpath_list *)cl->DATA;
2225 sig=tp->ROOT->ROOT;
2226 if ((pt=getptype(sig->USER, ptypenum))==NULL)
2227 {
2228 pt=sig->USER=addptype(sig->USER, ptypenum, NULL);
2229 extr=addchain(extr, sig);
2230 }
2231 pt->DATA=addchain((chain_list *)pt->DATA, tp);
2232 }
2233
2234 freechain(lst);
2235 return extr;
2236 }
2237
2238 static void associatepathtosig_more(ttvfig_list *tf, chain_list *lst, long minmax, long ptypenum, chain_list **siglist)
2239 {
2240 ptype_list *pt;
2241 ttvsig_list *tvs;
2242
2243 while (lst!=NULL)
2244 {
2245 tvs=lst->DATA;
2246 if ((tvs->TYPE & TTV_SIG_C)!=0 && (tvs->TYPE & TTV_SIG_BYPASSIN)==0)
2247 {
2248 if ((pt=getptype(tvs->USER, ptypenum))==NULL)
2249 {
2250 pt=tvs->USER=addptype(tvs->USER, ptypenum, NULL);
2251 *siglist=addchain(*siglist, tvs);
2252 }
2253 pt->DATA=addchain((chain_list *)pt->DATA, ttv_create_one_node_path(tf, tf, &tvs->NODE[0], minmax));
2254 pt->DATA=addchain((chain_list *)pt->DATA, ttv_create_one_node_path(tf, tf, &tvs->NODE[1], minmax));
2255 }
2256 lst=lst->NEXT;
2257 }
2258 }
2259
2260 static void cleanpathonsig(chain_list *cl, long ptypenum)
2261 {
2262 ttvsig_list *sig;
2263 ptype_list *pt;
2264 while (cl!=NULL)
2265 {
2266 sig=(ttvsig_list *)cl->DATA;
2267 if ((pt=getptype(sig->USER, ptypenum))!=NULL)
2268 {
2269
2270 ttv_FreePathList((chain_list *)pt->DATA);
2271 freechain((chain_list *)pt->DATA);
2272 sig->USER=delptype(sig->USER, ptypenum);
2273 }
2274 cl=cl->NEXT;
2275 }
2276 }
2277
2278 #define BREAKCONSTRAINT 0xfab70809
2279
2280 static void ttv_setupbreakinfo(ttvfig_list *tvf, ttvevent_list *tve, long type)
2281 {
2282 ttvline_list *line ;
2283 ptype_list *pt ;
2284 long delay ;
2285
2286
2287 if((type & TTV_FIND_PATH) == TTV_FIND_PATH)
2288 line = tve->INPATH ;
2289 else
2290 line = tve->INLINE ;
2291
2292 for(; line != NULL ; line = line->NEXT)
2293 {
2294 if(((line->TYPE & (TTV_LINE_D|TTV_LINE_T)) != 0) &&
2295 (line->FIG != tvf))
2296 continue ;
2297
2298 if((line->NODE->ROOT->TYPE & TTV_SIG_B)!=0 &&
2299 ((line->TYPE & TTV_LINE_U) == TTV_LINE_U || (line->TYPE & TTV_LINE_O) == TTV_LINE_O))
2300 {
2301 if ((pt=getptype(line->NODE->USER, BREAKCONSTRAINT))==NULL)
2302 pt=line->NODE->USER=addptype(line->NODE->USER, BREAKCONSTRAINT, addptype(NULL, (long)NULL, NULL));
2303
2304 // delay=ttv_getdelaymax(line);
2305
2306 pt=(ptype_list *)pt->DATA;
2307 if((line->TYPE & TTV_LINE_U) == TTV_LINE_U)
2308 pt->TYPE=(long )addptype((ptype_list *)pt->TYPE, (long)line, line->ROOT);
2309 else
2310 pt->DATA=addptype((ptype_list *)pt->DATA, (long)line, line->ROOT);
2311 }
2312 }
2313 }
2314
2315 static void ttv_removebreakinfo(ttvevent_list *tve)
2316 {
2317 ptype_list *pt ;
2318 if ((pt=getptype(tve->USER, BREAKCONSTRAINT))!=NULL)
2319 {
2320 pt=(ptype_list *)pt->DATA;
2321 freeptype((ptype_list *)pt->TYPE);
2322 freeptype((ptype_list *)pt->DATA);
2323 freeptype(pt);
2324 tve->USER=delptype(tve->USER, BREAKCONSTRAINT);
2325 }
2326 }
2327
2328 static ptype_list *ttv_getbreakinfo(ttvevent_list *tve, int setup)
2329 {
2330 ptype_list *pt ;
2331 if ((pt=getptype(tve->USER, BREAKCONSTRAINT))!=NULL)
2332 {
2333 pt=(ptype_list *)pt->DATA;
2334 if (setup)
2335 return dupptypelst((ptype_list *)pt->TYPE);
2336 else
2337 return dupptypelst((ptype_list *)pt->DATA);
2338 }
2339 return NULL;
2340 }
2341
2342 #define CONTRAINTOBJECT_REFCOUNT 0xfab70806
2343 #define CONTRAINTOBJECT_GENE_CLOCK_PATH_MIN 0xfab70828
2344 #define CONTRAINTOBJECT_GENE_CLOCK_PATH_MAX 0xfab70829
2345
2346
2347 typedef struct
2348 {
2349 double min;
2350 ConstraintObject *setup, *hold;
2351 } BI_ConstraintObject;
2352
2353 double ttv_ComputeConstraintVALID(ConstraintObject *co)
2354 {
2355 return ttv_GetPathDelay(co->datapath)+co->margedata+co->intrinsic_margin;
2356 }
2357 double ttv_ComputeConstraintREQUIRED(ConstraintObject *co)
2358 {
2359 return ttv_GetPathDelay(co->clockpath)+co->margeclock+co->clocklatency;
2360 }
2361
2362 double ttv_ComputeConstraintObjectMargin(ConstraintObject *co)
2363 {
2364 double val;
2365
2366 val=ttv_ComputeConstraintVALID(co)-ttv_ComputeConstraintREQUIRED(co);
2367
2368 if (co->setup)
2369 return val;
2370 else
2371 return -val;
2372 }
2373 typedef int (*sortfunc)(const void *a0, const void *b0);
2374
2375 static int ConstraintObjectSort(const void *a0, const void *b0)
2376 {
2377 ConstraintObject *a=*(ConstraintObject **)a0, *b=*(ConstraintObject **)b0;
2378 int cmp, cmp0;
2379 double m0, m1;
2380 cmp=strcmp(a->datapath->NODE->ROOT->NAME, b->datapath->NODE->ROOT->NAME);
2381 if (cmp<0) return -1;
2382 if (cmp>0) return 1;
2383
2384 if (a->datapath->NODE->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2385 if (b->datapath->NODE->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2386 if (cmp<cmp0) return -1;
2387 if (cmp>cmp0) return 1;
2388
2389 cmp=strcmp(a->clockpath->NODE->ROOT->NAME, b->clockpath->NODE->ROOT->NAME);
2390 if (cmp<0) return -1;
2391 if (cmp>0) return 1;
2392
2393 if (a->clockpath->NODE->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2394 if (b->clockpath->NODE->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2395 if (cmp<cmp0) return -1;
2396 if (cmp>cmp0) return 1;
2397
2398 m0=ttv_ComputeConstraintObjectMargin(a);
2399 m1=ttv_ComputeConstraintObjectMargin(b);
2400
2401 if (m0<m1) return -1;
2402 if (m0>m1) return 1;
2403
2404 return 0;
2405 }
2406
2407 static int ConstraintObjectSort_for_C2L_cmp(ConstraintObject *a, ConstraintObject *b, int ids, int ide, int ics, int ice, int imargin)
2408 {
2409 int cmp, cmp0;
2410 double m0, m1;
2411
2412 if (!ids)
2413 {
2414 cmp=strcmp(a->datapath->NODE->ROOT->NAME, b->datapath->NODE->ROOT->NAME);
2415 if (cmp<0) return -1;
2416 if (cmp>0) return 1;
2417
2418 if (a->datapath->NODE->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2419 if (b->datapath->NODE->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2420 if (cmp<cmp0) return -1;
2421 if (cmp>cmp0) return 1;
2422 }
2423
2424 if (!ide)
2425 {
2426 cmp=strcmp(a->datapath->ROOT->ROOT->NAME, b->datapath->ROOT->ROOT->NAME);
2427 if (cmp<0) return -1;
2428 if (cmp>0) return 1;
2429
2430 if (a->datapath->ROOT->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2431 if (b->datapath->ROOT->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2432 if (cmp<cmp0) return -1;
2433 if (cmp>cmp0) return 1;
2434 }
2435
2436 if (!ics || ics==2)
2437 {
2438 cmp=strcmp(a->clockpath->NODE->ROOT->NAME, b->clockpath->NODE->ROOT->NAME);
2439 if (cmp<0) return -1;
2440 if (cmp>0) return 1;
2441
2442 if (ics==0)
2443 {
2444 if (a->clockpath->NODE->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2445 if (b->clockpath->NODE->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2446 if (cmp<cmp0) return -1;
2447 if (cmp>cmp0) return 1;
2448 }
2449 }
2450
2451 if (!ice)
2452 {
2453 cmp=strcmp(a->clockpath->ROOT->ROOT->NAME, b->clockpath->ROOT->ROOT->NAME);
2454 if (cmp<0) return -1;
2455 if (cmp>0) return 1;
2456
2457 if (a->clockpath->ROOT->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2458 if (b->clockpath->ROOT->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2459 if (cmp<cmp0) return -1;
2460 if (cmp>cmp0) return 1;
2461 }
2462
2463 if (!imargin)
2464 {
2465 m0=ttv_ComputeConstraintObjectMargin(a);
2466 m1=ttv_ComputeConstraintObjectMargin(b);
2467
2468 if (m0>m1) return -1;
2469 if (m0<m1) return 1;
2470 }
2471
2472 return 0;
2473 }
2474
2475 static int cfgclock, cfgcmd;
2476
2477 static int ConstraintObjectSort_for_C2L(const void *a0, const void *b0)
2478 {
2479 ConstraintObject *a=*(ConstraintObject **)a0, *b=*(ConstraintObject **)b0;
2480 return ConstraintObjectSort_for_C2L_cmp(a, b, 0, 0, cfgclock, cfgcmd, 0);
2481 }
2482
2483
2484 static int BI_ConstraintObjectSort(const void *a0, const void *b0)
2485 {
2486 BI_ConstraintObject *a=(BI_ConstraintObject *)a0, *b=(BI_ConstraintObject *)b0;
2487 int cmp, cmp0;
2488 ConstraintObject *coa=a->setup, *cob=b->setup;
2489
2490 if (coa==NULL) coa=a->hold;
2491 if (cob==NULL) cob=b->hold;
2492
2493
2494 cmp=strcmp(coa->datapath->NODE->ROOT->NAME, cob->datapath->NODE->ROOT->NAME);
2495 if (cmp<0) return -1;
2496 if (cmp>0) return 1;
2497
2498 if (coa->datapath->NODE->TYPE & TTV_NODE_UP) cmp=1; else cmp=0;
2499 if (cob->datapath->NODE->TYPE & TTV_NODE_UP) cmp0=1; else cmp0=0;
2500 if (cmp<cmp0) return -1;
2501 if (cmp>cmp0) return 1;
2502
2503 if (a->min<b->min) return 1;
2504 if (a->min>b->min) return -1;
2505
2506 return 0;
2507 }
2508
2509 ttvevent_list *ttv_GetClockPathCmd(ttvevent_list *node, ttvevent_list *cmd, int hzpath, int setup, int *mustbehz)
2510 {
2511 ttvevent_list *tve;
2512 ttvevent_list *revert_tve;
2513 int prech=0, breakp=0, fflop=0;
2514 ptype_list *pt;
2515
2516 if ((node->ROOT->TYPE & TTV_SIG_R)!=0) prech=1;
2517 else if ((node->ROOT->TYPE & TTV_SIG_B)!=0) breakp=1;
2518 else if ((node->ROOT->TYPE & TTV_SIG_LF)==TTV_SIG_LF) fflop=1;
2519 if ((tve=cmd)==NULL)
2520 {
2521 if (prech) tve=node;
2522 else if (breakp)
2523 {
2524 if ((pt=getptype(node->ROOT->USER, STB_BREAK_TEST_EVENT))!=NULL)
2525 tve=(ttvevent_list *)pt->DATA;
2526 }
2527 }
2528
2529 *mustbehz=0;
2530 if (tve!=NULL)
2531 {
2532 if (prech)
2533 {
2534 if (!hzpath)
2535 {
2536 revert_tve=tve, *mustbehz=1;
2537 }
2538 else
2539 {
2540 revert_tve=tve;
2541 }
2542 }
2543 else if (breakp || fflop)
2544 revert_tve=tve;
2545 else
2546 {
2547 if (!setup || !ttv_has_strict_setup(node))
2548 revert_tve=ttv_opposite_event(tve);
2549 else
2550 revert_tve=tve;
2551 }
2552
2553 tve=revert_tve;
2554 }
2555 return tve;
2556 }
2557
2558 static void ttv_sortaddedpaths(chain_list **paths, int max)
2559 {
2560 ttvpath_list *pth;
2561 chain_list *cl, *ch;
2562 ptype_list *tp;
2563
2564 if (*paths==NULL) return;
2565
2566 for (cl=*paths; cl!=NULL; cl=cl->NEXT)
2567 {
2568 pth=(ttvpath_list *)cl->DATA;
2569 if (cl->NEXT!=NULL)
2570 pth->NEXT=cl->NEXT->DATA;
2571 else
2572 pth->NEXT=NULL;
2573 }
2574
2575 pth=(ttvpath_list *)(*paths)->DATA;
2576 freechain(*paths);
2577
2578 pth=ttv_classpath(pth, max?TTV_FIND_MAX:TTV_FIND_MIN);
2579
2580 cl=ch=NULL;
2581 while (pth!=NULL)
2582 {
2583 if ((tp=getptype(pth->NODE->USER, TTV_SIG_MARQUE))==NULL)
2584 tp=pth->NODE->USER=addptype(pth->NODE->USER, TTV_SIG_MARQUE, (void *)0);
2585
2586 if ((((long)tp->DATA & (TTV_NODE_UP|TTV_NODE_DOWN)) & (pth->ROOT->TYPE & (TTV_NODE_UP|TTV_NODE_DOWN)))==0)
2587 {
2588 cl=addchain(cl, pth);
2589 tp->DATA=(void *)(((long)tp->DATA) | pth->ROOT->TYPE);
2590 }
2591 else
2592 ch=addchain(ch, pth);
2593 pth=pth->NEXT;
2594 }
2595
2596 ttv_FreePathList(ch);
2597 freechain(ch);
2598
2599 for (ch=cl; ch!=NULL; ch=ch->NEXT)
2600 {
2601 pth=(ttvpath_list *)ch->DATA;
2602 pth->NODE->USER=testanddelptype(pth->NODE->USER, TTV_SIG_MARQUE);
2603 }
2604
2605 *paths=reverse(cl);
2606 }
2607 static chain_list *getcmdpaths_new(ttvfig_list *tf, ttvevent_list *cmd_ev, int max, int hz)
2608 {
2609 long search;
2610 ptype_list *pt0;
2611 chain_list *last, *sp;
2612 ttvpath_list *pth;
2613
2614 if (max) search=TTV_FIND_MAX, max=1;
2615 else search=TTV_FIND_MIN, max=0;
2616
2617 search|=TTV_FIND_LINE;
2618
2619 last=NULL;
2620
2621 if (max) search=MAXCLOCKPATH_PTYPE;
2622 else search=MINCLOCKPATH_PTYPE;
2623
2624 if ((pt0=getptype(cmd_ev->ROOT->USER, search))==NULL) sp=NULL;
2625 else sp=(chain_list *)pt0->DATA;
2626
2627 if (sp==NULL && ttv_IsClock(cmd_ev->ROOT) && (cmd_ev->ROOT->TYPE & TTV_SIG_BYPASSIN)==0)
2628 {
2629 sp=addchain(sp, ttv_create_one_node_path(tf, tf, cmd_ev, (search & (TTV_FIND_MIN|TTV_FIND_MAX))));
2630 cmd_ev->ROOT->USER=addptype(cmd_ev->ROOT->USER, search, sp);
2631 }
2632
2633 while (sp!=NULL)
2634 {
2635 pth=(ttvpath_list *)sp->DATA;
2636 if (pth->ROOT==cmd_ev
2637 && ((hz && (pth->TYPE & TTV_FIND_HZ)!=0)
2638 || (!hz && (pth->TYPE & TTV_FIND_HZ)==0))
2639 )
2640 {
2641 last=addchain(last, pth);
2642 }
2643 sp=sp->NEXT;
2644 }
2645
2646 return last;
2647 }
2648
2649 static chain_list *getcmdpaths_data_new(ttvfig_list *tf, ttvevent_list *cmd_ev, int max)
2650 {
2651 long search;
2652 ptype_list *pt0;
2653 chain_list *last, *sp;
2654 ttvpath_list *pth;
2655
2656 if (max) search=TTV_FIND_MAX, max=1;
2657 else search=TTV_FIND_MIN, max=0;
2658
2659 search|=TTV_FIND_LINE;
2660
2661 last=NULL;
2662
2663 if (max) search=MAXDATAPATH_PTYPE;
2664 else search=MINDATAPATH_PTYPE;
2665
2666 if ((pt0=getptype(cmd_ev->ROOT->USER, search))==NULL) sp=NULL;
2667 else sp=(chain_list *)pt0->DATA;
2668
2669 if (sp==NULL && (cmd_ev->ROOT->TYPE & TTV_SIG_C)!=0)
2670 {
2671 sp=addchain(sp, ttv_create_one_node_path(tf, tf, cmd_ev, (search & (TTV_FIND_MIN|TTV_FIND_MAX))));
2672 cmd_ev->ROOT->USER=addptype(cmd_ev->ROOT->USER, search, sp);
2673 }
2674
2675 while (sp!=NULL)
2676 {
2677 pth=(ttvpath_list *)sp->DATA;
2678 if (pth->ROOT==cmd_ev && !ttv_IsClock(pth->NODE->ROOT))
2679 {
2680 last=addchain(last, pth);
2681 }
2682 sp=sp->NEXT;
2683 }
2684
2685 return last;
2686 }
2687
2688 static void ttv_sort_cotab(chain_list *allobj, sortfunc sf)
2689 {
2690 ConstraintObject **cotab;
2691 chain_list *cl;
2692 int i, tot=countchain(allobj);
2693 cotab=(ConstraintObject **)mbkalloc(sizeof(ConstraintObject *)*tot);
2694 for (cl=allobj, i=0; cl!=NULL; cl=cl->NEXT, i++) cotab[i]=(ConstraintObject *)cl->DATA;
2695 qsort(cotab, tot, sizeof(ConstraintObject *), sf);
2696 for (cl=allobj, i=0; cl!=NULL; cl=cl->NEXT, i++) cl->DATA=cotab[i];
2697 mbkfree(cotab);
2698 }
2699
2700 chain_list *ttv_getnext_different_ConstraintObject(chain_list *lst, ConstraintObject *co, int ics, int ice)
2701 {
2702 while (lst!=NULL)
2703 {
2704 if (ConstraintObjectSort_for_C2L_cmp(co, (ConstraintObject *)lst->DATA, 0, 0, ics, ice, 1)!=0) break;
2705 lst=delchain(lst, lst);
2706 }
2707 return lst;
2708 }
2709
2710
2711 static void ttv_GetDirectiveConstraintObject_SetupNodes(chain_list *directivenodes)
2712 {
2713 chain_list *cl;
2714 ttvsig_list *tvs;
2715
2716 for(cl=directivenodes; cl!=NULL; cl=cl->NEXT)
2717 {
2718 tvs=(ttvsig_list *)cl->DATA;
2719 if((tvs->TYPE & (TTV_SIG_C | TTV_SIG_L | TTV_SIG_R | TTV_SIG_B)) == 0)
2720 {
2721 tvs->NODE[0].TYPE |= TTV_NODE_STOP ;
2722 tvs->NODE[1].TYPE |= TTV_NODE_STOP ;
2723 if ((tvs->TYPE & TTV_SIG_N) != 0)
2724 TTV_MORE_SEARCH_OPTIONS|=TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N;
2725 TTV_MORE_SEARCH_OPTIONS|=TTV_MORE_OPTIONS_CROSS_STOP_NODE_IF_NONSTOP;
2726 }
2727 }
2728 }
2729
2730 static void ttv_GetDirectiveConstraintObject_UnSetupNodes(chain_list *directivenodes)
2731 {
2732 chain_list *cl;
2733 ttvsig_list *tvs;
2734
2735 TTV_MORE_SEARCH_OPTIONS&=~(TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N|TTV_MORE_OPTIONS_CROSS_STOP_NODE_IF_NONSTOP);
2736
2737 for(cl=directivenodes; cl!=NULL; cl=cl->NEXT)
2738 {
2739 tvs=(ttvsig_list *)cl->DATA;
2740 if((tvs->TYPE & (TTV_SIG_C | TTV_SIG_L | TTV_SIG_R | TTV_SIG_B)) == 0)
2741 {
2742 tvs->NODE[0].TYPE &= ~TTV_NODE_STOP ;
2743 tvs->NODE[1].TYPE &= ~TTV_NODE_STOP ;
2744 }
2745 }
2746 }
2747
2748 static void ttv_GetDirectiveConstraintObject(chain_list *allnodes, chain_list **directivecmd, chain_list **directivedata)
2749 {
2750 chain_list *allcmd=NULL, *cl, *alldirectivenode=NULL;
2751 ttvsig_list *tvs, *tvscmd;
2752 ptype_list *checkcmd, *pt;
2753 int i, cnt, j;
2754
2755 for (cl=allnodes; cl!=NULL; cl=cl->NEXT)
2756 {
2757 tvs=(ttvsig_list *)cl->DATA;
2758 cnt=0;
2759 for (j=0; j<2; j++)
2760 {
2761 for (i=0; i<2; i++)
2762 {
2763 checkcmd=ttv_get_directive_slopes(&tvs->NODE[i], j, -1, -1);
2764 // checkcmd=(ptype_list *)append((chain_list *)ttv_get_directive_slopes(&tvs->NODE[i], j, 1), (chain_list *)checkcmd);
2765 for (pt=checkcmd; pt!=NULL; pt=pt->NEXT)
2766 {
2767 cnt++;
2768 tvscmd=((ttvevent_list *)pt->DATA)->ROOT;
2769 if (getptype(tvscmd->USER, TTV_SIG_MARQUE)==NULL)
2770 {
2771 allcmd=addchain(allcmd, tvscmd);
2772 tvscmd->USER=addptype(tvscmd->USER, TTV_SIG_MARQUE, NULL);
2773 }
2774 }
2775 freeptype(checkcmd);
2776 }
2777 }
2778 if (cnt!=0)
2779 alldirectivenode=addchain(alldirectivenode, tvs);
2780 }
2781
2782 for (cl=allcmd; cl!=NULL; cl=cl->NEXT)
2783 {
2784 tvs=(ttvsig_list *)cl->DATA;
2785 tvs->USER=testanddelptype(tvs->USER, TTV_SIG_MARQUE);
2786 }
2787
2788 *directivecmd=allcmd;
2789 *directivedata=alldirectivenode;
2790 }
2791
2792 static void ttv_FreeConstraintObjectManagement(ttvfig_list *tf, chain_list *allnodes)
2793 {
2794 ptype_list *pt;
2795 ConstraintObjectManagement *com;
2796 chain_list *cl;
2797 ttvsig_list *tvs;
2798
2799 if ((pt=getptype(tf->USER, CONTRAINTOBJECT_REFCOUNT))!=NULL)
2800 {
2801 com=(ConstraintObjectManagement *)pt->DATA;
2802 freechain(com->directivedata);
2803 freechain(com->connectordone);
2804 for (cl=allnodes; cl!=NULL; cl=cl->NEXT)
2805 {
2806 tvs=(ttvsig_list *)cl->DATA;
2807 if ((tvs->TYPE & TTV_SIG_Q)!=0)
2808 {
2809 ttv_removebreakinfo(&tvs->NODE[0]);
2810 ttv_removebreakinfo(&tvs->NODE[1]);
2811 }
2812 }
2813 mbkfree(com);
2814 tf->USER=delptype(tf->USER, CONTRAINTOBJECT_REFCOUNT);
2815 }
2816 }
2817
2818
2819 static void ttv_SetupGeneratedClockPaths(ttvfig_list *tvf)
2820 {
2821 chain_list *clks;
2822 ttvsig_list *tvs;
2823 int i;
2824
2825 clks=ttv_GetClockList(tvf);
2826 while (clks!=NULL)
2827 {
2828 tvs=(ttvsig_list *)clks->DATA;
2829 for (i=0; i<2; i++)
2830 {
2831 tvs->NODE[i].USER=addptype(tvs->NODE[i].USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MIN, ttv_GetGeneratedClockPaths(tvf, &tvs->NODE[i], "min"));
2832 tvs->NODE[i].USER=addptype(tvs->NODE[i].USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MAX, ttv_GetGeneratedClockPaths(tvf, &tvs->NODE[i], "max"));
2833 }
2834 clks=delchain(clks, clks);
2835 }
2836 }
2837 static void ttv_UnSetupGeneratedClockPaths(ttvfig_list *tvf)
2838 {
2839 chain_list *clks, *cl;
2840 ttvsig_list *tvs;
2841 int i;
2842 ptype_list *pt;
2843
2844 clks=ttv_GetClockList(tvf);
2845 while (clks!=NULL)
2846 {
2847 tvs=(ttvsig_list *)clks->DATA;
2848 for (i=0; i<2; i++)
2849 {
2850 if ((pt=getptype(tvs->NODE[i].USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MIN))!=NULL)
2851 {
2852 cl=(chain_list *)pt->DATA;
2853 ttv_FreePathList(cl);
2854 freechain(cl);
2855 }
2856 if ((pt=getptype(tvs->NODE[i].USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MAX))!=NULL)
2857 {
2858 cl=(chain_list *)pt->DATA;
2859 ttv_FreePathList(cl);
2860 freechain(cl);
2861 }
2862 }
2863 clks=delchain(clks, clks);
2864 }
2865 }
2866
2867 static void ttv_GetGeneratedClockPathsInfo(ttvevent_list *tve, int max, double *latency, ttvevent_list **master)
2868 {
2869 chain_list *cl;
2870 ptype_list *pt;
2871
2872 *latency=0;
2873 *master=NULL;
2874
2875 if (max)
2876 pt=getptype(tve->USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MAX);
2877 else
2878 pt=getptype(tve->USER, CONTRAINTOBJECT_GENE_CLOCK_PATH_MIN);
2879
2880 if (pt!=NULL && (cl=(chain_list *)pt->DATA)!=NULL)
2881 {
2882 *master=((ttvpath_list *)cl->DATA)->NODE;
2883 while (cl!=NULL)
2884 {
2885 *latency+=ttv_GetPathDelay((ttvpath_list *)cl->DATA);
2886 cl=cl->NEXT;
2887 }
2888 }
2889 }
2890
2891
2892 void ttv_FreeConstraintObject_sub(ConstraintObject *co, int freeclocks)
2893 {
2894 ptype_list *pt;
2895 chain_list *allnodes;
2896
2897 co->com->count--;
2898 if (co->com->count==0)
2899 {
2900 allnodes=ttv_getsigbytype(co->com->tf,NULL,TTV_SIG_TYPEALL,NULL);
2901 cleanpathonsig(allnodes, MINDATAPATH_PTYPE);
2902 cleanpathonsig(allnodes, MAXDATAPATH_PTYPE);
2903
2904 if (freeclocks)
2905 {
2906 cleanpathonsig(allnodes, MINCLOCKPATH_PTYPE);
2907 cleanpathonsig(allnodes, MAXCLOCKPATH_PTYPE);
2908 ttv_UnSetupGeneratedClockPaths(co->com->tf);
2909 ttv_FreeConstraintObjectManagement(co->com->tf, allnodes);
2910 }
2911 freechain(allnodes);
2912 }
2913 mbkfree(co);
2914 }
2915
2916 void ttv_FreeConstraints_sub(chain_list *allobj, ttvfig_list *tvf, int autoclean)
2917 {
2918 chain_list *allnodes;
2919 while (allobj!=NULL)
2920 {
2921 ttv_FreeConstraintObject_sub((ConstraintObject *)allobj->DATA, autoclean);
2922 allobj=allobj->NEXT;
2923 }
2924 if (tvf!=NULL)
2925 {
2926 allnodes=ttv_getsigbytype(tvf,NULL,TTV_SIG_TYPEALL,NULL);
2927 cleanpathonsig(allnodes, MINCLOCKPATH_PTYPE);
2928 cleanpathonsig(allnodes, MAXCLOCKPATH_PTYPE);
2929 ttv_FreeConstraintObjectManagement(tvf, allnodes);
2930 freechain(allnodes);
2931 }
2932 }
2933
2934 double ttv_GetLatchIntrinsicQuick(ttvfig_list *tvf, ttvevent_list *latch, ttvevent_list *cmd, int setup, ttvline_list **rline)
2935 {
2936 long type, val;
2937 if ((ttv_getloadedfigtypes(tvf) & TTV_FILE_DTX)==TTV_FILE_DTX)
2938 type = TTV_FIND_LINE;
2939 else
2940 type = TTV_FIND_PATH;
2941
2942 if (setup) type|=TTV_FIND_SETUP;
2943 else type|=TTV_FIND_HOLD;
2944
2945 val=ttv_getconstraintquick(tvf,latch->ROOT->ROOT,latch,cmd,type|TTV_FIND_MAX,rline);
2946 if (val==TTV_NOTIME) val=0;
2947 return _LONG_TO_DOUBLE(val);
2948 }
2949
2950 chain_list *ttv_GetConstraints(ttvfig_list *tf, char *inputconnector, char *towhat)
2951 {
2952 ttvsig_list *latch, *tvs;
2953 ttvevent_list *in_ev, *out_ev, *checkcmd;
2954 ttvpath_list *tp;
2955 int i, tot, hz, j;
2956 chain_list *latchlist, *cl, *ch, *connectorlist;
2957 ptype_list *cmdlist;
2958 chain_list *pth, *cmdsigsmin, *cmdsigsmax, *datasigmin, *datasigmax, *allobj;
2959 long margedata, margeclock, overlapc, overlapd;
2960 long old0, old1;
2961 ptype_list *pt;
2962 int saveTTV_MAX_PATH_PERIOD;
2963 ConstraintObject *co;
2964 chain_list *directivecmd, *allnodes, *allclocks;
2965 ConstraintObjectManagement *com;
2966 char *tok, *c, buf1[1024];
2967 int latchh=0, prech=0, clockgating=0, breakp=0;
2968 ttvline_list *rline;
2969
2970 API_TEST_TOKEN_SUB(TMA_API,"tma")
2971
2972 allclocks=ttv_getclocksiglist(tf);
2973
2974 if (allclocks==NULL)
2975 {
2976 avt_errmsg(TTV_API_ERRMSG, "042", AVT_ERROR);
2977 return NULL;
2978 }
2979
2980
2981 strcpy(buf1, towhat);
2982 tok=strtok_r(buf1, " ", &c);
2983 while (tok!=NULL)
2984 {
2985 if (strcasecmp(tok,"latch")==0) latchh=1;
2986 else if (strcasecmp(tok,"precharge")==0) prech=1;
2987 else if (strcasecmp(tok,"clockgating")==0) clockgating=1;
2988 else if (strcasecmp(tok,"breakpoint")==0) breakp=1;
2989 else if (strcasecmp(tok,"all")==0) latchh=prech=clockgating=breakp=1;
2990 else
2991 avt_errmsg(TTV_API_ERRMSG, "048", AVT_ERROR, tok);
2992 tok=strtok_r(NULL, " ", &c);
2993 }
2994
2995 ttv_setsearchexclude(0, 0, &old0, &old1);
2996
2997 if ((pt=getptype(tf->USER, CONTRAINTOBJECT_REFCOUNT))==NULL)
2998 {
2999 com=(ConstraintObjectManagement *)mbkalloc(sizeof(ConstraintObjectManagement));
3000 com->count=0;
3001 com->tf=tf;
3002 com->connectordone=NULL;
3003 tf->USER=addptype(tf->USER, CONTRAINTOBJECT_REFCOUNT, com);
3004
3005 // retreiving clock path once
3006 allnodes=ttv_getsigbytype(tf,NULL,TTV_SIG_TYPEALL,NULL);
3007 ttv_GetDirectiveConstraintObject(allnodes, &directivecmd, &com->directivedata);
3008 // setup info for breakpoints
3009 for (cl=allnodes; cl!=NULL; cl=cl->NEXT)
3010 {
3011 tvs=(ttvsig_list *)cl->DATA;
3012 if ((tvs->TYPE & TTV_SIG_Q)!=0 || (tvs->TYPE & TTV_SIG_B)!=0)
3013 {
3014 ttv_setupbreakinfo(tf, &tvs->NODE[0], TTV_FIND_LINE);
3015 ttv_setupbreakinfo(tf, &tvs->NODE[1], TTV_FIND_LINE);
3016 }
3017 }
3018 freechain(allnodes);
3019
3020 ttv_GetDirectiveConstraintObject_SetupNodes(directivecmd);
3021
3022 cl=append(ttv_GetInterfaceCommandList(tf), ttv_GetInternalCommandList(tf));
3023 latchlist=append(cl, dupchainlst(directivecmd));
3024 cl=append(ttv_GetInterfaceBreakpointList(tf), ttv_GetInternalBreakpointList(tf));
3025 latchlist=append(cl, latchlist);
3026 cl=append(ttv_GetInterfacePrechargeList(tf), ttv_GetInternalPrechargeList(tf));
3027 latchlist=append(cl, latchlist);
3028
3029 TTV_EXPLICIT_START_NODES=allclocks;
3030 TTV_EXPLICIT_END_NODES=latchlist;
3031 saveTTV_MAX_PATH_PERIOD=V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE;
3032 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE=0;
3033 ttv_SetSearchMode("findcmd");
3034 ttv_SetSearchMode("dual");
3035 cmdsigsmin=associatepathtosig(tf, "*", "*", "*", "min", MINCLOCKPATH_PTYPE, '?', "path");
3036 freechain(cmdsigsmin);
3037 cmdsigsmax=associatepathtosig(tf, "*", "*", "*", "max", MAXCLOCKPATH_PTYPE, '?', "path");
3038 freechain(cmdsigsmax);
3039 ttv_SetSearchMode("!dual");
3040 ttv_SetSearchMode("!findcmd");
3041 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE=saveTTV_MAX_PATH_PERIOD;
3042 TTV_EXPLICIT_START_NODES=TTV_EXPLICIT_END_NODES=NULL;
3043
3044 ttv_GetDirectiveConstraintObject_UnSetupNodes(directivecmd);
3045 freechain(directivecmd);
3046
3047 ttv_SetupGeneratedClockPaths(tf);
3048
3049 if (V_BOOL_TAB[__TMA_ALLOW_ACCESS_AS_CLOCKPATH].VALUE)
3050 {
3051 ch=NULL;
3052 for (cl=latchlist; cl!=NULL; cl=cl->NEXT)
3053 {
3054 tvs=(ttvsig_list *)cl->DATA;
3055
3056 if ((tvs->TYPE & TTV_SIG_Q)!=0)
3057 ch=addchain(ch, tvs);
3058 }
3059
3060 if (ch!=NULL)
3061 {
3062 TTV_EXPLICIT_CLOCK_NODES=allclocks;
3063 TTV_EXPLICIT_END_NODES=ch;
3064 saveTTV_MAX_PATH_PERIOD=V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE;
3065 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE=0;
3066 cmdsigsmin=associatepathtosig(tf, "*", "*", "*", "min", MINCLOCKPATH_PTYPE, '?', "access");
3067 freechain(cmdsigsmin);
3068 cmdsigsmax=associatepathtosig(tf, "*", "*", "*", "max", MAXCLOCKPATH_PTYPE, '?', "access");
3069 freechain(cmdsigsmax);
3070 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE=saveTTV_MAX_PATH_PERIOD;
3071 TTV_EXPLICIT_CLOCK_NODES=TTV_EXPLICIT_END_NODES=NULL;
3072 }
3073
3074 for (cl=ch; cl!=NULL; cl=cl->NEXT)
3075 {
3076 tvs=(ttvsig_list *)cl->DATA;
3077 if ((pt=getptype(tvs->USER, MINCLOCKPATH_PTYPE))!=NULL)
3078 ttv_sortaddedpaths((chain_list **)&pt->DATA, 0);
3079 if ((pt=getptype(tvs->USER, MAXCLOCKPATH_PTYPE))!=NULL)
3080 ttv_sortaddedpaths((chain_list **)&pt->DATA, 1);
3081 }
3082
3083 freechain(ch);
3084 }
3085
3086 freechain(latchlist);
3087 }
3088 else
3089 com=(ConstraintObjectManagement *)pt->DATA;
3090
3091 freechain(allclocks);
3092
3093 allobj=NULL;
3094
3095 // selection des connecteurs sans recherche de datapath
3096 connectorlist=ttv_GetMatchingSignal(tf, inputconnector, "connector");
3097 for (cl=com->connectordone; cl!=NULL; cl=cl->NEXT)
3098 {
3099 tvs=(ttvsig_list *)cl->DATA;
3100 tvs->USER=addptype(tvs->USER, CONTRAINTOBJECT_REFCOUNT, NULL);
3101 }
3102
3103 cl=NULL;
3104 while (connectorlist!=NULL)
3105 {
3106 tvs=(ttvsig_list *)connectorlist->DATA;
3107 if (getptype(tvs->USER, CONTRAINTOBJECT_REFCOUNT)==NULL/* && !ttv_IsClock(tvs)*/)
3108 cl=addchain(cl, tvs);
3109 connectorlist=delchain(connectorlist, connectorlist);
3110 }
3111 connectorlist=cl;
3112
3113 for (cl=com->connectordone; cl!=NULL; cl=cl->NEXT)
3114 {
3115 tvs=(ttvsig_list *)cl->DATA;
3116 tvs->USER=delptype(tvs->USER, CONTRAINTOBJECT_REFCOUNT);
3117 }
3118
3119 if (connectorlist==NULL) return NULL;
3120
3121 // recuperation des datapaths
3122 latchlist=NULL;
3123 if (latchh)
3124 {
3125 cl=append(ttv_GetInterfaceLatchList(tf), ttv_GetInternalLatchList(tf));
3126 latchlist=append(cl, latchlist);
3127 }
3128 if (prech)
3129 {
3130 cl=append(ttv_GetInterfacePrechargeList(tf), ttv_GetInternalPrechargeList(tf));
3131 latchlist=append(cl, latchlist);
3132 }
3133 if (breakp)
3134 {
3135 cl=append(ttv_GetInterfaceBreakpointList(tf), ttv_GetInternalBreakpointList(tf));
3136 latchlist=append(cl, latchlist);
3137 }
3138 if (clockgating)
3139 {
3140 latchlist=append(dupchainlst(com->directivedata), latchlist);
3141 ttv_GetDirectiveConstraintObject_SetupNodes(com->directivedata);
3142 }
3143
3144 TTV_EXPLICIT_START_NODES=connectorlist;
3145 TTV_EXPLICIT_END_NODES=latchlist;
3146 ttv_SetSearchMode("dual");
3147 datasigmin=associatepathtosig(tf, "*", "*", "*", "min", MINDATAPATH_PTYPE, '?', "path");
3148 associatepathtosig_more(tf, latchlist, TTV_FIND_MIN, MINDATAPATH_PTYPE, &datasigmin);
3149 datasigmax=associatepathtosig(tf, "*", "*", "*", "max", MAXDATAPATH_PTYPE, '?', "path");
3150 associatepathtosig_more(tf, latchlist, TTV_FIND_MAX, MAXDATAPATH_PTYPE, &datasigmax);
3151 ttv_SetSearchMode("!dual");
3152 TTV_EXPLICIT_START_NODES=TTV_EXPLICIT_END_NODES=NULL;
3153
3154 freechain(datasigmin);
3155 freechain(datasigmax);
3156
3157 /* for (cl=connectorlist; cl!=NULL; cl=cl->NEXT)
3158 {
3159 tvs=(ttvsig_list *)cl->DATA;
3160 if (getptype(tvs->USER, CONTRAINTOBJECT_REFCOUNT)==NULL)
3161 tvs->USER=addptype(tvs->USER, CONTRAINTOBJECT_REFCOUNT, NULL);
3162 }
3163 */
3164 com->connectordone=append(connectorlist, com->connectordone);
3165
3166 if (clockgating)
3167 ttv_GetDirectiveConstraintObject_UnSetupNodes(com->directivedata);
3168
3169
3170 tot=0;
3171 for (cl=latchlist; cl!=NULL; cl=cl->NEXT)
3172 {
3173 latch=(ttvsig_list *)cl->DATA;
3174
3175 for (i=0; i<2; i++)
3176 {
3177 if ((pt=getptype(latch->USER, i==0?MAXDATAPATH_PTYPE:MINDATAPATH_PTYPE))!=NULL)
3178 pth=(chain_list *)pt->DATA;
3179 else
3180 pth=NULL;
3181
3182 while (pth!=NULL)
3183 {
3184 tp=(ttvpath_list *)pth->DATA;
3185 in_ev=tp->NODE;
3186 out_ev=tp->ROOT;
3187
3188 if ((in_ev->ROOT->TYPE & TTV_SIG_C)!=0)
3189 {
3190 if (mbk_TestREGEX(ttv_GetFullSignalName(tf, in_ev->ROOT), inputconnector))
3191 {
3192 ptype_list *pt;
3193 if ((out_ev->ROOT->TYPE & TTV_SIG_L)!=0)
3194 cmdlist = ttv_getlatchdatacommands(tf,out_ev,TTV_FIND_LINE|(i==0?TTV_FIND_MIN:TTV_FIND_MAX));
3195 else if ((out_ev->ROOT->TYPE & TTV_SIG_B)!=0)
3196 cmdlist = ttv_getbreakinfo(out_ev, i==0?1:0);
3197 else if ((out_ev->ROOT->TYPE & (TTV_SIG_L|TTV_SIG_R|TTV_SIG_B))!=0)
3198 cmdlist = addptype(NULL, 0, out_ev);
3199 else
3200 cmdlist = NULL;
3201
3202 pt=cmdlist;
3203 while (cmdlist!=NULL)
3204 {
3205 checkcmd=ttv_GetClockPathCmd(out_ev, (ttvevent_list *)cmdlist->DATA, (tp->TYPE & TTV_FIND_HZ)!=0?1:0, i==0?1:0, &hz);
3206 ch=getcmdpaths_new(tf, checkcmd, i, hz);
3207 while (ch!=NULL)
3208 {
3209 co=(ConstraintObject *)mbkalloc(sizeof(ConstraintObject));
3210 co->setup=(i==0?1:0);
3211 co->datapath=tp;
3212 co->clockpath=(ttvpath_list *)ch->DATA;
3213 ttv_get_path_margins(tf, co->datapath, co->clockpath, &margedata, &margeclock, &overlapc, &overlapd,0,0);
3214 co->margedata=_LONG_TO_DOUBLE(margedata);
3215 co->margeclock=_LONG_TO_DOUBLE(margeclock);
3216 co->overlapclock=_LONG_TO_DOUBLE(overlapc);
3217 co->overlapdata=_LONG_TO_DOUBLE(overlapd);
3218 co->intrinsic_margin_model=NULL;
3219 if ((out_ev->ROOT->TYPE & TTV_SIG_L)!=0)
3220 {
3221 rline=NULL;
3222 if (i==0)
3223 {
3224 if (!ttv_has_strict_setup(out_ev)) co->intrinsic_margin=ttv_GetLatchIntrinsicQuick(tf, out_ev, co->clockpath->ROOT, 1, &rline);
3225 else co->intrinsic_margin=0;
3226 }
3227 else
3228 {
3229 co->intrinsic_margin=-ttv_GetLatchIntrinsicQuick(tf, out_ev, co->clockpath->ROOT, 0, &rline);
3230 }
3231 co->intrinsic_margin_model=rline?rline->MDMAX:NULL;
3232 }
3233 else
3234 {
3235 if ((out_ev->ROOT->TYPE & TTV_SIG_B)!=0)
3236 {
3237 co->intrinsic_margin=_LONG_TO_DOUBLE(ttv_getdelaymax((ttvline_list *)cmdlist->TYPE));
3238 co->intrinsic_margin_model=((ttvline_list *)cmdlist->TYPE)->MDMAX;
3239 }
3240 else
3241 co->intrinsic_margin=_LONG_TO_DOUBLE(cmdlist->TYPE);
3242 }
3243 ttv_GetGeneratedClockPathsInfo(co->clockpath->NODE, i, &co->clocklatency, &co->masterck);
3244 if (co->masterck==NULL) co->masterck=co->clockpath->NODE;
3245 co->com=com;
3246 com->count++;
3247 ch=delchain(ch, ch);
3248 allobj=addchain(allobj, co);
3249 tot++;
3250 }
3251 cmdlist=cmdlist->NEXT;
3252 }
3253 freeptype(pt);
3254
3255 // directives
3256 for (j=0; j<2; j++)
3257 {
3258 pt=cmdlist=ttv_get_directive_slopes(out_ev, i==0?1:0, j,ttv_IsClock(in_ev->ROOT)?1:0);
3259 while (cmdlist!=NULL)
3260 {
3261 checkcmd=(ttvevent_list *)cmdlist->DATA;
3262 if (j==0)
3263 ch=getcmdpaths_new(tf, checkcmd, i, 0);
3264 else
3265 ch=getcmdpaths_data_new(tf, checkcmd, i);
3266 while (ch!=NULL)
3267 {
3268 co=(ConstraintObject *)mbkalloc(sizeof(ConstraintObject));
3269 co->setup=(i==0?1:0);
3270 co->datapath=tp;
3271 co->clockpath=(ttvpath_list *)ch->DATA;
3272 ttv_get_path_margins(tf, co->datapath, co->clockpath, &margedata, &margeclock, &overlapc, &overlapd,0,0);
3273 co->margedata=_LONG_TO_DOUBLE(margedata);
3274 co->margeclock=_LONG_TO_DOUBLE(margeclock);
3275 co->overlapclock=_LONG_TO_DOUBLE(overlapc);
3276 co->overlapdata=_LONG_TO_DOUBLE(overlapd);
3277 co->intrinsic_margin=_LONG_TO_DOUBLE(pt->TYPE);
3278 co->intrinsic_margin_model=NULL;
3279 ttv_GetGeneratedClockPathsInfo(co->clockpath->NODE, i, &co->clocklatency, &co->masterck);
3280 if (co->masterck==NULL) co->masterck=co->clockpath->NODE;
3281 co->com=com;
3282 com->count++;
3283 ch=delchain(ch, ch);
3284 allobj=addchain(allobj, co);
3285 tot++;
3286 }
3287 cmdlist=cmdlist->NEXT;
3288 }
3289 freeptype(pt);
3290 }
3291 }
3292 }
3293 pth=pth->NEXT;
3294 }
3295 }
3296 }
3297 freechain(latchlist);
3298 ttv_setsearchexclude(old0, old1, &old0, &old1);
3299 return allobj;
3300 }
3301
3302
3303 void ttv_DisplayConnectorToLatchMargin (FILE *f, ttvfig_list *tf, char *inputconnector, char *mode)
3304 {
3305 ttvpath_list *tp;
3306 char buf1[1024], buf3[256], buf4[256];
3307 int i, j, tot, dispall=0, split=0, margins=0, max;
3308 chain_list *cl, *connectorlist;
3309 chain_list *allobj, *allsetup, *allhold;
3310 Board *b;
3311 void *last;
3312 long old0, old1;
3313 char *tok, *c, *saveAUTO, savesimdiffmode=DISPLAY_simdiffmode, doDISPLAY_simdiffmode=0;
3314 char *towhat="latch";
3315 ConstraintObject *co;
3316 BI_ConstraintObject *bicotab;
3317 int filterclock=1, filtercmd=1, dosetup, dohold;
3318 chain_list *allnodes, *allclocks;
3319
3320 if (f==NULL || tf==NULL) return;
3321
3322 if (ftello(f)==0)
3323 ttv_DumpHeader(f, tf);
3324
3325 strcpy(buf1, mode);
3326 tok=strtok_r(buf1, " ", &c);
3327 while (tok!=NULL)
3328 {
3329 if (strcasecmp(tok,"resume")==0 || strcasecmp(tok,"summary")==0) dispall=0;
3330 else if (strcasecmp(tok,"all")==0) dispall=1;
3331 else if (strcasecmp(tok,"split")==0) split=1;
3332 else if (strcasecmp(tok,"margins")==0) margins=1;
3333 else if (strcasecmp(tok,"pathcomp")==0) doDISPLAY_simdiffmode=1;
3334 else if (strcasecmp(tok,"allconstraints")==0) towhat="all", filterclock=2;
3335 else if (strcasecmp(tok,"full")==0) towhat="all", filterclock=0;
3336 else
3337 avt_errmsg(TTV_API_ERRMSG, "041", AVT_ERROR, tok);
3338 tok=strtok_r(NULL, " ", &c);
3339 }
3340
3341 avt_fprintf(f, " *** Connector to Latch report (unit:[%s]) ***\n\n", DISPLAY_time_string);
3342 cfgclock=filterclock;
3343 cfgcmd=filtercmd;
3344 if (split)
3345 {
3346 connectorlist=ttv_GetMatchingSignal(tf, inputconnector, "connector");
3347 for (cl=connectorlist; cl!=NULL; cl=cl->NEXT) cl->DATA=((ttvsig_list *)cl->DATA)->NETNAME;
3348 }
3349 else
3350 connectorlist=addchain(NULL, inputconnector);
3351
3352 saveAUTO=ttv_AutomaticDetailBuild(dispall?"on":"noassoc");
3353 savesimdiffmode=DISPLAY_simdiffmode;
3354 DISPLAY_simdiffmode=doDISPLAY_simdiffmode;
3355
3356 ttv_setsearchexclude(0, 0, &old0, &old1);
3357
3358 while (connectorlist!=NULL)
3359 {
3360 allobj=ttv_GetConstraints(tf, (char *)connectorlist->DATA, towhat);
3361
3362 if (allobj!=NULL)
3363 {
3364
3365 tot=countchain(allobj);
3366 ttv_sort_cotab(allobj, ConstraintObjectSort_for_C2L);
3367
3368 allsetup=allhold=NULL;
3369
3370 for (cl=allobj; cl!=NULL; cl=cl->NEXT)
3371 {
3372 co=(ConstraintObject *)cl->DATA;
3373 if (co->setup) allsetup=addchain(allsetup, co);
3374 else allhold=addchain(allhold, co);
3375 }
3376
3377 allsetup=reverse(allsetup);
3378 allhold=reverse(allhold);
3379
3380 bicotab=(BI_ConstraintObject *)mbkalloc(sizeof(BI_ConstraintObject)*tot);
3381 i=0;
3382 while (allsetup!=NULL || allhold!=NULL)
3383 {
3384 bicotab[i].setup=bicotab[i].hold=NULL;
3385 dosetup=dohold=0;
3386
3387 if (allhold==NULL) dosetup=1;
3388 else if (allsetup==NULL) dohold=1;
3389 else
3390 {
3391 int res;
3392 res=ConstraintObjectSort_for_C2L_cmp((ConstraintObject *)allsetup->DATA, (ConstraintObject *)allhold->DATA, 0, 0, filterclock, filtercmd, 1);
3393 if (res<0) dosetup=1;
3394 else if (res>0) dohold=1;
3395 else dosetup=dohold=1;
3396 }
3397
3398 if (dosetup)
3399 {
3400 co=(ConstraintObject *)allsetup->DATA;
3401 bicotab[i].min=ttv_ComputeConstraintObjectMargin(co);
3402 bicotab[i].setup=co;
3403 allsetup=ttv_getnext_different_ConstraintObject(allsetup, co, filterclock, filtercmd);
3404 }
3405 if (dohold)
3406 {
3407 co=(ConstraintObject *)allhold->DATA;
3408 if (!dosetup || (dosetup && bicotab[i].min>ttv_ComputeConstraintObjectMargin(co)))
3409 bicotab[i].min=ttv_ComputeConstraintObjectMargin(co);
3410 bicotab[i].hold=co;
3411 allhold=ttv_getnext_different_ConstraintObject(allhold, co, filterclock, filtercmd);
3412 }
3413 i++;
3414 }
3415
3416 tot=i;
3417 if (tot>0)
3418 {
3419 qsort(bicotab, i, sizeof(BI_ConstraintObject), BI_ConstraintObjectSort);
3420
3421 b=Board_CreateBoard();
3422
3423 Board_SetSize(b, COL_INDEX, 5, 'r');
3424 Board_SetSize(b, COL_CONNECTOR, 10, 'l');
3425 Board_SetSize(b, COL_CONNECTOR_DIR, 3, 'l');
3426 Board_SetSize(b, COL_LATCH_C2L, 10, 'l');
3427 Board_SetSize(b, COL_LATCH_DIR, 3, 'l');
3428 Board_SetSize(b, COL_SETUP_C2L, 7, DISPLAY_number_justify);
3429 Board_SetSize(b, COL_HOLD_C2L, 7, DISPLAY_number_justify);
3430 Board_SetSize(b, COL_DATAMAX, 7, DISPLAY_number_justify);
3431 Board_SetSize(b, COL_DATAMIN, 7, DISPLAY_number_justify);
3432 Board_SetSize(b, COL_CLOCKMAX, 7, DISPLAY_number_justify);
3433 Board_SetSize(b, COL_CLOCKMIN, 7, DISPLAY_number_justify);
3434
3435 if (margins)
3436 {
3437 Board_SetSize(b, COL_DATAMAX_MARGIN, 5, DISPLAY_number_justify);
3438 Board_SetSize(b, COL_CLOCKMIN_MARGIN, 5, DISPLAY_number_justify);
3439 Board_SetSize(b, COL_DATAMIN_MARGIN, 5, DISPLAY_number_justify);
3440 Board_SetSize(b, COL_CLOCKMAX_MARGIN, 5, DISPLAY_number_justify);
3441 }
3442
3443 Board_SetSep(b, COL_C2L_SEP_CONNECTOR);
3444 Board_SetSep(b, COL_C2L_SEP_LATCH);
3445 Board_SetSep(b, COL_C2L_SEP_SETUPHOLD);
3446
3447 Board_NewLine(b);
3448 Board_SetValue(b, COL_INDEX, "Path");
3449 Board_SetValue(b, COL_CONNECTOR, "Connector");
3450 Board_SetValue(b, COL_LATCH_C2L, "Latch");
3451 sprintf(buf1,"Setup");
3452 Board_SetValue(b, COL_SETUP_C2L, buf1);
3453 Board_SetValue(b, COL_DATAMAX, " DataMax");
3454 Board_SetValue(b, COL_CLOCKMIN, " ClockMin");
3455 sprintf(buf1,"Hold");
3456 Board_SetValue(b, COL_HOLD_C2L, buf1);
3457 Board_SetValue(b, COL_DATAMIN, " DataMin");
3458 Board_SetValue(b, COL_CLOCKMAX, " ClockMax");
3459
3460 if (margins)
3461 {
3462 Board_SetValue(b, COL_DATAMAX_MARGIN, "Margin");
3463 Board_SetValue(b, COL_CLOCKMIN_MARGIN, "Margin");
3464 Board_SetValue(b, COL_DATAMIN_MARGIN, "Margin");
3465 Board_SetValue(b, COL_CLOCKMAX_MARGIN, "Margin");
3466 }
3467
3468 Board_NewSeparation(b);
3469 last=NULL;
3470 for (i=0 ; i<tot ; i++)
3471 {
3472 Board_NewLine(b);
3473 sprintf(buf1,"%d", i+1);
3474 Board_SetValue(b, COL_INDEX, buf1);
3475
3476 co=bicotab[i].setup;
3477 if (co==NULL) co=bicotab[i].hold;
3478
3479 if (last!=co->datapath->NODE)
3480 {
3481 Board_SetValue(b, COL_CONNECTOR, ttv_GetFullSignalName_COND(tf, co->datapath->NODE->ROOT));
3482 last=co->datapath->NODE;
3483 sprintf(buf1, "(%c)", dirconv(ttv_GetTimingEventDirection(co->datapath->NODE)));
3484 Board_SetValue(b, COL_CONNECTOR_DIR, buf1);
3485 }
3486
3487 Board_SetValue(b, COL_LATCH_C2L, ttv_GetFullSignalName_COND(tf, co->datapath->ROOT->ROOT));
3488 sprintf(buf1, "(%c)", dirconv(ttv_GetTimingEventDirection(co->datapath->ROOT)));
3489 Board_SetValue(b, COL_LATCH_DIR, buf1);
3490
3491 if (bicotab[i].setup==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintObjectMargin(bicotab[i].setup)*DISPLAY_time_unit);
3492 Board_SetValue(b, COL_SETUP_C2L, buf1);
3493 if (bicotab[i].hold==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintObjectMargin(bicotab[i].hold)*DISPLAY_time_unit);
3494 Board_SetValue(b, COL_HOLD_C2L, buf1);
3495
3496 if (bicotab[i].setup==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintVALID(bicotab[i].setup)*DISPLAY_time_unit);
3497 Board_SetValue(b, COL_DATAMAX, buf1);
3498 if (bicotab[i].setup==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintREQUIRED(bicotab[i].setup)*DISPLAY_time_unit);
3499 Board_SetValue(b, COL_CLOCKMIN, buf1);
3500 if (bicotab[i].hold==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintVALID(bicotab[i].hold)*DISPLAY_time_unit);
3501 Board_SetValue(b, COL_DATAMIN, buf1);
3502 if (bicotab[i].hold==NULL) strcpy(buf1,"none"); else sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintREQUIRED(bicotab[i].hold)*DISPLAY_time_unit);
3503 Board_SetValue(b, COL_CLOCKMAX, buf1);
3504
3505 if (margins)
3506 {
3507
3508 if (bicotab[i].setup)
3509 {
3510 sprintf(buf1,DISPLAY_time_format,bicotab[i].setup->margedata*DISPLAY_time_unit);
3511 Board_SetValue(b, COL_DATAMAX_MARGIN, buf1);
3512 sprintf(buf1,DISPLAY_time_format,bicotab[i].setup->margeclock*DISPLAY_time_unit);
3513 Board_SetValue(b, COL_CLOCKMIN_MARGIN, buf1);
3514 }
3515 if (bicotab[i].hold)
3516 {
3517 sprintf(buf1,DISPLAY_time_format,bicotab[i].hold->margedata*DISPLAY_time_unit);
3518 Board_SetValue(b, COL_DATAMIN_MARGIN, buf1);
3519 sprintf(buf1,DISPLAY_time_format,bicotab[i].hold->margeclock*DISPLAY_time_unit);
3520 Board_SetValue(b, COL_CLOCKMAX_MARGIN, buf1);
3521 }
3522 }
3523 }
3524
3525 Board_NewSeparation(b);
3526
3527 Board_Display(f, b, "");
3528 fflush(f);
3529
3530 Board_FreeBoard(b);
3531
3532 avt_fprintf(f, "\n\n");
3533
3534 if (dispall==1)
3535 {
3536 long oldmode;
3537 oldmode=detail_forced_mode;
3538
3539 detail_forced_mode=NOSUPINFO_DETAIL|RELATIVE_DETAIL;
3540
3541 for (i=0 ; i<tot ; i++)
3542 {
3543 co=bicotab[i].setup;
3544 if (co==NULL) co=bicotab[i].hold;
3545
3546 if ((co->datapath->ROOT->ROOT->TYPE & TTV_SIG_L)!=0) strcpy(buf1,"LATCH");
3547 else if ((co->datapath->ROOT->ROOT->TYPE & TTV_SIG_R)!=0) strcpy(buf1,"PRECHARGE");
3548 else if ((co->datapath->ROOT->ROOT->TYPE & TTV_SIG_B)!=0) strcpy(buf1,"BREAKPOINT");
3549 else strcpy(buf1,"NODE");
3550
3551 fprintf(f, "Path (%d): FROM CONNECTOR %s(%c) TO %s %s(%c)\n\n", i+1,
3552 ttv_GetFullSignalName_COND(tf, co->datapath->NODE->ROOT),
3553 dirconv(ttv_GetTimingEventDirection(co->datapath->NODE)),
3554 buf1,
3555 ttv_GetFullSignalName_COND(tf, co->datapath->ROOT->ROOT),
3556 dirconv(ttv_GetTimingEventDirection(co->datapath->ROOT))
3557 );
3558
3559 for (j=0; j<2; j++)
3560 {
3561 if (j==0) co=bicotab[i].setup; else co=bicotab[i].hold;
3562
3563 if (co!=NULL)
3564 {
3565 sprintf(buf1,DISPLAY_time_format,ttv_ComputeConstraintObjectMargin(co)*DISPLAY_time_unit);
3566 fprintf(f, " %s of %s\n\n", j==0?"SETUP":"HOLD", buf1);
3567 max=0;
3568 tp=co->datapath;
3569 ttvapi_setprefix(" ");
3570 PATH_MORE_INFO.enabled=1;
3571 if (co->margedata!=0)
3572 PATH_MORE_INFO.add[max].label="[PATH MARGIN]", PATH_MORE_INFO.add[max++].val=co->margedata;
3573 if (co->intrinsic_margin!=0)
3574 PATH_MORE_INFO.add[max].label=(j==0?"[INTRINSIC SETUP]":"[INTRINSIC HOLD]"), PATH_MORE_INFO.add[max++].val=co->intrinsic_margin;
3575 PATH_MORE_INFO.add[max++].label=NULL;
3576
3577 avt_fprintf(f, " DATA PATH:\n");
3578 ttv_DisplayPathDetail(f, -1, tp);
3579
3580 PATH_MORE_INFO.enabled=0;
3581
3582 tp=co->clockpath;
3583 max=0;
3584 PATH_MORE_INFO.enabled=1;
3585 if (co->margeclock!=0)
3586 PATH_MORE_INFO.add[max].label="[PATH MARGIN]", PATH_MORE_INFO.add[max++].val=co->margeclock;
3587 if (co->clocklatency!=0)
3588 {
3589 sprintf(buf3,"[LATENCY FROM %s]", ttv_GetFullSignalNetName(tf, co->masterck->ROOT));
3590 PATH_MORE_INFO.add[max].label=buf3, PATH_MORE_INFO.add[max++].val=co->clocklatency;
3591 }
3592 PATH_MORE_INFO.add[max++].label=NULL;
3593
3594 avt_fprintf(f, " CLOCK PATH:\n");
3595 ttv_DisplayPathDetail(f, -1, tp);
3596
3597 PATH_MORE_INFO.enabled=0;
3598
3599 if (co->overlapdata!=0 || co->overlapclock!=0)
3600 {
3601 sprintf(buf3,DISPLAY_signed_time_format, co->overlapdata*DISPLAY_time_unit);
3602 sprintf(buf4,DISPLAY_signed_time_format, co->overlapclock*DISPLAY_time_unit);
3603 avt_fprintf(f, "%s -> Path Margins overlap: datapath:%s clockpath:%s\n", " ", buf3, buf4);
3604 }
3605
3606 avt_fprintf(f, "\n");
3607
3608 ttvapi_setprefix("");
3609 }
3610 }
3611 }
3612 detail_forced_mode=oldmode;
3613 }
3614 }
3615
3616 mbkfree(bicotab);
3617
3618 while (allobj!=NULL)
3619 {
3620 ttv_FreeConstraintObject_sub((ConstraintObject *)allobj->DATA, 0);
3621 allobj=delchain(allobj, allobj);
3622 }
3623
3624 if (split && connectorlist->NEXT!=NULL)
3625 fprintf(f, "\n");
3626 }
3627 connectorlist=delchain(connectorlist, connectorlist);
3628 }
3629
3630 allnodes=ttv_getsigbytype(tf,NULL,TTV_SIG_TYPEALL,NULL);
3631 cleanpathonsig(allnodes, MINCLOCKPATH_PTYPE);
3632 cleanpathonsig(allnodes, MAXCLOCKPATH_PTYPE);
3633 ttv_FreeConstraintObjectManagement(tf, allnodes);
3634 freechain(allnodes);
3635
3636 ttv_setsearchexclude(old0, old1, &old0, &old1);
3637 ttv_AutomaticDetailBuild(saveAUTO);
3638 DISPLAY_simdiffmode=savesimdiffmode;
3639
3640 }
3641
3642 chain_list *ttv_GetClockPath(ttvpath_list *tp, ttvevent_list **connector, ttvevent_list **pathcmd)
3643 {
3644 chain_list *cl, *list, *ret, *allclocksig, *foundcl;
3645 ttvpath_list *pth;
3646 char dir[5];
3647 ttvsig_list *tvs;
3648 ttvevent_list *tve;
3649 ttvevent_list *revert_tve;
3650 int prech=0, mustbehz=0, breakp=0, fflop=0;
3651 char type;
3652 stbnode *node;
3653 stbck *clock=NULL;
3654 double cur, this=-1;
3655 ptype_list *pt;
3656
3657
3658 *connector=*pathcmd=NULL;
3659 ret=NULL;
3660
3661 if ((tp->ROOT->ROOT->TYPE & TTV_SIG_R)!=0) prech=1;
3662 else if ((tp->ROOT->ROOT->TYPE & TTV_SIG_B)!=0) breakp=1;
3663 else if ((tp->ROOT->ROOT->TYPE & TTV_SIG_LF)==TTV_SIG_LF) fflop=1;
3664 if ((tve=ttv_GetPathCommand(tp))==NULL)
3665 {
3666 if (prech) tve=tp->ROOT;
3667 else if (breakp)
3668 {
3669 if ((pt=getptype(tp->ROOT->USER, STB_BREAK_TEST_EVENT))!=NULL)
3670 tve=(ttvevent_list *)pt->DATA;
3671 }
3672 }
3673
3674 if (tve!=NULL)
3675 {
3676 node=stb_getstbnode(tve);
3677
3678 if (tp->TYPE & TTV_FIND_MAX) type='m'; //min
3679 else type='M'; // max
3680
3681 if (prech)
3682 {
3683 if (!ttv_PathIsHZ(tp))
3684 {
3685 if (node!=NULL && node->CK!=NULL)
3686 {
3687 if ((type=='M' && (node->CK->FLAGS & STBCK_MAX_EDGE_NOT_HZ)!=0)
3688 || (type=='m' && (node->CK->FLAGS & STBCK_MIN_EDGE_NOT_HZ)!=0))
3689 revert_tve=ttv_opposite_event(tve);
3690 else
3691 revert_tve=tve, mustbehz=1;
3692 }
3693 else
3694 revert_tve=tve, mustbehz=1;
3695 }
3696 else
3697 {
3698 if (node!=NULL && node->CK!=NULL)
3699 {
3700 if ((type=='M' && (node->CK->FLAGS & STBCK_MAX_EDGE_HZ)!=0)
3701 || (type=='m' && (node->CK->FLAGS & STBCK_MIN_EDGE_HZ)!=0))
3702 revert_tve=ttv_opposite_event(tve), mustbehz=1;
3703 else
3704 revert_tve=tve;
3705 }
3706 else
3707 revert_tve=tve;
3708 }
3709 }
3710 else if (breakp || fflop)
3711 revert_tve=tve;
3712 else
3713 {
3714 if (type=='M' || !ttv_has_strict_setup(tp->ROOT))
3715 revert_tve=ttv_opposite_event(tve);
3716 else
3717 revert_tve=tve;
3718 }
3719
3720 *pathcmd=tve;
3721 tve=revert_tve;
3722 tvs=tve->ROOT;
3723
3724 node=stb_getstbnode(tve);
3725 allclocksig=NULL;
3726 if (node==NULL || node->CK==NULL || node->CK->ORIGINAL_CLOCK==NULL || mustbehz)
3727 sprintf(dir,"?%c",ttv_GetTimingEventDirection(tve));
3728 else
3729 {
3730 /*if (!prech) revert_tve=ttv_opposite_event(node->CK->ORIGINAL_CLOCK);
3731 else*/ revert_tve=node->CK->ORIGINAL_CLOCK;
3732 sprintf(dir,"%c%c",ttv_GetTimingEventDirection(revert_tve), ttv_GetTimingEventDirection(tve));
3733 allclocksig=addchain(NULL, revert_tve->ROOT);
3734 }
3735
3736 if (node!=NULL)
3737 {
3738 int checkdir;
3739 if ((tve->TYPE & TTV_NODE_UP)==TTV_NODE_UP) checkdir=1;
3740 else checkdir=0;
3741 if ((checkdir==0 && (node->CK->FLAGS & STBCK_FAKE_DOWN)!=0)
3742 || (checkdir==1 && (node->CK->FLAGS & STBCK_FAKE_UP)!=0))
3743 return NULL;
3744 }
3745 // if (!prech)
3746 /* else
3747 strcpy(dir,"??");*/
3748
3749 if (!allclocksig) allclocksig=ttv_getclocksiglist(tp->FIG);
3750 ttv_search_mode(1, TTV_MORE_OPTIONS_MUST_BE_CLOCK|TTV_MORE_OPTIONS_USE_CLOCK_START);
3751
3752 if (allclocksig!=NULL)
3753 {
3754 cl=addchain(NULL, tvs);
3755 list=ttv_internal_GetPaths_EXPLICIT(tp->FIG, NULL, allclocksig, cl, dir, -1, "critic", "path", type=='M'?"max":"min");
3756 /*
3757 if (type=='M') list=ttv_internal_GetCriticPath(NULL, tvs, dir, -1, 1);
3758 else list=ttv_internal_GetCriticPath(NULL, tvs, dir, -1, 0);
3759 */
3760
3761 freechain(cl);
3762 freechain(allclocksig);
3763 }
3764 else
3765 list=NULL;
3766 ttv_search_mode(0, TTV_MORE_OPTIONS_MUST_BE_CLOCK|TTV_MORE_OPTIONS_USE_CLOCK_START);
3767
3768 cl=list;
3769 foundcl=NULL;
3770 while (cl!=NULL)
3771 {
3772 pth=(ttvpath_list *)cl->DATA;
3773 tvs=ttv_GetPathStartSignal(pth);
3774 if (isclock(tvs))
3775 {
3776 if (!prech) break;
3777 if (!mustbehz && !ttv_PathIsHZ(pth)) break;
3778 if (mustbehz && ttv_PathIsHZ(pth))
3779 {
3780 // to comply with stb hz path in stb_initcmd
3781 cur=ttv_GetPathStartTime(pth)+ttv_GetPathDelay(pth);
3782 if (this==-1 || (type=='M' && cur>this) || (type=='m' && cur<this))
3783 {
3784 this=cur;
3785 foundcl=cl;
3786 }
3787 // break;
3788 }
3789 }
3790 cl=cl->NEXT;
3791 }
3792 if (foundcl!=NULL) cl=foundcl;
3793 if (cl!=NULL)
3794 {
3795 ret=addchain(ret, cl->DATA);
3796 cl->DATA=NULL;
3797 }
3798 else
3799 {
3800 if (list==NULL && (tve->ROOT->TYPE & TTV_SIG_C)!=0 && isclock(tve->ROOT))
3801 {
3802 *connector=tve;
3803 }
3804 }
3805
3806 ttv_FreePathList(list);
3807 freechain(list);
3808 }
3809 return ret;
3810 }
3811
3812 static ptype_list *fitdouble(double val)
3813 {
3814 ptype_list *pt;
3815 pt=addptype(NULL, TYPE_DOUBLE, NULL);
3816 *(float *)&pt->DATA=(float)val;
3817 return pt;
3818 }
3819
3820 Property *ttv_GetTimingConstraintProperty (ConstraintObject *co, char *property)
3821 {
3822 char buf[256];
3823
3824 if (!co) {
3825 sprintf (buf, "error_null_timing_constraint");
3826 return addptype (NULL, TYPE_CHAR, strdup (buf));
3827 }
3828
3829 if (!strcasecmp (property, "CLOCK_PATH")) {
3830 return addptype (NULL, TYPE_TIMING_PATH, co->clockpath);
3831 }
3832
3833 if (!strcasecmp (property, "DATA_PATH")) {
3834 return addptype (NULL, TYPE_TIMING_PATH, co->datapath);
3835 }
3836
3837 if (!strcasecmp (property, "INTRINSIC_MARGIN")) {
3838 return fitdouble(co->intrinsic_margin);
3839 }
3840
3841 if (!strcasecmp (property, "INTRINSIC_MARGIN_MODEL")) {
3842 return addptype (NULL, TYPE_CHAR, strdup(co->intrinsic_margin_model?co->intrinsic_margin_model:"NULL"));
3843 }
3844
3845 if (!strcasecmp (property, "TYPE")) {
3846 return addptype (NULL, TYPE_CHAR, strdup(co->setup?"setup":"hold"));
3847 }
3848
3849 if (!strcasecmp (property, "CLOCK_PATH_MARGIN")) {
3850 return fitdouble(co->margeclock);
3851 }
3852
3853 if (!strcasecmp (property, "DATA_PATH_MARGIN")) {
3854 return fitdouble(co->margedata);
3855 }
3856
3857 if (!strcasecmp (property, "MASTER_CLOCK")) {
3858 return addptype (NULL, TYPE_TIMING_EVENT, co->masterck);
3859 }
3860
3861 if (!strcasecmp (property, "MASTER_CLOCK_LATENCY")) {
3862 return fitdouble(co->clocklatency);
3863 }
3864
3865 if (!strcasecmp (property, "VALUE")) {
3866 return fitdouble(ttv_ComputeConstraintObjectMargin(co));
3867 }
3868
3869 avt_errmsg(TTV_API_ERRMSG, "043", AVT_ERROR, property);
3870 return addptype (NULL, TYPE_CHAR, strdup ("error_unknown_property"));
3871 //fprintf (stderr, "error: unknown property %s\n", property);
3872 // return NULL;
3873 }
3874
3875 typedef struct wave {
3876 struct wave *NEXT;
3877 char *NAME;
3878 double TIME;
3879 double SLOPE;
3880 double VT;
3881 double SWING;
3882 double GROUND;
3883 char SENSE;
3884 } wave;
3885
3886 double slope_convert(double F, double vdd, double vt, char sense, double vth_low, double vth_high)
3887 {
3888 double v0, v1, x0, x1;
3889
3890 v0 = vth_low * vdd;
3891 v1 = vth_high * vdd;
3892
3893 if (sense == 'R') {
3894 if (v0 >= vt) {
3895 x0 = atanh((v0-vt)/(vdd-vt));
3896 x1 = atanh((v1-vt)/(vdd-vt));
3897 }
3898 else if (v1 >= vt) {
3899 x0 = (v0-vt)/(vdd-vt);
3900 x1 = atanh((v1-vt)/(vdd-vt));
3901 }
3902 else {
3903 x0 = (v0-vt)/(vdd-vt);
3904 x1 = (v1-vt)/(vdd-vt);
3905 }
3906 return (F/(x1-x0));
3907 }
3908 else {
3909 if (v1 < vdd-vt) {
3910 x1 = atanh((v1-(vdd-vt))/(-(vdd-vt)));
3911 x0 = atanh((v0-(vdd-vt))/(-(vdd-vt)));
3912 }
3913 else if (v0 < vdd-vt) {
3914 x1 = (v1-(vdd-vt))/(-(vdd-vt));
3915 x0 = atanh((v0-(vdd-vt))/(-(vdd-vt)));
3916 }
3917 else {
3918 x1 = (v1-(vdd-vt))/(-(vdd-vt));
3919 x0 = (v0-(vdd-vt))/(-(vdd-vt));
3920 }
3921 return (F/(x0-x1));
3922 }
3923 }
3924
3925 double hitas_tanh(double t, double F, double vdd, double vt, char sense)
3926 {
3927 double t0;
3928 double direction, threshold, initial;
3929
3930 if (sense == 'F') {
3931 direction = -1;
3932 threshold = vdd-vt;
3933 initial = vdd;
3934 }
3935 else {
3936 direction = 1;
3937 threshold = vt;
3938 initial = 0;
3939 }
3940
3941 t0 = F*vt/(vdd-vt);
3942
3943 if (t <= 0) return initial;
3944 else if (t <= t0) return (threshold + (direction)*(vdd-vt)*((t-t0)/F));
3945 else return (threshold + (direction)*(vdd-vt)*tanh((t-t0)/F));
3946 }
3947
3948 double get_threshold_time(double F, double vdd, double vt)
3949 {
3950 if (vt >= vdd/2) return (F*vdd/(2*(vdd-vt)));
3951 else return ((F*vt)/(vdd-vt) + F * atanh((vdd-2*vt)/(2*(vdd-vt))));
3952 }
3953
3954 void ttv_PlotCompletePathDetail(FILE *f, ttvpath_list *tp, chain_list *detailchain)
3955 {
3956 chain_list *ptchain;
3957 ttvcritic_list *detail, *nextdetail;
3958 timing_model *model, *nextmodel;
3959 ttvsig_list *startsig;
3960 wave *ptwave, *headwave = NULL;
3961 double maxdelay, transient_time, time_step, startlag, timeshift, simtime;
3962 float low, high;
3963
3964 startsig = tp->NODE->ROOT;
3965 for (ptchain = detailchain; ptchain; ptchain = ptchain->NEXT) {
3966 detail = (ttvcritic_list *)ptchain->DATA;
3967 if (detail->LINEMODELNAME) {
3968 model = stm_getmodel(detail->MODNAME, detail->LINEMODELNAME);
3969 }
3970 else model = NULL;
3971 nextmodel = NULL;
3972 if (ptchain->NEXT) {
3973 nextdetail = (ttvcritic_list *)ptchain->NEXT->DATA;
3974 if (nextdetail->LINEMODELNAME) {
3975 nextmodel = stm_getmodel(nextdetail->MODNAME, nextdetail->LINEMODELNAME);
3976 }
3977 }
3978 ptwave = malloc(sizeof(wave));
3979 ptwave->NEXT = headwave;
3980 ptwave->NAME = detail->NAME;
3981 ptwave->TIME = ((detail->DELAY + detail->DATADELAY)*1e-12/TTV_UNIT);
3982 if (headwave) ptwave->TIME += headwave->TIME;
3983 ptwave->SLOPE = detail->SLOPE*1e-12/TTV_UNIT;
3984 ptwave->GROUND = 0;
3985 if (model) ptwave->SWING = model->VDD;
3986 else {
3987 ptwave->SWING = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
3988 if (ptchain == detailchain) {
3989 if (ttv_get_signal_swing(tp->FIG, startsig, &low, &high) == 0) {
3990 ptwave->SWING = high - low;
3991 ptwave->GROUND = low;
3992 }
3993 }
3994 }
3995 if (nextmodel) ptwave->VT = nextmodel->VT;
3996 else ptwave->VT = STM_DEFAULT_VT;
3997 ptwave->SENSE = (detail->SNODE == TTV_UP)?'R':'F';
3998 ptwave->SLOPE = slope_convert(ptwave->SLOPE, ptwave->SWING, ptwave->VT, ptwave->SENSE, SIM_VTH_LOW, SIM_VTH_HIGH);
3999 headwave = ptwave;
4000 }
4001
4002 maxdelay = 2*headwave->TIME;
4003 headwave = (wave *)reverse((chain_list *)headwave);
4004 startlag = get_threshold_time(headwave->SLOPE, headwave->SWING, headwave->VT);
4005 maxdelay += startlag;
4006 if (maxdelay > V_FLOAT_TAB[__SIM_TIME].VALUE) transient_time = maxdelay;
4007 else transient_time = V_FLOAT_TAB[__SIM_TIME].VALUE;
4008 time_step = V_FLOAT_TAB[__SIM_TRAN_STEP].VALUE;
4009
4010
4011
4012 fputs("#TIME ", f);
4013 for (ptwave = headwave; ptwave; ptwave = ptwave->NEXT) {
4014 fputs(" ", f);
4015 fputs(ptwave->NAME, f);
4016 }
4017 fputs("\n", f);
4018 for (simtime = 0; simtime < transient_time + time_step; simtime += time_step) {
4019 fprintf(f, "% .5e", simtime);
4020 for (ptwave = headwave; ptwave; ptwave = ptwave->NEXT) {
4021 timeshift = startlag + ptwave->TIME - get_threshold_time(ptwave->SLOPE, ptwave->SWING, ptwave->VT);
4022 fprintf(f, " %- .5e", hitas_tanh(simtime-timeshift, ptwave->SLOPE, ptwave->SWING, ptwave->VT, ptwave->SENSE) + ptwave->GROUND);
4023 }
4024 fputs("\n", f);
4025 }
4026 }
4027
4028 void ttv_PlotPathDetail(FILE *f, ttvpath_list *tp)
4029 {
4030 chain_list *detail;
4031
4032 if (tp==NULL) return;
4033
4034 detail=ttv_GetPathDetail(tp);
4035 if (detail==NULL) return;
4036
4037 ttv_PlotCompletePathDetail(f, tp, detail);
4038
4039 ttv_FreePathDetail(detail);
4040 freechain(detail);
4041 }
4042
4043 void ttv_ChangePathStartTime(ttvpath_list *tp, double time)
4044 {
4045 tp->DELAYSTART=_DOUBLE_TO_LONG(time);
4046 if (tp->CRITIC)
4047 {
4048 tp->CRITIC->DELAY=tp->CRITIC->REFDELAY=tp->DELAYSTART;
4049 if (tp->CRITIC->SIMDELAY!=TTV_NOTIME) tp->CRITIC->SIMDELAY=tp->DELAYSTART;
4050 }
4051 }