Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stb / stb_parse.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : STB Version 1.00 */
6 /* Fichier : stb_parse.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Karim DIOURY */
12 /* Anthony LESTER */
13 /* 03082004 : Antony PINTO */
14 /* several functions moved from stb.yac */
15 /* */
16 /****************************************************************************/
17
18 #include STB_H
19
20 #include "stb_init.h"
21 #include "stb_util.h"
22 #include "stb_error.h"
23 #include "stb_parse.h"
24 #include "stb_fromx.h"
25 #include <sys/wait.h>
26
27 #define STB_P_MEM 5 // node memory
28 #define STB_P_NOD 6 // node
29 #define STB_P_ONOD 7 // output node
30 #define STB_P_INOD 8 // input node
31 #define STB_P_LOC 9 // locon
32 #define STB_P_ILOCD 10 // input default locon
33 #define STB_P_OLOCD 11 // output define locon
34
35 #define STB_P_DUPPAIR 1
36 #define STB_P_ADDPAIR 2
37
38 #define BEGIN //printf("%s\n",__func__);
39
40 extern int stbparse();
41 extern void stbrestart();
42 extern void stb_parse_init_stab(stb_parse *stab);
43
44 extern FILE *stbin;
45 int yylineno;
46 static stb_parse *STAB;
47
48 /****************************************************************************/
49 /*{{{ */
50 /* */
51 /* */
52 /****************************************************************************/
53 static void
54 stb_yyclean()
55 {
56 if (STAB->PTINSCHAIN != NULL) {
57 freechain(STAB->PTINSCHAIN);
58 STAB->PTINSCHAIN = NULL;
59 }
60 if (STAB->PTSTABLELIST != NULL) {
61 freechain(STAB->PTSTABLELIST);
62 STAB->PTSTABLELIST = NULL;
63 }
64 if (STAB->PTUNSTABLELIST != NULL) {
65 freechain(STAB->PTUNSTABLELIST);
66 STAB->PTUNSTABLELIST = NULL;
67 }
68 if (STAB->PARSEDFIG != NULL) {
69 stb_delstbfig(STAB->PARSEDFIG);
70 STAB->PARSEDFIG = NULL;
71 }
72 }
73
74 void
75 stb_parse_init_stab(stb_parse *stab)
76 {
77 STAB = stab;
78 stb_parse_init(STAB,stb_yyclean);
79 }
80
81 stb_parse *
82 stb_convert_inf_to_stb_1(stbfig_list *ptstbfig)
83 {
84 stb_fromX_t fxt;
85 static stb_parse stab = {
86 NULL, // parsedfig
87 NULL, // ptinschain
88 NULL, // ptstablelist
89 NULL, // ptunstablelist
90 NULL, // ckdomains
91 NULL, // ckeqvt
92 0, // defaultphase
93 0, // domainindex
94 0, // eqvtindex
95 0, // inverted
96 0, // ideal
97 0, // virtual
98 NULL // cleanfunc
99 };
100 fxt.STBFIG = ptstbfig;
101 fxt.UNIT = 1e-12;
102
103
104 stb_parse_init_stab(&stab);
105 stb_fromX_STEP1_traditional(&fxt, &stab);
106
107 return &stab;
108
109 }
110
111 int
112 stb_convert_inf_to_stb_2(stbfig_list *ptstbfig, stb_parse *stab)
113 {
114 stb_fromX_t fxt;
115 fxt.STBFIG = ptstbfig;
116 fxt.UNIT = 1e-12;
117
118
119 stb_fromX_STEP2_stability(&fxt, stab);
120 stb_fromX_STEP3_finish(&fxt, stab);
121
122 return 0;
123
124 }
125
126 int
127 stb_loadstbfig(stbfig_list *ptstbfig)
128 {
129 pid_t pid;
130 int status;
131 char str[1024];
132 int j;
133 stb_fromX_t fxt;
134 static stb_parse stab = {
135 NULL, // parsedfig
136 NULL, // ptinschain
137 NULL, // ptstablelist
138 NULL, // ptunstablelist
139 NULL, // ckdomains
140 NULL, // ckeqvt
141 0, // defaultphase
142 0, // domainindex
143 0, // eqvtindex
144 0, // inverted
145 0, // ideal
146 0, // virtual
147 NULL // cleanfunc
148 };
149
150
151 if (STB_FILE_FORMAT == STB_SDC_FORMAT) {
152 if (STB_FOREIGN_CONSTRAINT_FILE == NULL) {
153 strcpy (str, ptstbfig->FIG->INFO->FIGNAME);
154 strcat (str, ".sdc");
155 STB_FOREIGN_CONSTRAINT_FILE = namealloc (str);
156 }
157
158 pid = vfork ();
159
160 if (pid == (pid_t) (-1))
161 stb_error (ERR_CANNOT_RUN, "sdc2stb", 0, STB_FATAL);
162
163 else if (pid == 0) {
164 if (execlp ("sdc2stb", "sdc2stb", STB_FOREIGN_CONSTRAINT_FILE, "-tu", STB_FOREIGN_TIME_UNIT, "-out", ptstbfig->FIG->INFO->FIGNAME, NULL)==-1)
165 {
166 perror("system says ");
167 EXIT(1);
168 }
169 }
170 else {
171 j = mbkwaitpid (pid, 1, &status);
172 if ((j == 0) || (WIFEXITED (status) == 0))
173 fprintf (stderr, "cannot execute sdc2stb\n");
174 else if (WEXITSTATUS (status) != 0)
175 fprintf (stderr, "sdc2stb exit with a non zero value\n");
176 else
177 {
178 inf_DisplayLoad(1);
179 inf_Dirty(ptstbfig->FIG->INFO->FIGNAME);
180 getinffig(ptstbfig->FIG->INFO->FIGNAME);
181 inf_DisplayLoad(0);
182 }
183 }
184 }
185
186 /*
187 if ((stbin = mbkfopen(ptstbfig->FIG->INFO->FIGNAME, "stb", READ_TEXT)) == NULL) {
188 stb_error(ERR_CANNOT_OPEN, NULL, 0, STB_FATAL);
189 }
190 */
191 /*
192 if(vierge == 0)
193 stbrestart(stbin) ;
194 vierge = 0 ;
195
196 yylineno = 1;
197 */
198 fxt.STBFIG = ptstbfig;
199 fxt.UNIT = 1e-12;
200
201
202 stb_parse_init_stab(&stab);
203 stb_fromX(&fxt,&stab);
204 // stbparse();
205
206 /*
207 if (fclose(stbin)) {
208 stb_error(ERR_CANNOT_CLOSE, NULL, 0, STB_FATAL);
209 }
210 */
211
212 return 0;
213 }
214
215 /*}}}************************************************************************/
216 /****************************************************************************/
217 /*{{{ Parse struct */
218 /****************************************************************************/
219 /*{{{ stb_parse_init(); */
220 /* */
221 /* */
222 /****************************************************************************/
223 void
224 stb_parse_init(stb_parse *stab, void (*cleanfunc)(void))
225 {BEGIN
226 stab->PARSEDFIG = NULL;
227 stab->PTINSCHAIN = NULL;
228 stab->PTSTABLELIST = NULL;
229 stab->PTUNSTABLELIST = NULL;
230 stab->CKDOMAINS = NULL;
231 stab->CKEQVT = NULL;
232 stab->DEFAULTPHASE = STB_NO_INDEX;
233 stab->DOMAININDEX = 0;
234 stab->EQVTINDEX = 0;
235 stab->INVERTED = 0;
236 stab->IDEAL = 0;
237 stab->VIRTUAL = 0;
238 stab->CLEANFUNC = cleanfunc;
239 }
240
241 /*}}}************************************************************************/
242 /*}}}************************************************************************/
243 /*{{{ Parse Clock */
244 /****************************************************************************/
245 /*{{{ addstbck() */
246 /* */
247 /* */
248 /****************************************************************************/
249 static inline void
250 addstbck(stbnode *ptstbnode, stb_parse_pulse *pulse, stbfig_list *parsedfig)
251 {
252 stb_addstbck(ptstbnode,
253 pulse->supmin, pulse->supmax,
254 pulse->sdnmin, pulse->sdnmax,
255 pulse->period,
256 parsedfig->SETUP, parsedfig->HOLD,
257 STB_NO_INDEX, 0, STB_NO_VERIF, STB_TYPE_CLOCK, ptstbnode->EVENT);
258
259 }
260
261 /*}}}************************************************************************/
262 /*{{{ stb_parse_cklocon() */
263 /* */
264 /* */
265 /****************************************************************************/
266
267 static chain_list *clocksigpriority(chain_list *cl)
268 {
269 chain_list *ch=NULL, *runcl;
270 ttvsig_list *tvs;
271 long go[4]={TTV_SIG_B, TTV_SIG_L, TTV_SIG_C, 0};
272 int i;
273
274 for (i=0; i<4; i++)
275 {
276 for (runcl=cl; runcl!=NULL; runcl=runcl->NEXT)
277 {
278 tvs=(ttvsig_list *)runcl->DATA;
279 if (tvs!=NULL && (go[i]==0 || (tvs->TYPE & go[i])!=0))
280 {
281 ch=addchain(ch, tvs);
282 runcl->DATA=NULL;
283 }
284 }
285 }
286 freechain(cl);
287 return ch;
288 }
289
290 static long stb_findlatency(inffig_list *ifl, stb_parse *stab, ttvsig_list *ptttvsig, char *type, int *found)
291 {
292 chain_list *list, *chainx, *cl;
293 double val=0;
294 int res=0;
295 // clock
296 list = inf_GetEntriesByType(ifl,type,INF_ANY_VALUES);
297 for (chainx = list; chainx && res==0; chainx = delchain(chainx,chainx))
298 {
299 cl=addchain(NULL, (char *)chainx->DATA);
300 res=ttv_testnetnamemask(stab->PARSEDFIG->FIG, ptttvsig, cl);
301 if (res)
302 {
303 inf_GetDouble(ifl, (char *)chainx->DATA, type, &val);
304 *found=1;
305 }
306 freechain(cl);
307 }
308 return val*1e12*TTV_UNIT;
309 }
310
311 void
312 stb_parse_cklocon(stb_parse *stab, char *ident, stb_parse_pulse *pulse, inffig_list *ifl)
313 {BEGIN
314 ttvsig_list *ptttvsig;
315 chain_list *ptchain;
316 chain_list *headlist, *cl;
317 char *name;
318 long period, swap;
319 int found = FALSE;
320 stb_propagated_clock_to_clock *spctc;
321
322 name = namealloc(ident);
323 if (pulse->supmin==STB_NO_TIME || pulse->sdnmin==STB_NO_TIME)
324 avt_errmsg(STB_ERRMSG, "044", AVT_FATAL, name);
325
326 headlist = ttv_getsigbytype(stab->PARSEDFIG->FIG, NULL,
327 TTV_SIG_C|TTV_SIG_B|TTV_SIG_L/*|TTV_SIG_Q*/, NULL);
328
329 headlist=clocksigpriority(headlist);
330
331 cl=addchain(NULL, name);
332 for (ptchain = headlist; ptchain; ptchain = ptchain->NEXT)
333 {
334 ptttvsig = (ttvsig_list *)ptchain->DATA;
335 if (ttv_testnetnamemask(stab->PARSEDFIG->FIG, ptttvsig, cl))
336 {
337 ttvevent_list *ptevent;
338 stbnode *ptstbnode;
339
340 if (stab->INVERTED)
341 {
342 ptttvsig->USER = addptype (ptttvsig->USER, STB_INVERTED_CLOCK, 0);
343 swap=pulse->supmin, pulse->supmin=pulse->sdnmin, pulse->sdnmin=swap;
344 swap=pulse->supmax, pulse->supmax=pulse->sdnmax, pulse->sdnmax=swap;
345 }
346 if (stab->IDEAL)
347 ptttvsig->USER = addptype (ptttvsig->USER, STB_IDEAL_CLOCK, 0);
348
349 period = pulse->period;
350 stab->PARSEDFIG->CLOCK = addchain(stab->PARSEDFIG->CLOCK, ptttvsig);
351
352 ptevent = ptttvsig->NODE;
353 ptstbnode = stb_getstbnode(ptevent);
354 addstbck(ptstbnode,pulse,stab->PARSEDFIG);
355
356 ptevent = ptttvsig->NODE+1;
357 ptstbnode = stb_getstbnode(ptevent);
358 addstbck(ptstbnode,pulse,stab->PARSEDFIG);
359
360 spctc=(stb_propagated_clock_to_clock *)mbkalloc(sizeof(stb_propagated_clock_to_clock));
361 spctc->edges=pulse->master_edges;
362 spctc->master=pulse->master_clock;
363 memcpy(&spctc->original_waveform, ptstbnode->CK, sizeof(stbck));
364 spctc->haslatency=0;
365 spctc->latencies.SUPMIN=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_RISE_MIN,&spctc->haslatency);
366 spctc->latencies.SUPMAX=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_RISE_MAX,&spctc->haslatency);
367 spctc->latencies.SDNMIN=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_FALL_MIN,&spctc->haslatency);
368 spctc->latencies.SDNMAX=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_FALL_MAX,&spctc->haslatency);
369 if (stab->INVERTED)
370 {
371 swap=spctc->latencies.SUPMIN; spctc->latencies.SUPMIN=spctc->latencies.SDNMIN; spctc->latencies.SDNMIN=swap;
372 swap=spctc->latencies.SUPMAX; spctc->latencies.SUPMAX=spctc->latencies.SDNMAX; spctc->latencies.SDNMAX=swap;
373 }
374 ptstbnode->CK->SUPMIN+=spctc->latencies.SUPMIN; ptstbnode->CK->SUPMAX+=spctc->latencies.SUPMAX;
375 ptstbnode->CK->SDNMIN+=spctc->latencies.SDNMIN; ptstbnode->CK->SDNMAX+=spctc->latencies.SDNMAX;
376 ptttvsig->USER = addptype (ptttvsig->USER, STB_IS_CLOCK, spctc);
377
378 found = TRUE;
379
380 if (!mbk_isregex_name(name))
381 break;
382 }
383 }
384 freechain(cl);
385 freechain(headlist);
386
387 if (found == FALSE)
388 {
389 if (stab->VIRTUAL)
390 {
391 ttvevent_list *ptevent;
392 stbnode *ptstbnode;
393 ptttvsig = (ttvsig_list *)mbkalloc(sizeof(ttvsig_list));
394 ttv_init_refsig(stab->PARSEDFIG->FIG, ptttvsig, ident, ident, 0, TTV_SIG_C);
395 stb_addstbnode (ptttvsig->NODE);
396 stb_addstbnode (ptttvsig->NODE+1);
397
398 ptttvsig->USER = addptype (ptttvsig->USER, STB_VIRTUAL_CLOCK, 0);
399
400 if (stab->INVERTED)
401 {
402 ptttvsig->USER = addptype (ptttvsig->USER, STB_INVERTED_CLOCK, 0);
403 swap=pulse->supmin, pulse->supmin=pulse->sdnmin, pulse->sdnmin=swap;
404 swap=pulse->supmax, pulse->supmax=pulse->sdnmax, pulse->sdnmax=swap;
405 }
406 if (stab->IDEAL)
407 ptttvsig->USER = addptype (ptttvsig->USER, STB_IDEAL_CLOCK, 0);
408
409 period = pulse->period;
410 stab->PARSEDFIG->CLOCK = addchain(stab->PARSEDFIG->CLOCK, ptttvsig);
411
412 ptevent = ptttvsig->NODE;
413 ptstbnode = stb_getstbnode(ptevent);
414 addstbck(ptstbnode,pulse,stab->PARSEDFIG);
415
416 ptevent = ptttvsig->NODE+1;
417 ptstbnode = stb_getstbnode(ptevent);
418 addstbck(ptstbnode,pulse,stab->PARSEDFIG);
419
420 spctc=(stb_propagated_clock_to_clock *)mbkalloc(sizeof(stb_propagated_clock_to_clock));
421 spctc->edges=pulse->master_edges;
422 spctc->master=pulse->master_clock;
423 memcpy(&spctc->original_waveform, ptstbnode->CK, sizeof(stbck));
424 spctc->haslatency=0;
425 spctc->latencies.SUPMIN=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_RISE_MIN,&spctc->haslatency);
426 spctc->latencies.SUPMAX=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_RISE_MAX,&spctc->haslatency);
427 spctc->latencies.SDNMIN=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_FALL_MIN,&spctc->haslatency);
428 spctc->latencies.SDNMAX=stb_findlatency(ifl,stab, ptttvsig, INF_LATENCY_FALL_MAX,&spctc->haslatency);
429 if (stab->INVERTED)
430 {
431 swap=spctc->latencies.SUPMIN; spctc->latencies.SUPMIN=spctc->latencies.SDNMIN; spctc->latencies.SDNMIN=swap;
432 swap=spctc->latencies.SUPMAX; spctc->latencies.SUPMAX=spctc->latencies.SDNMAX; spctc->latencies.SDNMAX=swap;
433 }
434 ptstbnode->CK->SUPMIN+=spctc->latencies.SUPMIN; ptstbnode->CK->SUPMAX+=spctc->latencies.SUPMAX;
435 ptstbnode->CK->SDNMIN+=spctc->latencies.SDNMIN; ptstbnode->CK->SDNMAX+=spctc->latencies.SDNMAX;
436 ptttvsig->USER = addptype (ptttvsig->USER, STB_IS_CLOCK, spctc);
437
438 found = TRUE;
439 }
440
441 if (found == FALSE)
442 {
443 stab->CLEANFUNC();
444 stb_error(ERR_NO_CLOCK_CONNECTOR, name, yylineno, STB_FATAL);
445 }
446 }
447
448 stab->INVERTED = 0;
449 stab->IDEAL = 0;
450 }
451
452 /*}}}************************************************************************/
453 /*{{{ stb_parse_ckdeclar() */
454 /* */
455 /* */
456 /****************************************************************************/
457 static inline char edge(char org)
458 {
459 switch (org)
460 {
461 case INF_STB_RISING : return STB_SLOPE_UP;
462 case INF_STB_FALLING : return STB_SLOPE_DN;
463 case INF_STB_SLOPEALL : return STB_SLOPE_ALL;
464 default : printf("0) Ca va pas non!!\n"); return 0;
465 }
466 }
467
468 static void
469 treatpin_mark(stb_fromX_t *fxt, char *name, char *type)
470 {
471 inf_stb_p_s *ipss;
472 inffig_list *inf;
473 ttvevent_list *tve;
474
475 inf = fxt->INFFIG;
476 if (inf_GetPointer(inf,name,type,(void **)&ipss))
477 {
478 while (ipss!=NULL)
479 {
480 if (ipss->CKNAME!=NULL)
481 {
482 if ((tve=stb_getclockevent(fxt->STBFIG, ipss->CKNAME, edge(ipss->CKEDGE)))!=NULL)
483 {
484 long flag=STB_SLOPE_DN;
485 if ((tve->TYPE & TTV_NODE_UP)==TTV_NODE_UP) flag=STB_SLOPE_UP;
486 stb_getstbnode (tve->ROOT->NODE)->CK->ACTIVE |= flag;
487 stb_getstbnode (tve->ROOT->NODE + 1)->CK->ACTIVE |= flag;
488 }
489 }
490 ipss=ipss->NEXT;
491 }
492 }
493 }
494
495
496 static int stb_ismultiple(long val0, long val1)
497 {
498 if (val0<val1) return (val1 % val0)==0;
499 return (val0 % val1)==0;
500 }
501
502 void
503 stb_parse_ckdeclar(void *fxt0, stb_parse *stab)
504 {BEGIN
505 ttvsig_list *ptttvsig;
506 chain_list *ptchain, *ptchain1, *list;
507 chain_list *foundchain = NULL;
508 stbck *ptstbck;
509 long period;
510 char namebuf[1024];
511 stb_fromX_t *fxt=(stb_fromX_t *)fxt0;
512 stab->DOMAININDEX ++;
513 for (ptchain = stab->PARSEDFIG->CLOCK; ptchain; ptchain = ptchain->NEXT)
514 {
515 ptttvsig = (ttvsig_list *)ptchain->DATA;
516 if (getptype(ptttvsig->USER, STB_DOMAIN) == NULL)
517 {
518 foundchain = addchain(foundchain, ptttvsig);
519 ptttvsig->USER = addptype(ptttvsig->USER, STB_DOMAIN,
520 (void *)((long)stab->DOMAININDEX));
521 }
522 ptstbck = stb_getstbnode(ptttvsig->NODE)->CK;
523 if (ptstbck->PERIOD == STB_NO_TIME)
524 {
525 if (stab->PARSEDFIG->CLOCKPERIOD == STB_NO_TIME)
526 {
527 stab->CLEANFUNC();
528 stb_error(ERR_UNDEFINED_PERIOD,
529 ttv_getsigname(stab->PARSEDFIG->FIG, namebuf, ptttvsig),
530 0, STB_FATAL);
531 }
532 ptstbck->PERIOD = stab->PARSEDFIG->CLOCKPERIOD;
533 ptstbck = stb_getstbnode(ptttvsig->NODE+1)->CK;
534 ptstbck->PERIOD = stab->PARSEDFIG->CLOCKPERIOD;
535 }
536 }
537 if (foundchain != NULL)
538 {
539 stab->CKDOMAINS = addchain(stab->CKDOMAINS, foundchain);
540 stab->PARSEDFIG->CKDOMAIN = stb_addstbdomain(stab->PARSEDFIG->CKDOMAIN,
541 STB_NO_INDEX, STB_NO_INDEX);
542 }
543 stab->PARSEDFIG->USER = addptype(stab->PARSEDFIG->USER, STB_DOMAIN,
544 stab->CKDOMAINS);
545
546 /* verify that domains have equivalent periods */
547 for (ptchain = stab->CKDOMAINS; ptchain; ptchain = ptchain->NEXT)
548 {
549 period = STB_NO_TIME;
550 for (ptchain1 = (chain_list *)ptchain->DATA;
551 ptchain1;
552 ptchain1 = ptchain1->NEXT)
553 {
554 ptttvsig = (ttvsig_list *)ptchain1->DATA;
555 ptstbck = stb_getstbnode(ptttvsig->NODE)->CK;
556 if (period == STB_NO_TIME)
557 period = ptstbck->PERIOD;
558 else if (!stb_ismultiple(ptstbck->PERIOD,period))
559 {
560 stb_error( ERR_INCOHERENT_PERIOD,
561 stab->PARSEDFIG ?
562 ttv_getsigname(stab->PARSEDFIG->FIG, namebuf, ptttvsig) :
563 "-null-",
564 0,
565 STB_FATAL);
566 stab->CLEANFUNC();
567 }
568 }
569 }
570
571 // marquage pour les phases des inputs
572 list = inf_GetEntriesByType(fxt->INFFIG,INF_SPECIN,INF_ANY_VALUES);
573 for (ptchain = list; ptchain; ptchain = delchain(ptchain,ptchain))
574 treatpin_mark(fxt,ptchain->DATA,INF_SPECIN);
575
576 // marquage pour les phases des outputs
577 list = inf_GetEntriesByType(fxt->INFFIG,INF_SPECOUT,INF_ANY_VALUES);
578 for (ptchain = list; ptchain; ptchain = delchain(ptchain,ptchain))
579 treatpin_mark(fxt,ptchain->DATA,INF_SPECOUT);
580
581 /* initialise the clocks */
582 stb_initclock(stab->PARSEDFIG,0);
583 stb_checkclock(stab->PARSEDFIG);
584 }
585
586 /*}}}************************************************************************/
587 /*{{{ stb_parse_domain_groups() */
588 /* */
589 /* */
590 /****************************************************************************/
591 void
592 stb_parse_domain_groups(stb_parse *stab, chain_list *group)
593 {BEGIN
594 ttvsig_list *ptttvsig;
595 chain_list *ptchain;
596 char name[1024];
597
598 stab->DOMAININDEX ++;
599 stab->CKDOMAINS = addchain(stab->CKDOMAINS, group);
600 for (ptchain = group; ptchain; ptchain = ptchain->NEXT)
601 {
602 ptttvsig = (ttvsig_list *)ptchain->DATA;
603 if (getptype(ptttvsig->USER, STB_DOMAIN) != NULL)
604 {
605 ttv_getsigname(stab->PARSEDFIG->FIG, name, ptttvsig);
606 stab->CLEANFUNC();
607 stb_error(ERR_MULTIPLE_DOMAIN, name, yylineno, STB_FATAL);
608 }
609 ptttvsig->USER = addptype(ptttvsig->USER, STB_DOMAIN,
610 (void *)((long)stab->DOMAININDEX));
611 }
612 stab->PARSEDFIG->CKDOMAIN = stb_addstbdomain(stab->PARSEDFIG->CKDOMAIN,
613 STB_NO_INDEX, STB_NO_INDEX);
614 }
615
616 /*}}}************************************************************************/
617 /*{{{ stb_parse_ckprio_pair() */
618 /* */
619 /* */
620 /****************************************************************************/
621 stbpriority *
622 stb_parse_ckprio_pair(stb_parse *stab, char *id1, char *id3)
623 {BEGIN
624 char cknamebuf[1024];
625 char cknetnamebuf[1024];
626 chain_list *ptchain;
627 stbpriority *res = NULL;
628 ttvsig_list *ptttvsig;
629
630 for (ptchain = stab->PARSEDFIG->CLOCK ; ptchain ; ptchain = ptchain->NEXT)
631 {
632 ptttvsig = (ttvsig_list*)ptchain->DATA ;
633 ttv_getsigname(stab->PARSEDFIG->FIG, cknamebuf, ptttvsig);
634 ttv_getnetname(stab->PARSEDFIG->FIG, cknetnamebuf, ptttvsig);
635 if (!mbk_casestrcmp(cknamebuf, id3) || !mbk_casestrcmp(cknetnamebuf, id3))
636 {
637 res = (stbpriority*)mbkalloc (sizeof (struct stbpriority)) ;
638 res->CLOCK = ptttvsig ;
639 res->MASK = strdup(id1) ;
640 break ;
641 }
642 }
643 if (!ptchain)
644 stb_error(ERR_NO_CLOCK_CONNECTOR, id3, yylineno, STB_FATAL);
645
646 return res;
647 }
648
649 /*}}}************************************************************************/
650 /*{{{ stb_parse_ckname_list() */
651 /* */
652 /* */
653 /****************************************************************************/
654 chain_list *
655 stb_parse_ckname_list(stb_parse *stab, chain_list *cklist, char *ident)
656 {BEGIN
657 chain_list *res;
658 char *ck;
659 chain_list *cl;
660
661 ck = namealloc(ident);
662 cl = stb_getsigfromlist(stab->PARSEDFIG->FIG,
663 stab->PARSEDFIG->CLOCK,
664 ck);
665
666 if (!cl)
667 {
668 stab->CLEANFUNC();
669 stb_error(ERR_NO_CLOCK_CONNECTOR, ck, yylineno, STB_FATAL);
670 }
671 //res = addchain(cklist,sig);
672 while (cl!=NULL)
673 {
674 if (getchain(cklist, cl->DATA)==NULL)
675 cklist=addchain(cklist, cl->DATA);
676 // res = append(cklist,cl);
677 cl=delchain(cl,cl);
678 }
679
680 return cklist;
681 }
682
683 /*}}}************************************************************************/
684 /*{{{ stb_parse_group() */
685 /* */
686 /* */
687 /****************************************************************************/
688 chain_list *
689 stb_parse_group(chain_list *cklist, long period)
690 {BEGIN
691 ttvsig_list *ptttvsig;
692 chain_list *ptchain;
693 stbck *ptstbck;
694
695 if (period != STB_NO_TIME)
696 {
697 for (ptchain = cklist; ptchain; ptchain = ptchain->NEXT)
698 {
699 ptttvsig = (ttvsig_list *)ptchain->DATA;
700
701 ptstbck = stb_getstbnode(ptttvsig->NODE)->CK;
702 if (ptstbck->PERIOD == STB_NO_TIME)
703 ptstbck->PERIOD = period;
704
705 ptstbck = stb_getstbnode(ptttvsig->NODE+1)->CK;
706 if (ptstbck->PERIOD == STB_NO_TIME)
707 ptstbck->PERIOD = period;
708 }
709 }
710
711 return cklist;
712 }
713
714 /*}}}************************************************************************/
715 /*{{{ stb_parse_eqvt_groups() */
716 /* */
717 /* */
718 /****************************************************************************/
719 void
720 stb_parse_eqvt_groups(stb_parse *stab, chain_list *group)
721 {BEGIN
722 ttvsig_list *ptttvsig;
723 chain_list *ptchain;
724 ptype_list *ptuser;
725 char curdomain = STB_NO_INDEX;
726 char sigdomain;
727 char name[1024];
728
729 stab->CKEQVT = addchain(stab->CKEQVT, group);
730 stab->EQVTINDEX ++;
731 for (ptchain = group; ptchain; ptchain = ptchain->NEXT)
732 {
733 ptttvsig = (ttvsig_list *)ptchain->DATA;
734 if (getptype(ptttvsig->USER, STB_EQUIVALENT) != NULL)
735 {
736 ttv_getsigname(stab->PARSEDFIG->FIG, name, ptttvsig);
737 stab->CLEANFUNC();
738 stb_error(ERR_MULTIPLE_EQUIVALENCE, name, yylineno, STB_FATAL);
739 }
740
741 if ((ptuser = getptype(ptttvsig->USER, STB_DOMAIN)) == NULL)
742 sigdomain = 0;
743 else
744 sigdomain = (char)((long)ptuser->DATA);
745
746 if (curdomain == STB_NO_INDEX)
747 curdomain = sigdomain;
748 else if (sigdomain != curdomain)
749 {
750 ttv_getsigname(stab->PARSEDFIG->FIG, name, ptttvsig);
751 stab->CLEANFUNC();
752 stb_error(ERR_DOMAIN_NOT_EQUIVALENT, name, yylineno, STB_FATAL);
753 }
754
755 ptttvsig->USER = addptype(ptttvsig->USER, STB_EQUIVALENT,
756 (void *)((long)stab->EQVTINDEX));
757 }
758 }
759
760 chain_list *stb_auto_create_equivalent_groups(stb_parse *stab)
761 {
762 stb_propagated_clock_to_clock *spctc;
763 chain_list *cl, *ch, *clocks;
764 char *master;
765 stbck *ref, *cur;
766 ttvsig_list *tvs, *tvso;
767 char clockname[1024];
768 char *thisgroupmaster, ok;
769 chain_list *grp, *res=NULL;
770 ptype_list *pt;
771 void *refdomain, *curdomain;
772
773 clocks=dupchainlst(stab->PARSEDFIG->CLOCK);
774
775 for (cl = clocks; cl; cl = cl->NEXT)
776 {
777 tvso=(ttvsig_list *)cl->DATA;
778 if (tvso!=NULL)
779 {
780 /* if ((pt=getptype(tvso->USER, STB_IS_CLOCK))!=NULL)
781 {
782 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
783 ref=&spctc->original_waveform;
784 }
785 else*/
786 ref=stb_getstbnode(&tvso->NODE[0])->CK;
787 if ((pt=getptype(tvso->USER, STB_DOMAIN))!=NULL) refdomain=pt->DATA;
788 else refdomain=NULL;
789
790 grp=addchain(NULL, tvso);
791 cl->DATA=NULL;
792 for (ch = cl->NEXT; ch; ch = ch->NEXT)
793 {
794 tvs=(ttvsig_list *)ch->DATA;
795 if (tvs!=NULL)
796 {
797 /* if ((pt=getptype(tvs->USER, STB_IS_CLOCK))!=NULL)
798 {
799 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
800 cur=&spctc->original_waveform;
801 }
802 else*/
803 cur=stb_getstbnode(&tvs->NODE[0])->CK;
804
805 if ((pt=getptype(tvso->USER, STB_DOMAIN))!=NULL) curdomain=pt->DATA;
806 else curdomain=NULL;
807 if (curdomain==refdomain && cur->PERIOD==ref->PERIOD
808 && ((cur->SUPMAX==ref->SUPMAX && cur->SUPMIN==ref->SUPMIN
809 && cur->SDNMAX==ref->SDNMAX && cur->SDNMIN==ref->SDNMIN)
810 || (cur->SUPMAX==ref->SDNMAX && cur->SUPMIN==ref->SDNMIN
811 && cur->SDNMAX==ref->SUPMAX && cur->SDNMIN==ref->SUPMIN)))
812 {
813 grp=addchain(grp, tvs);
814 ch->DATA=NULL;
815 }
816 }
817 }
818 if (grp->NEXT!=NULL)
819 {
820 avt_log(LOGSTABILITY,1, "New equivalent clock group:");
821 for (ch=grp; ch!=NULL; ch=ch->NEXT)
822 avt_log(LOGSTABILITY,1, " %s", ttv_getsigname(stab->PARSEDFIG->FIG,clockname,(ttvsig_list *)ch->DATA));
823 avt_log(LOGSTABILITY,1, "\n");
824
825 res=addchain(res, grp);
826 }
827 else
828 freechain(grp);
829 }
830 }
831 freechain(clocks);
832 return res;
833 }
834
835 chain_list *stb_merge_equiv_if_needed(chain_list *equiv, chain_list *equiv_auto)
836 {
837 chain_list *cl, *ch, *ecl, *ech, *toapp;
838 while (equiv_auto!=NULL)
839 {
840 toapp=NULL;
841 for (ch=(chain_list *)equiv_auto->DATA; ch!=NULL; ch=ch->NEXT)
842 {
843 for (ecl=equiv; ecl!=NULL; ecl=ecl->NEXT)
844 {
845 for (ech=(chain_list *)ecl->DATA; ech!=NULL && ech->DATA!=ch->DATA; ech=ech->NEXT) ;
846 if (ech!=NULL)
847 {
848 toapp=append(ecl->DATA, toapp);
849 ecl->DATA=NULL;
850 }
851 }
852 }
853 while (toapp!=NULL)
854 {
855 for (ch=(chain_list *)equiv_auto->DATA; ch!=NULL && ch->DATA!=toapp->DATA; ch=ch->NEXT) ;
856 if (ch==NULL)
857 equiv_auto->DATA=addchain(equiv_auto->DATA, toapp->DATA);
858 toapp=delchain(toapp, toapp);
859 }
860 equiv=addchain(equiv, append((chain_list *)equiv_auto->DATA, toapp));
861 equiv_auto=delchain(equiv_auto, equiv_auto);
862 }
863 return equiv;
864 }
865
866 /*}}}************************************************************************/
867 /*{{{ stb_parse_eqvt_clocks() */
868 /* */
869 /* */
870 /****************************************************************************/
871 void
872 stb_parse_eqvt_clocks(stb_parse *stab)
873 {BEGIN
874 stab->PARSEDFIG->USER = addptype(stab->PARSEDFIG->USER, STB_EQUIVALENT,
875 stab->CKEQVT);
876 }
877
878 /*}}}************************************************************************/
879 /*}}}************************************************************************/
880 /*{{{ Parse Pin */
881 /****************************************************************************/
882 /*{{{ command_state */
883 /* */
884 /* */
885 /****************************************************************************/
886 static inline void
887 command_state(ttvsig_list *ptttvsig, char state, int isdefault)
888 {
889 stbnode *ptstbnode_up;
890 stbnode *ptstbnode_dn;
891
892 ptstbnode_dn = stb_getstbnode(ptttvsig->NODE);
893 ptstbnode_up = stb_getstbnode(ptttvsig->NODE+1);
894 if (state == STB_NO_VERIF)
895 {
896 ptstbnode_dn->CK->VERIF = state;
897 ptstbnode_up->CK->VERIF = state;
898 }
899 else
900 {
901 if (!isdefault)
902 {
903 ptstbnode_dn->CK->VERIF &= ~(STB_UP|STB_DN);
904 ptstbnode_up->CK->VERIF &= ~(STB_UP|STB_DN);
905 }
906 ptstbnode_dn->CK->VERIF = state;
907 ptstbnode_up->CK->VERIF = state;
908 }
909 }
910
911 /*}}}************************************************************************/
912 /*{{{ stb_parse_command() */
913 /* */
914 /* */
915 /****************************************************************************/
916 void
917 stb_parse_command(stb_parse *stab, char *ident, char state)
918 {BEGIN
919 ttvsig_list *ptttvsig;
920 chain_list *ptchain;
921 char *name = namealloc(ident);
922 chain_list *cl, *start;
923 int tag=1;
924
925
926 if ((start=getStartForNode_HT(stab->PARSEDFIG, name, 0))==NULL)
927 start=stab->PARSEDFIG->COMMAND, tag=0;
928 cl=addchain(NULL, name);
929 for (ptchain = start; ptchain; ptchain = ptchain->NEXT)
930 {
931 ptttvsig = (ttvsig_list *)ptchain->DATA;
932 if (getptype(ptttvsig->USER, STB_WENABLE) != NULL)
933 continue ;
934 if (tag || ttv_testnetnamemask(stab->PARSEDFIG->FIG, ptttvsig, cl))
935 {
936 ptttvsig->USER = addptype(ptttvsig->USER, STB_WENABLE, (void *)NULL);
937 command_state(ptttvsig,state,0);
938 if (!mbk_isregex_name(name))
939 break;
940 }
941 }
942 if (tag) freechain(start);
943 freechain(cl);
944 if (ptchain == NULL && !mbk_isregex_name(name))
945 {
946 stab->CLEANFUNC();
947 stb_error(ERR_NO_COMMAND, name, yylineno, STB_FATAL);
948 }
949 }
950
951 /*}}}************************************************************************/
952 /*{{{ stb_parse_comdefault() */
953 /* */
954 /* */
955 /****************************************************************************/
956 void
957 stb_parse_comdefault(stb_parse *stab, char state)
958 {BEGIN
959 ttvsig_list *ptttvsig;
960 chain_list *ptchain;
961
962 for (ptchain = stab->PARSEDFIG->COMMAND; ptchain; ptchain = ptchain->NEXT)
963 {
964 ptttvsig = (ttvsig_list *)ptchain->DATA;
965 if (getptype(ptttvsig->USER, STB_WENABLE) != NULL)
966 continue ;
967 command_state(ptttvsig,state,1);
968 }
969 }
970
971 /*}}}************************************************************************/
972 /*{{{ Node abstraction */
973 /* */
974 /* */
975 /****************************************************************************/
976 static inline ttvsig_list *
977 getSigForNode(chain_list *ptchain, int type)
978 {
979 ttvsig_list *res = NULL;
980
981 switch (type)
982 {
983 case STB_P_ONOD :
984 case STB_P_INOD :
985 case STB_P_LOC :
986 case STB_P_MEM :
987 res = (ttvsig_list *)ptchain->DATA;
988 break;
989 case STB_P_NOD :
990 res = ((ttvevent_list *)ptchain->DATA)->ROOT;
991 break;
992 }
993 return res;
994 }
995
996 static NameAllocator stb_na;
997 static ht *stb_sight=NULL;
998
999 chain_list *
1000 getStartForNode_HT(stbfig_list *parsedfig, char *ident, int type)
1001 {
1002 chain_list *cl;
1003 char buf[1024];
1004 long l;
1005
1006 if (stb_sight==NULL)
1007 {
1008 stb_sight=addht(10000);
1009 CreateNameAllocator(20000, &stb_na, CASE_SENSITIVE);
1010 for (cl=parsedfig->MEMORY; cl!=NULL; cl=cl->NEXT)
1011 {
1012 ttv_getsigname(parsedfig->FIG, buf, (ttvsig_list *)cl->DATA);
1013 addhtitem(stb_sight, NameAlloc(&stb_na, buf), (long)cl->DATA);
1014 }
1015 for (cl=parsedfig->CONNECTOR; cl!=NULL; cl=cl->NEXT)
1016 {
1017 ttv_getsigname(parsedfig->FIG, buf, (ttvsig_list *)cl->DATA);
1018 addhtitem(stb_sight, NameAlloc(&stb_na, buf), (long)cl->DATA);
1019 }
1020 for (cl=parsedfig->NODE; cl!=NULL; cl=cl->NEXT)
1021 {
1022 ttv_getsigname(parsedfig->FIG, buf, ((ttvevent_list *)cl->DATA)->ROOT);
1023 addhtitem(stb_sight, NameAlloc(&stb_na, buf), (long)((ttvevent_list *)cl->DATA)->ROOT);
1024 }
1025 }
1026
1027 if ((l=gethtitem(stb_sight, NameAlloc(&stb_na, ident)))==EMPTYHT)
1028 return NULL;
1029
1030 return addchain(NULL, (void *)l);
1031 }
1032
1033 void cleanStartForNode_HT()
1034 {
1035 if (stb_sight!=NULL)
1036 {
1037 delht(stb_sight);
1038 DeleteNameAllocator(&stb_na);
1039 stb_sight=NULL;
1040 }
1041 }
1042
1043 static inline chain_list *
1044 getStartForNode(stbfig_list *parsedfig, int type)
1045 {
1046 chain_list *res = NULL;
1047 switch (type)
1048 {
1049 case STB_P_MEM :
1050 res = parsedfig->MEMORY;
1051 break;
1052 case STB_P_NOD :
1053 res = parsedfig->NODE;
1054 break;
1055 case STB_P_INOD :
1056 case STB_P_ONOD :
1057 res = parsedfig->CONNECTOR;
1058 break;
1059 }
1060
1061 return res;
1062 }
1063
1064 static inline int
1065 contForNode(ttvsig_list *ptttvsig, int type)
1066 {
1067 int res = 0;
1068
1069 switch (type)
1070 {
1071 case STB_P_MEM :
1072 res = ((ptttvsig->TYPE & TTV_SIG_C) == TTV_SIG_C ||
1073 (ptttvsig->TYPE & TTV_SIG_L) != TTV_SIG_L);
1074 break;
1075 case STB_P_NOD :
1076 res = ((ptttvsig->TYPE & TTV_SIG_C) == TTV_SIG_C ||
1077 (ptttvsig->TYPE & TTV_SIG_L) == TTV_SIG_L);
1078 break;
1079 case STB_P_OLOCD :
1080 case STB_P_ONOD :
1081 res = ((ptttvsig->TYPE & TTV_SIG_CO) != TTV_SIG_CO);
1082 break;
1083 case STB_P_ILOCD :
1084 case STB_P_INOD :
1085 res = ((ptttvsig->TYPE & TTV_SIG_CI) != TTV_SIG_CI ||
1086 (ptttvsig->TYPE & TTV_SIG_CB) == TTV_SIG_CB);
1087 break;
1088 }
1089 return res;
1090 }
1091
1092 static inline int
1093 chkCkForDefaultNode(stbnode *ptstbnode, int type)
1094 {
1095 int res = 0;
1096
1097 switch (type)
1098 {
1099 case STB_P_ILOCD :
1100 res = (ptstbnode->CK && ptstbnode->CK->TYPE == STB_TYPE_CLOCK);
1101 break;
1102 }
1103 return res;
1104 }
1105
1106 static inline stbpair_list ***
1107 getPairForDefaultNode(stbnode *ptstbnode, int type)
1108 {
1109 stbpair_list ***pair = NULL;
1110
1111 switch (type)
1112 {
1113 case STB_P_ILOCD :
1114 pair = &(ptstbnode->SPECIN);
1115 break;
1116 case STB_P_OLOCD :
1117 pair = &(ptstbnode->SPECOUT);
1118 break;
1119 }
1120
1121 return pair;
1122 }
1123
1124 /*}}}************************************************************************/
1125 /*{{{ copyIntervallsForDefaultNode() */
1126 /* */
1127 /* */
1128 /****************************************************************************/
1129 static inline void
1130 copyIntervallsForDefaultNode(stbnode *ptstbnode,
1131 stbpair_list *ptstbpair,
1132 int edge_option,
1133 int phase,
1134 stbfig_list *parsedfig,
1135 int type, int slope,
1136 long d, long u,
1137 int mode)
1138 {
1139 stbpair_list ***pair;
1140
1141 if (ptstbnode)
1142 {
1143 pair = getPairForDefaultNode(ptstbnode,type);
1144 if (!(*pair) &&
1145 (edge_option == slope || edge_option == STB_SLOPE_ALL))
1146 {
1147 *pair = stb_alloctab(parsedfig->PHASENUMBER);
1148 if (mode == STB_P_DUPPAIR)
1149 (*pair)[phase] = stb_dupstbpairlist(ptstbpair);
1150 else if (mode == STB_P_ADDPAIR)
1151 (*pair)[phase] = stb_addstbpair(NULL, d, u);
1152 }
1153 }
1154 }
1155
1156 /*}}}************************************************************************/
1157 /*{{{ parse_checkPhase() */
1158 /* */
1159 /* */
1160 /****************************************************************************/
1161 static inline char
1162 parse_checkPhase(stb_parse *stab, char *ident, int source_phase)
1163 {
1164 char phase;
1165
1166 if (source_phase == STB_NO_INDEX)
1167 if (stab->DEFAULTPHASE != STB_NO_INDEX)
1168 phase = stab->DEFAULTPHASE;
1169 else if (!stab->PARSEDFIG->CKDOMAIN ||
1170 !stab->PARSEDFIG->CKDOMAIN->NEXT)
1171 phase = (int)stab->PARSEDFIG->PHASENUMBER - 1;
1172 else
1173 stb_error(ERR_UNKNOWN_PHASE, ident, yylineno, STB_FATAL);
1174 else
1175 phase = source_phase;
1176
1177 return phase;
1178 }
1179
1180 /*}}}************************************************************************/
1181 /*{{{ node() */
1182 /* */
1183 /* */
1184 /****************************************************************************/
1185 static inline void
1186 node(stb_parse *stab, char *ident, char edge_option, int source_phase,
1187 char hz_option, int type)
1188 {
1189 ttvsig_list *ptttvsig;
1190 chain_list *ptchain;
1191 int errcode = 0;
1192 int table, done=0;
1193 char phase;
1194
1195 #if 1
1196 // + rapide mais consomme localement +
1197 ptchain = getStartForNode_HT(stab->PARSEDFIG, ident, type);
1198
1199 for ( ; ptchain; ptchain = delchain(ptchain, ptchain))
1200 {
1201 ptttvsig = (ttvsig_list *)ptchain->DATA;
1202 if (contForNode(ptttvsig,type))
1203 continue;
1204
1205 phase = parse_checkPhase(stab,ident,source_phase);
1206 if (hz_option == 0)
1207 table = STB_TABLE;
1208 else
1209 table = STB_THZ;
1210
1211 errcode = stb_addintervals(stab->PARSEDFIG, ptttvsig,
1212 stab->PTSTABLELIST,
1213 stab->PTUNSTABLELIST, table,
1214 edge_option, phase, hz_option,type==STB_P_NOD?1:0);
1215 if (errcode)
1216 {
1217 stab->CLEANFUNC();
1218 stb_error(errcode, ident, yylineno, STB_FATAL);
1219 }
1220 done=1;
1221 }
1222 stb_parse_freeStab(stab);
1223 if (!done)
1224 {
1225 stb_error(ERR_NOT_FOUND_NODE, ident, yylineno, STB_NONFATAL);
1226 }
1227 #else
1228 char namebuf[1024];
1229 // consomme moins (?) et N2/2 pour les noeuds internes
1230 ptchain = getStartForNode(stab->PARSEDFIG,type);
1231 for ( ; ptchain; ptchain = ptchain->NEXT)
1232 {
1233 ptttvsig = getSigForNode(ptchain,type);
1234 if (contForNode(ptttvsig,type))
1235 continue;
1236 ttv_getsigname(stab->PARSEDFIG->FIG, namebuf, ptttvsig);
1237 // if (namealloc(namebuf) == name)
1238 if (mbk_casestrcmp(namebuf,ident)==0)
1239 {
1240 phase = parse_checkPhase(stab,ident,source_phase);
1241 if (hz_option == 0)
1242 table = STB_TABLE;
1243 else
1244 table = STB_THZ;
1245
1246 errcode = stb_addintervals(stab->PARSEDFIG, ptttvsig,
1247 stab->PTSTABLELIST,
1248 stab->PTUNSTABLELIST, table,
1249 edge_option, phase, hz_option,type==STB_P_NOD?1:0);
1250 if (errcode)
1251 {
1252 stab->CLEANFUNC();
1253 stb_error(errcode, ident, yylineno, STB_FATAL);
1254 }
1255 if (type==STB_P_NOD) break; // pas de regex et ttvsig en double dans la liste
1256 }
1257 }
1258 stb_parse_freeStab(stab);
1259 #endif
1260 }
1261
1262 /*}}}************************************************************************/
1263 /*{{{ stb_parse_mem() */
1264 /* */
1265 /* */
1266 /****************************************************************************/
1267 void
1268 stb_parse_mem(stb_parse *stab, char *ident, char edge_option,
1269 int source_phase, char hz_option)
1270 {BEGIN
1271 node(stab, ident, edge_option, source_phase, hz_option, STB_P_MEM);
1272 }
1273
1274 /*}}}************************************************************************/
1275 /*{{{ stb_parse_node() */
1276 /* */
1277 /* */
1278 /****************************************************************************/
1279 void
1280 stb_parse_node(stb_parse *stab, char *ident, char edge_option,
1281 int source_phase, char hz_option)
1282 {BEGIN
1283 node(stab, ident, edge_option, source_phase, hz_option, STB_P_NOD);
1284 }
1285
1286 /*}}}************************************************************************/
1287 /*{{{ stb_parse_outnode() */
1288 /* */
1289 /* */
1290 /****************************************************************************/
1291 void
1292 stb_parse_outnode(stb_parse *stab, char *ident, char edge_option,
1293 int source_phase, char hz_option)
1294 {BEGIN
1295 node(stab, ident, edge_option, source_phase, hz_option, STB_P_ONOD);
1296 }
1297
1298 /*}}}************************************************************************/
1299 /*{{{ stb_parse_innode() */
1300 /* */
1301 /* */
1302 /****************************************************************************/
1303 void
1304 stb_parse_innode(stb_parse *stab, char *ident, char edge_option,
1305 int source_phase, char hz_option)
1306 {BEGIN
1307 node(stab, ident, edge_option, source_phase, hz_option, STB_P_INOD);
1308 }
1309
1310 /*}}}************************************************************************/
1311 /*{{{ stb_parse_freeStab() */
1312 /* */
1313 /* */
1314 /****************************************************************************/
1315 void
1316 stb_parse_freeStab(stb_parse *stab)
1317 {BEGIN
1318 freechain(stab->PTSTABLELIST);
1319 stab->PTSTABLELIST = NULL;
1320 freechain(stab->PTUNSTABLELIST);
1321 stab->PTUNSTABLELIST = NULL;
1322 stab->DEFAULTPHASE = STB_NO_INDEX;
1323 }
1324
1325 /*}}}************************************************************************/
1326 /*{{{ locon() */
1327 /* */
1328 /* */
1329 /****************************************************************************/
1330 static inline void
1331 locon(stb_parse *stab, char *ident, char edge_option, int source_phase,
1332 int table)
1333 {
1334 ttvsig_list *ptttvsig;
1335 chain_list *ptchain;
1336 char *name = namealloc(ident);
1337 char namebuf[1024];
1338 int errcode = 0, cx=0;
1339 char phase;
1340
1341 for (ptchain = stab->PARSEDFIG->CONNECTOR; ptchain; ptchain = ptchain->NEXT)
1342 {
1343 ptttvsig = (ttvsig_list *)ptchain->DATA;
1344
1345 if (table==STB_SPECIN && contForNode(ptttvsig,STB_P_ILOCD) && (ptttvsig->TYPE & TTV_SIG_CX) != TTV_SIG_CX)
1346 continue;
1347 if (table==STB_SPECIN && (ptttvsig->TYPE & TTV_SIG_CB) == TTV_SIG_CB)
1348 continue;
1349 if (table==STB_SPECOUT && contForNode(ptttvsig,STB_P_OLOCD) && (ptttvsig->TYPE & TTV_SIG_CX) != TTV_SIG_CX)
1350 continue;
1351
1352 if ((ptttvsig->TYPE & TTV_SIG_CX) == TTV_SIG_CX) cx=1;
1353
1354 ttv_getsigname(stab->PARSEDFIG->FIG, namebuf, ptttvsig);
1355
1356 if (mbk_TestREGEX(namebuf, name))
1357 {
1358 // on evite les clocks
1359 if (getptype(ptttvsig->USER, STB_IS_CLOCK)==NULL)
1360 {
1361 phase = parse_checkPhase(stab,ident,source_phase);
1362 errcode = stb_addintervals(stab->PARSEDFIG, ptttvsig,
1363 stab->PTSTABLELIST,
1364 stab->PTUNSTABLELIST,
1365 table, edge_option, phase, 0, table==STB_SPECOUT?1:0);
1366 if (errcode != 0)
1367 {
1368 stab->CLEANFUNC();
1369 stb_error(errcode, name, yylineno, STB_FATAL);
1370 }
1371 }
1372 if (!mbk_isregex_name(name))
1373 break;
1374 }
1375 }
1376 stb_parse_freeStab(stab);
1377 if (ptchain == NULL && !mbk_isregex_name(name))
1378 {
1379 stab->CLEANFUNC();
1380 stb_error(ERR_NO_CONNECTOR, name, yylineno, STB_FATAL);
1381 }
1382 else
1383 {
1384 if (cx && !mbk_isregex_name(name)) avt_errmsg(STB_ERRMSG, "043", AVT_WARNING, name);
1385 }
1386 }
1387
1388 /*}}}************************************************************************/
1389 /*{{{ stb_parse_inlocon() */
1390 /* */
1391 /* */
1392 /****************************************************************************/
1393 void
1394 stb_parse_inlocon(stb_parse *stab, char *ident, char edge_option,
1395 int source_phase)
1396 {BEGIN
1397 locon(stab,ident,edge_option,source_phase,STB_SPECIN);
1398 }
1399
1400 /*}}}************************************************************************/
1401 /*{{{ stb_parse_outlocon() */
1402 /* */
1403 /* */
1404 /****************************************************************************/
1405 void
1406 stb_parse_outlocon(stb_parse *stab, char *ident, char edge_option,
1407 int source_phase)
1408 {BEGIN
1409 locon(stab,ident,edge_option,source_phase,STB_SPECOUT);
1410 }
1411
1412 /*}}}************************************************************************/
1413 /*{{{ default_locon() */
1414 /* */
1415 /* */
1416 /****************************************************************************/
1417 static inline void
1418 default_locon(stb_parse *stab, char edge_option, int source_phase, int type)
1419 {
1420 ttvsig_list *pttarget;
1421 stbnode *ptstbnode_up;
1422 stbnode *ptstbnode_dn;
1423 stbpair_list *ptstbpair;
1424 chain_list *ptchain;
1425 long period;
1426 int errcode = 0;
1427 char phase;
1428
1429 phase = parse_checkPhase(stab,"default",source_phase);
1430 period = stb_getperiod(stab->PARSEDFIG, phase);
1431 ptstbpair = stb_buildintervals(stab->PTSTABLELIST,
1432 stab->PTUNSTABLELIST,
1433 period,&errcode);
1434 if (errcode != 0)
1435 {
1436 stab->CLEANFUNC();
1437 stb_error(errcode, "default", yylineno, STB_FATAL);
1438 }
1439 stb_parse_freeStab(stab);
1440
1441 for (ptchain = stab->PARSEDFIG->CONNECTOR; ptchain; ptchain = ptchain->NEXT)
1442 {
1443 pttarget = (ttvsig_list *)ptchain->DATA;
1444 if (contForNode(pttarget,type))
1445 continue;
1446 ptstbnode_dn = stb_getstbnode(pttarget->NODE);
1447 ptstbnode_up = stb_getstbnode(pttarget->NODE+1);
1448
1449 if (chkCkForDefaultNode(ptstbnode_dn,type) ||
1450 chkCkForDefaultNode(ptstbnode_up,type))
1451 continue;
1452
1453 copyIntervallsForDefaultNode(ptstbnode_dn,ptstbpair,edge_option,phase,
1454 stab->PARSEDFIG,type,STB_SLOPE_DN,0,0,
1455 STB_P_DUPPAIR);
1456 copyIntervallsForDefaultNode(ptstbnode_up,ptstbpair,edge_option,phase,
1457 stab->PARSEDFIG,type,STB_SLOPE_UP,0,0,
1458 STB_P_DUPPAIR);
1459 }
1460 stb_freestbpair(ptstbpair);
1461 }
1462
1463 /*}}}************************************************************************/
1464 /*{{{ stb_parse_indefault() */
1465 /* */
1466 /* */
1467 /****************************************************************************/
1468 void
1469 stb_parse_indefault(stb_parse *stab, char edge_option, int source_phase)
1470 {BEGIN
1471 default_locon(stab,edge_option,source_phase,STB_P_ILOCD);
1472 }
1473
1474 /*}}}************************************************************************/
1475 /*{{{ stb_parse_outdefault() */
1476 /* */
1477 /* */
1478 /****************************************************************************/
1479 void
1480 stb_parse_outdefault(stb_parse *stab, char edge_option, int source_phase)
1481 {BEGIN
1482 default_locon(stab,edge_option,source_phase,STB_P_OLOCD);
1483 }
1484
1485 /*}}}************************************************************************/
1486 /*}}}************************************************************************/
1487 /*{{{ Main */
1488 /****************************************************************************/
1489 /*{{{ stb_parse_stb_file() */
1490 /* */
1491 /* */
1492 /****************************************************************************/
1493 void
1494 stb_parse_stb_file(stb_parse *stab)
1495 {BEGIN
1496 ttvsig_list *ptttvsig;
1497 stbfig_list *parsedfig = stab->PARSEDFIG;
1498 chain_list *ptchain;
1499 stbnode *ptstbnode;
1500 stbck *ptstbck;
1501 char edge, phasenumber;
1502 long d = 0, u = 0;
1503 int i;
1504
1505 phasenumber = parsedfig->PHASENUMBER;
1506 ptstbck = stb_getclock(parsedfig,phasenumber - 1,NULL,&edge,NULL);
1507
1508 if (ptstbck != NULL)
1509 {
1510 if (edge == STB_SLOPE_DN)
1511 {
1512 d = ptstbck->SDNMIN;
1513 u = ptstbck->SDNMAX;
1514 }
1515 else
1516 {
1517 d = ptstbck->SUPMIN;
1518 u = ptstbck->SUPMAX;
1519 }
1520 }
1521
1522 for (ptchain = parsedfig->CONNECTOR; ptchain; ptchain = ptchain->NEXT)
1523 {
1524 ptttvsig = (ttvsig_list *)ptchain->DATA;
1525 if (contForNode(ptttvsig,STB_P_ILOCD))
1526 continue;
1527 for (i = 0; i < 2; i++)
1528 {
1529 ptstbnode = stb_getstbnode(ptttvsig->NODE+i);
1530 if (chkCkForDefaultNode(ptstbnode,STB_P_ILOCD))
1531 continue;
1532
1533 copyIntervallsForDefaultNode(ptstbnode,NULL,0,phasenumber-1,parsedfig,
1534 STB_P_ILOCD,0,d,u,STB_P_ADDPAIR);
1535 }
1536 }
1537 stab->PARSEDFIG = NULL; /* finished with it */
1538 }
1539
1540 /*}}}************************************************************************/
1541 /*{{{ stb_parse_name() */
1542 /* */
1543 /* */
1544 /****************************************************************************/
1545 void
1546 stb_parse_name(stb_parse *stab, char *ident, int doit)
1547 {BEGIN
1548 stbfig_list *ptfig;
1549 char *name;
1550 int found = FALSE;
1551
1552 doit=0;
1553 // if (doit || !done)
1554 // {
1555 name = namealloc(ident);
1556
1557 /* check that the STB figure exists */
1558 for (ptfig = HEAD_STBFIG; ptfig && !found; ptfig = ptfig->NEXT)
1559 {
1560 if (ptfig->FIG->INFO->FIGNAME == name)
1561 {
1562 found = TRUE;
1563 stab->PARSEDFIG = ptfig;
1564 }
1565 if (!found)
1566 stb_error(ERR_NO_FIGURE, NULL, 0, STB_FATAL);
1567 }
1568 // }
1569 }
1570
1571 /*}}}************************************************************************/
1572 /*{{{ stb_parse_relative_phase() */
1573 /* */
1574 /* */
1575 /****************************************************************************/
1576 void
1577 stb_parse_relative_phase(stb_parse *stab, stb_parse_doublet *relative_phase,
1578 char relative_type, char *ident, int edge_option)
1579 {BEGIN
1580 ttvevent_list *ptttvevent;
1581 ttvevent_list *ptttvck;
1582 stbck *ptstbck;
1583 char *name;
1584
1585 name = namealloc(ident);
1586 ptttvevent = stb_getphase(stab->PARSEDFIG,name,edge_option);
1587 if (!ptttvevent)
1588 {
1589 ptttvevent = stb_getphase(stab->PARSEDFIG,name,STB_SLOPE_ALL);
1590 if (ptttvevent)
1591 if ((ptttvevent->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
1592 ptttvck = ptttvevent->ROOT->NODE ;
1593 else
1594 ptttvck = ptttvevent->ROOT->NODE + 1 ;
1595 else
1596 {
1597 stab->CLEANFUNC();
1598 stb_error(ERR_UNKNOWN_PHASE,name,yylineno,STB_FATAL);
1599 }
1600 }
1601 else
1602 ptttvck = ptttvevent ;
1603
1604 ptstbck = stb_getstbnode(ptttvck)->CK;
1605 if ((ptttvck->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
1606 {
1607 relative_phase->start = ptstbck->SUPMIN;
1608 relative_phase->end = ptstbck->SUPMAX;
1609 }
1610 else
1611 {
1612 relative_phase->start = ptstbck->SDNMIN;
1613 relative_phase->end = ptstbck->SDNMAX;
1614 }
1615
1616 if (relative_type == STBYY_BEFORE)
1617 {
1618 relative_phase->start += ptstbck->PERIOD;
1619 relative_phase->end += ptstbck->PERIOD;
1620 relative_phase->signe = (long)-1;
1621 }
1622 else
1623 relative_phase->signe = (long)1;
1624
1625 ptstbck = stb_getstbnode(ptttvevent)->CK;
1626 stab->DEFAULTPHASE = ptstbck->CKINDEX;
1627
1628 }
1629
1630 /*}}}************************************************************************/
1631 /*{{{ stb_parse_phase() */
1632 /* */
1633 /* */
1634 /****************************************************************************/
1635 int
1636 stb_parse_phase(stb_parse *stab, char *ident, int edge_option)
1637 {BEGIN
1638 int res;
1639 char *name;
1640
1641 if (!ident)
1642 res = STB_NO_INDEX;
1643 else
1644 {
1645 name = namealloc(ident);
1646 res = (int)stb_getphaseindex(stab->PARSEDFIG,name,edge_option);
1647 if (res == STB_NO_INDEX)
1648 {
1649 stab->CLEANFUNC();
1650 stb_error(ERR_UNKNOWN_PHASE,name,yylineno,STB_FATAL);
1651 }
1652 }
1653
1654 return res;
1655 }
1656
1657 /*}}}************************************************************************/
1658 /*{{{ stb_parse_stability() */
1659 /* */
1660 /* */
1661 /****************************************************************************/
1662 void
1663 stb_parse_stability(stb_parse *stab, char stability_type, long integer,
1664 stb_parse_doublet *relative_phase, chain_list *inschain)
1665 {BEGIN
1666 chain_list *res;
1667 long stabtime;
1668
1669 if (relative_phase)
1670 {
1671 stabtime = integer * relative_phase->signe + relative_phase->end;
1672 res = addchain(NULL,(void *)stabtime);
1673 }
1674 else
1675 res = inschain;
1676
1677 if (stability_type == STB_STABLE)
1678 stab->PTSTABLELIST = append(stab->PTSTABLELIST,res);
1679 else
1680 stab->PTUNSTABLELIST = append(stab->PTUNSTABLELIST,res);
1681 }
1682
1683 /*}}}************************************************************************/
1684 /*{{{ stb_parse_wenable() */
1685 /* */
1686 /* */
1687 /****************************************************************************/
1688 void
1689 stb_parse_wenable(stb_parse *stab)
1690 {BEGIN
1691 ttvsig_list *ptttvsig;
1692 chain_list *ptchain;
1693
1694 for (ptchain = stab->PARSEDFIG->COMMAND; ptchain; ptchain = ptchain->NEXT)
1695 {
1696 ptttvsig = (ttvsig_list *)ptchain->DATA;
1697 if (getptype(ptttvsig->USER, STB_WENABLE) != NULL)
1698 ptttvsig->USER = delptype(ptttvsig->USER, STB_WENABLE);
1699 }
1700 }
1701
1702 /*}}}************************************************************************/
1703 /*}}}************************************************************************/
1704
1705 void
1706 stb_parse_memory(stb_parse *stab, char *ident, int state)
1707 {BEGIN
1708 ttvsig_list *ptttvsig;
1709 chain_list *ptchain;
1710 char *name = namealloc(ident);
1711 stbnode *n;
1712 chain_list *cl, *start;
1713 int tag=1;
1714
1715 if ((start=getStartForNode_HT(stab->PARSEDFIG, name, 0))==NULL)
1716 start=stab->PARSEDFIG->MEMORY, tag=0;
1717
1718 cl=addchain(NULL, ident);
1719 for (ptchain = start; ptchain; ptchain = ptchain->NEXT)
1720 {
1721 ptttvsig = (ttvsig_list *)ptchain->DATA;
1722 if (tag || ttv_testnetnamemask(stab->PARSEDFIG->FIG, ptttvsig, cl))
1723 {
1724 n=stb_getstbnode(ptttvsig->NODE);
1725 if (state & INF_NOCHECK_SETUP) n->FLAG|=STB_NODE_NOSETUP;
1726 if (state & INF_NOCHECK_HOLD) n->FLAG|=STB_NODE_NOHOLD;
1727 n=stb_getstbnode(ptttvsig->NODE+1);
1728 if (state & INF_NOCHECK_SETUP) n->FLAG|=STB_NODE_NOSETUP;
1729 if (state & INF_NOCHECK_HOLD) n->FLAG|=STB_NODE_NOHOLD;
1730 if (!mbk_isregex_name(name))
1731 break;
1732 }
1733 }
1734 if (tag) freechain(start);
1735 freechain(cl);
1736 if (ptchain == NULL && !mbk_isregex_name(name))
1737 {
1738 stab->CLEANFUNC();
1739 stb_error(ERR_NOT_FOUND_MEMORY, name, yylineno, STB_FATAL);
1740 }
1741 }
1742