Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stb / stb_falseslack.c
1 #include <stdlib.h>
2
3 #include MUT_H
4 #include STB_H
5 #include "stb_falseslack.h"
6
7
8 typedef struct stbfalsepath
9 {
10 struct stbfalsepath *NEXT ;
11 char *startclock;
12 char *endclock;
13 char *startsig;
14 char *endsig;
15 char startclock_dir;
16 char endclock_dir;
17 char startsig_dir;
18 char endsig_dir;
19 char setuphold;
20 }
21 stbfalseslack_list ;
22
23 typedef struct
24 {
25 stbfalseslack_list *WILDCARDS, *NOWILDCARDS;
26 ht *START_HASH, *END_HASH;
27 } falseslack_info;
28
29 typedef struct
30 {
31 int nb;
32 chain_list *FALSESLACK_WILDCARD, *FALSESLACK_NOWILDCARD;
33 } nowildcard_info;
34
35 static int stb_falseslack_match_name(ttvfig_list *tvf, ttvsig_list *tvs, char *regex)
36 {
37 char buf[1024];
38 if (mbk_TestREGEX(ttv_getsigname(tvf, buf, tvs),regex)) return 1;
39 if (mbk_TestREGEX(ttv_getnetname(tvf, buf, tvs),regex)) return 1;
40 return 0;
41 }
42
43 static inline void *getkey_forsignal(ttvsig_list *tvs)
44 {
45 return tvs;
46 }
47
48 ht *stb_buildquickaccessht_forfalsepath(ttvfig_list *ttvfig, NameAllocator *NA)
49 {
50 chain_list *chainsig;
51 ht *h;
52 char buf[1024], *nname;
53 ttvsig_list *tvs;
54 long l;
55 chain_list *cl;
56
57
58 CreateNameAllocator(10000, NA, CASE_SENSITIVE);
59
60 chainsig = ttv_getsigbytype(ttvfig,NULL,TTV_SIG_C|
61 TTV_SIG_Q|
62 TTV_SIG_L|
63 TTV_SIG_B|
64 TTV_SIG_R,NULL) ;
65
66 h=addht(100000);
67 while (chainsig!=NULL)
68 {
69 tvs=(ttvsig_list *)chainsig->DATA;
70
71 ttv_getnetname(ttvfig, buf, tvs);
72 nname=NameAlloc(NA, buf);
73 if ((l=gethtitem(h, nname))==EMPTYHT) cl=NULL;
74 else cl=(chain_list *)l;
75
76 addhtitem(h, nname, (long)addchain(cl, tvs));
77
78 ttv_getsigname(ttvfig, buf, tvs);
79 if (mbk_casestrcmp(nname, buf)!=0 && (nname=namefind(buf))!=NULL)
80 addhtitem(h, nname, (long)tvs);
81
82 chainsig=delchain(chainsig, chainsig);
83 }
84 return h;
85 }
86
87 void stb_freeequickaccessht_forfalsepath(ht *h, NameAllocator *NA)
88 {
89 long nextitem ;
90 void *nextkey ;
91
92 scanhtkey( h, 1, &nextkey, &nextitem ) ;
93 while( nextitem != EMPTYHT )
94 {
95 if (NameAllocFind(NA, nextkey)!=NULL)
96 freechain( (chain_list *)nextitem ) ;
97 scanhtkey( h, 0, &nextkey, &nextitem ) ;
98 }
99
100 delht(h) ;
101 }
102
103 static int stb_addfalsepath_entry_in_hash_table(ttvfig_list *ttvfig, ht *destination, char *sig, ht *h, stbfalseslack_list *pt, int wild, NameAllocator *NA)
104 {
105 nowildcard_info *nwi;
106 long l, l1;
107 ttvsig_list *ptsig;
108 char *signame, buf[1024];
109 chain_list *cl;
110
111 if ((l=gethtitem(h, sig))!=EMPTYHT || ((signame=NameAllocFind(NA, sig))!=NULL && (l1=gethtitem(h, signame))!=EMPTYHT))
112 {
113 if (l!=EMPTYHT)
114 {
115 ttv_getnetname(ttvfig, buf, (ttvsig_list *)l);
116 signame=NameAllocFind(NA, buf);
117 if (signame!=NULL) l1=gethtitem(h, signame);
118 else l1=EMPTYHT;
119 }
120 if (l1!=EMPTYHT)
121 {
122 for (cl=(chain_list *)l1; cl!=NULL; cl=cl->NEXT)
123 {
124 ptsig=(ttvsig_list *)cl->DATA;
125
126 if ((l=gethtitem(destination, getkey_forsignal(ptsig)))==EMPTYHT)
127 {
128 nwi=(nowildcard_info *)mbkalloc(sizeof(nowildcard_info));
129 nwi->nb=0;
130 nwi->FALSESLACK_NOWILDCARD=nwi->FALSESLACK_WILDCARD=NULL;
131 addhtitem(destination, getkey_forsignal(ptsig), (long)nwi);
132 }
133 else
134 {
135 nwi=(nowildcard_info *)l;
136 }
137 nwi->nb++;
138 if (wild) nwi->FALSESLACK_WILDCARD=addchain(nwi->FALSESLACK_WILDCARD, pt);
139 else nwi->FALSESLACK_NOWILDCARD=addchain(nwi->FALSESLACK_NOWILDCARD, pt);
140 }
141 return 1;
142 }
143 else avt_errmsg(STB_ERRMSG, "042", AVT_WARNING, mbk_get_reverse_index_regex(sig));
144 }
145 return 0;
146 }
147
148 /*****************************************************************************/
149 /* function ttv_addfalsepath */
150 /* parametres : */
151 /* ttvfig : figure */
152 /* */
153 /* ajoute un faux chemin dans la liste des faux chemins */
154 /*****************************************************************************/
155 void stb_addfalsepath(stbfig_list *stbfig, ptype_list *siglist, ht *nametosig,NameAllocator *NA)
156 {
157 stbfalseslack_list *pt, **whereptype;
158 ptype_list *ptype;
159 falseslack_info *fpi;
160 int inw, outw;
161
162 pt = (stbfalseslack_list *)mbkalloc(sizeof(stbfalseslack_list));
163
164 pt->setuphold=((char)siglist->TYPE) & (INF_FALSESLACK_SETUP|INF_FALSESLACK_HOLD|INF_FALSESLACK_LATCH);
165 pt->startclock=mbk_index_regex((char *)siglist->DATA);
166 pt->startclock_dir=(char)siglist->TYPE;
167 siglist=siglist->NEXT;
168 pt->startsig=mbk_index_regex((char *)siglist->DATA);
169 pt->startsig_dir=(char)siglist->TYPE;
170 siglist=siglist->NEXT;
171 pt->endsig=mbk_index_regex((char *)siglist->DATA);
172 pt->endsig_dir=(char)siglist->TYPE;
173 siglist=siglist->NEXT;
174 pt->endclock=mbk_index_regex((char *)siglist->DATA);
175 pt->endclock_dir=(char)siglist->TYPE;
176
177 if ((ptype = getptype(stbfig->USER,STB_FIG_FALSESLACK))==NULL)
178 {
179 fpi=(falseslack_info *)mbkalloc(sizeof(falseslack_info));
180 fpi->WILDCARDS=fpi->NOWILDCARDS=NULL;
181 fpi->START_HASH=addht(100);
182 fpi->END_HASH=addht(100);
183 stbfig->USER = addptype(stbfig->USER, STB_FIG_FALSESLACK, fpi);
184 }
185 else
186 fpi=(falseslack_info *)ptype->DATA;
187
188 if (!mbk_isregex_name(pt->startsig)) inw=0; else inw=1;
189 if (!mbk_isregex_name(pt->endsig)) outw=0; else outw=1;
190 if (!inw || !outw)
191 whereptype=&fpi->NOWILDCARDS;
192 else
193 whereptype=&fpi->WILDCARDS;
194
195 pt->NEXT = *whereptype;
196 *whereptype= pt;
197
198 if (!stb_addfalsepath_entry_in_hash_table(stbfig->FIG,fpi->START_HASH, pt->startsig, nametosig, pt, outw, NA))
199 {
200 }
201
202 if (!stb_addfalsepath_entry_in_hash_table(stbfig->FIG,fpi->END_HASH, pt->endsig, nametosig, pt, inw, NA))
203 {
204 }
205 }
206
207 /*****************************************************************************/
208 /* function ttv_freefalsepath */
209 /* parametres : */
210 /* ttvfig : figure */
211 /* */
212 /* modelise un lien en fonction de sa resistance et son parametre de front */
213 /*****************************************************************************/
214
215 void stb_freefalseslack(stbfig_list *stbfig)
216 {
217 ptype_list *ptype ;
218 falseslack_info *fpi;
219 nowildcard_info *nwi;
220 chain_list *cl;
221 stbfalseslack_list *fpl, *nfpl;
222
223 ptype = getptype(stbfig->USER,STB_FIG_FALSESLACK) ;
224
225 if(ptype == NULL)
226 return ;
227
228 fpi=(falseslack_info *)ptype->DATA;
229 cl=GetAllHTElems(fpi->START_HASH);
230 while (cl!=NULL)
231 {
232 nwi=(nowildcard_info *)cl->DATA;
233 freechain(nwi->FALSESLACK_WILDCARD);
234 freechain(nwi->FALSESLACK_NOWILDCARD);
235 mbkfree(nwi);
236 cl=delchain(cl, cl);
237 }
238 delht(fpi->START_HASH);
239
240 cl=GetAllHTElems(fpi->END_HASH);
241 while (cl!=NULL)
242 {
243 nwi=(nowildcard_info *)cl->DATA;
244 freechain(nwi->FALSESLACK_WILDCARD);
245 freechain(nwi->FALSESLACK_NOWILDCARD);
246 mbkfree(nwi);
247 cl=delchain(cl, cl);
248 }
249 delht(fpi->END_HASH);
250
251 for (fpl=fpi->WILDCARDS; fpl!=NULL; fpl=nfpl)
252 {
253 nfpl=fpl->NEXT;
254 mbkfree(fpl) ;
255 }
256
257 for (fpl=fpi->NOWILDCARDS; fpl!=NULL; fpl=nfpl)
258 {
259 nfpl=fpl->NEXT;
260 mbkfree(fpl) ;
261 }
262
263 mbkfree(fpi);
264 stbfig->USER = delptype(stbfig->USER,STB_FIG_FALSESLACK) ;
265 }
266
267 static int stb_sameevent(char ev, long type)
268 {
269 if ((ev & INF_FALSESLACK_UP)!=0 && (type & TTV_NODE_UP)!=0) return 1;
270 if ((ev & INF_FALSESLACK_DOWN)!=0 && (type & TTV_NODE_UP)==0) return 1;
271 return 0;
272 }
273
274 static int check_goodtype(int type, ttvevent_list *eventout)
275 {
276 if ((type & (INF_FALSESLACK_LATCH|INF_FALSESLACK_PRECH))==0) return 1;
277 if ((type & INF_FALSESLACK_LATCH)!=0 && (eventout->ROOT->TYPE & TTV_SIG_L)!=0) return 1;
278 if ((type & INF_FALSESLACK_PRECH)!=0 && (eventout->ROOT->TYPE & TTV_SIG_R)!=0) return 1;
279 return 0;
280 }
281
282 int stb_isfalseslack(stbfig_list *stbfig, ttvevent_list *startck, ttvevent_list *eventin, ttvevent_list *eventout, ttvevent_list *endck, int type)
283 {
284 stbfalseslack_list *pt ;
285 ptype_list *ptype ;
286 falseslack_info *fpi;
287 long l;
288 int usew;
289 nowildcard_info *nwi_start, *nwi_end, *orig_nwi_start, *orig_nwi_end;
290 chain_list *cl;
291 int res=0, maxres;
292
293 if((ptype = getptype(stbfig->USER,STB_FIG_FALSESLACK)) == NULL)
294 return(0) ;
295
296 fpi=(falseslack_info *)ptype->DATA;
297
298 // GESTION DES NON WILDCARDS
299 if ((l=gethtitem(fpi->START_HASH, getkey_forsignal(eventin->ROOT)))!=EMPTYHT) nwi_start=(nowildcard_info *)l;
300 else nwi_start=NULL;
301 if ((l=gethtitem(fpi->END_HASH, getkey_forsignal(eventout->ROOT)))!=EMPTYHT) nwi_end=(nowildcard_info *)l;
302 else nwi_end=NULL;
303
304 if ((eventout->ROOT->TYPE & TTV_SIG_R)!=0 || (eventout->ROOT->TYPE & TTV_SIG_CT)==TTV_SIG_CT) maxres=INF_FALSESLACK_NOTHZ|INF_FALSESLACK_HZ;
305 else maxres=INF_FALSESLACK_NOTHZ;
306
307 orig_nwi_start=nwi_start;
308 orig_nwi_end=nwi_end;
309 l=1; // start
310 if (nwi_end!=NULL && nwi_start!=NULL)
311 {
312 // on grade la liste la plus courte
313 usew=0;
314 if (nwi_end->nb<nwi_start->nb) nwi_start=nwi_end, l=2;
315 }
316 else
317 {
318 usew=1;
319 if (nwi_start==NULL) nwi_start=nwi_end, l=2;
320 }
321
322 if (nwi_start!=NULL)
323 {
324 chain_list *tab[2];
325 if (usew==0) cl=nwi_start->FALSESLACK_NOWILDCARD;
326 else cl=nwi_start->FALSESLACK_WILDCARD;
327
328 while (cl!=NULL)
329 {
330 pt=(stbfalseslack_list *)cl->DATA;
331 if ((pt->setuphold & type)!=0 && check_goodtype(pt->setuphold,eventout))
332 {
333 if(stb_sameevent(pt->startsig_dir, eventin->TYPE) && stb_sameevent(pt->endsig_dir, eventout->TYPE) &&
334 (startck==NULL || stb_sameevent(pt->startclock_dir, startck->TYPE)) &&
335 (endck==NULL || stb_sameevent(pt->endclock_dir, endck->TYPE)))
336 {
337 if(((l==2 && stb_falseslack_match_name(stbfig->FIG, eventin->ROOT, pt->startsig))
338 || (l==1 && stb_falseslack_match_name(stbfig->FIG, eventout->ROOT,pt->endsig)))
339 && (startck==NULL || stb_falseslack_match_name(stbfig->FIG, startck->ROOT,pt->startclock))
340 && (endck==NULL || stb_falseslack_match_name(stbfig->FIG, endck->ROOT,pt->endclock)))
341 {
342 res|=(pt->endsig_dir & (INF_FALSESLACK_HZ|INF_FALSESLACK_NOTHZ));
343 if ((res & maxres)==maxres) return res ;
344 }
345 }
346 }
347 cl=cl->NEXT;
348 }
349
350 if (usew==0)
351 {
352 if (orig_nwi_start!=NULL) tab[0]=orig_nwi_start->FALSESLACK_WILDCARD; else tab[0]=NULL;
353 if (orig_nwi_end!=NULL) tab[1]=orig_nwi_end->FALSESLACK_WILDCARD; else tab[1]=NULL;
354
355 for (l=1; l<3; l++)
356 {
357 cl=tab[l-1];
358 while (cl!=NULL)
359 {
360 pt=(stbfalseslack_list *)cl->DATA;
361 if ((pt->setuphold & type)!=0 && check_goodtype(pt->setuphold,eventout))
362 {
363 if(stb_sameevent(pt->startsig_dir, eventin->TYPE) && stb_sameevent(pt->endsig_dir, eventout->TYPE) &&
364 (startck==NULL || stb_sameevent(pt->startclock_dir, startck->TYPE)) &&
365 (endck==NULL || stb_sameevent(pt->endclock_dir, endck->TYPE)))
366 {
367 if(((l==2 && stb_falseslack_match_name(stbfig->FIG, eventin->ROOT, pt->startsig))
368 || (l==1 && stb_falseslack_match_name(stbfig->FIG, eventout->ROOT,pt->endsig)))
369 && (startck==NULL || stb_falseslack_match_name(stbfig->FIG, startck->ROOT,pt->startclock))
370 && (endck==NULL || stb_falseslack_match_name(stbfig->FIG, endck->ROOT,pt->endclock)))
371 {
372 res|=(pt->endsig_dir & (INF_FALSESLACK_HZ|INF_FALSESLACK_NOTHZ));
373 if ((res & maxres)==maxres) return res ;
374 }
375 }
376 }
377 cl=cl->NEXT;
378 }
379 }
380 }
381 }
382
383 // GESTION DES WILDCARDS
384 for(pt = fpi->WILDCARDS ; pt != NULL ; pt = pt->NEXT)
385 {
386 if ((pt->setuphold & type)!=0 && check_goodtype(pt->setuphold,eventout))
387 {
388 if(stb_sameevent(pt->startsig_dir, eventin->TYPE) && stb_sameevent(pt->endsig_dir, eventout->TYPE) &&
389 (startck==NULL || stb_sameevent(pt->startclock_dir, startck->TYPE)) &&
390 (endck==NULL || stb_sameevent(pt->endclock_dir, endck->TYPE)))
391 {
392 if(stb_falseslack_match_name(stbfig->FIG, eventin->ROOT, pt->startsig)
393 && stb_falseslack_match_name(stbfig->FIG, eventout->ROOT,pt->endsig)
394 && (startck==NULL || stb_falseslack_match_name(stbfig->FIG, startck->ROOT,pt->startclock))
395 && (endck==NULL || stb_falseslack_match_name(stbfig->FIG, endck->ROOT,pt->endclock)))
396 {
397 res|=(pt->endsig_dir & (INF_FALSESLACK_HZ|INF_FALSESLACK_NOTHZ));
398 if ((res & maxres)==maxres) return res ;
399 }
400 }
401 }
402 }
403
404 return res ;
405 }
406
407 void stb_setfalseslack(stbfig_list *sf, inffig_list *ifl)
408 {
409 chain_list *ch;
410 ptype_list *p;
411 ht *nametosig;
412 NameAllocator NA;
413
414 if (ifl!=NULL && ifl->LOADED.INF_FALSESLACK!=NULL)
415 {
416 nametosig=stb_buildquickaccessht_forfalsepath(sf->FIG, &NA);
417
418 for (ch = ifl->LOADED.INF_FALSESLACK; ch; ch = ch->NEXT)
419 {
420 p = (ptype_list *) ch->DATA;
421 stb_addfalsepath(sf, p, nametosig, &NA);
422 }
423 stb_freeequickaccessht_forfalsepath(nametosig, &NA);
424 DeleteNameAllocator(&NA);
425 }
426 }
427
428 int stb_hasfalseslack(stbfig_list *stbfig, ttvevent_list *eventout)
429 {
430 stbfalseslack_list *pt ;
431 ptype_list *ptype ;
432 falseslack_info *fpi;
433 long l;
434 int res=0, maxres;
435
436 if((ptype = getptype(stbfig->USER,STB_FIG_FALSESLACK)) == NULL) return(0) ;
437
438 fpi=(falseslack_info *)ptype->DATA;
439
440 if ((l=gethtitem(fpi->END_HASH, getkey_forsignal(eventout->ROOT)))!=EMPTYHT) return 1;
441
442 for(pt = fpi->WILDCARDS ; pt != NULL ; pt = pt->NEXT)
443 {
444 if(stb_sameevent(pt->endsig_dir, eventout->TYPE))
445 {
446 if(stb_falseslack_match_name(stbfig->FIG, eventout->ROOT,pt->endsig)) return 1;
447 }
448 }
449
450 return 0;
451 }
452