Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / genius / gen_model_FCL.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : GENIUS v1.00 */
6 /* Fichier : gen_model_FCL.c */
7 /* */
8 /* (c) copyright 1999 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* Auteur(s) : Francois DONNET le : 23/06/1999 */
13 /* */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
17 /* */
18 /****************************************************************************/
19
20 #include <stdio.h>
21 #include <string.h>
22 #include MUT_H
23 #include MLO_H
24 #include API_H
25 #include AVT_H
26 #include "gen_execute_VHDL.h"
27 #include "gen_model_utils.h"
28 #include "gen_model_FCL.h"
29
30
31
32 static lofig_list *FIG=NULL; /*current lofig in construction*/
33 static ptype_list *FOR_ENV=NULL; /* local FOR variables with values */
34
35
36
37 /***************************************************************************/
38 /* change a tree of signals in a list */
39 /***************************************************************************/
40 static inline chain_list *SigTree2chain(tree_list *tree, chain_list *list)
41 {
42 if (!tree) {
43 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 233);
44 //fprintf(stderr,"SigTree2chain: NULL pointer\n");
45 EXIT(1);
46 }
47 switch (TOKEN(tree)) {
48 /* as an ABL this token is a node */
49 case GEN_TOKEN_NODE:
50 return SigTree2chain(tree->DATA,list);
51 break;
52 case ',':
53 list=SigTree2chain(tree->NEXT->NEXT,list); /*not to reverse order*/
54 return SigTree2chain(tree->NEXT,list);
55 break;
56 case GEN_TOKEN_SIGNAL:
57 return SigTree2chain(tree->NEXT,list);
58 break;
59 case GEN_TOKEN_IDENT: case '(':
60 return addchain(list,tree);
61 break;
62 default:
63 Error_Tree("SigTree2chain",tree);
64 EXIT(2); return NULL;
65 }
66 }
67
68
69 /****************************************************************************/
70 /* put in lofigchain of signal the value of its LOCON */
71 /****************************************************************************/
72 static inline void add_lofigchain(locon_list *locon, chain_list *sigchain)
73 {
74 losig_list *sig;
75 ptype_list *p;
76
77
78 if ((locon && !sigchain) || (!locon && sigchain)) {
79 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 234);
80 // fprintf(stderr,"add_lofigchain: parameters discrepancy\n");
81 EXIT(1);
82 }
83
84 if (!locon || !sigchain) return ;
85 else add_lofigchain(locon->NEXT,sigchain->NEXT);
86
87 sig=(losig_list*) sigchain->DATA;
88
89 /* lofigchain*/
90 p=getptype(sig->USER,LOFIGCHAIN);
91 if (!p) {
92 sig->USER=addptype(sig->USER,LOFIGCHAIN,NULL);
93 p=sig->USER;
94 }
95 p->DATA=addchain(p->DATA,locon);
96 }
97
98
99 /****************************************************************************/
100 /* build and return the list of losig in tree put on top of sigchain */
101 /* build also the generic of locon list and losig list returned */
102 /* signal from tree */
103 /* signals are sorted in the same order than in locon list */
104 /****************************************************************************/
105 extern chain_list *Get_Losig_Alliance(locon_list *locon, chain_list *signal,
106 chain_list *sigchain)
107 {
108 losig_list *sig;
109 chain_list *namechain;
110 tree_list *tree;
111 char *signame;
112 char memo_char;
113 long index;
114
115 if ((locon && !signal) || (!locon && signal)) {
116 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 235);
117 // fprintf(stderr,"Get_Losig_Alliance: parameters discrepancy\n");
118 EXIT(1);
119 }
120
121 if (!locon || !signal) return sigchain;
122 else sigchain=Get_Losig_Alliance(locon->NEXT,signal->NEXT,sigchain);
123
124 tree=(tree_list*)signal->DATA;
125 if (!tree) {
126 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 236);
127 // fprintf(stderr,"Get_Losig_Alliance: NULL pointer\n");
128 EXIT(1);
129 }
130
131 /*search signal*/
132 signame=getname(tree);
133 if (TOKEN(tree)=='(') { /*vector*/
134 if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_TO) { /*array*/
135 char *name;
136 int lim=Eval_Exp_VHDL(
137 (tree->NEXT->NEXT->DATA)->NEXT/*low bound*/,FOR_ENV);
138 long i;
139 for (i=Eval_Exp_VHDL(
140 (tree->NEXT->NEXT->DATA)->NEXT->NEXT/*high bound*/,FOR_ENV);
141 i>=lim; i--) {
142 memo_char=SEPAR; /* MBK variable it is for concatenation*/
143 SEPAR=' ';/*nameindex() must be compatible with vectorradical() */
144 name=nameindex(signame,i);
145 SEPAR=memo_char; /* put last value in MBK environment */
146 index=INDEX_START;
147 /*search sig*/
148 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) {
149 for (namechain=sig->NAMECHAIN;
150 namechain;
151 namechain=namechain->NEXT) {
152 if (((char*)namechain->DATA)==name) {break;}
153 }
154 if (namechain) break;
155 index++;
156 }
157 if (!sig) {
158 chain_list *namechain;
159 namechain=addchain(NULL,name);
160 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
161 sig=FIG->LOSIG;
162 }
163 sigchain=addchain(sigchain,sig);
164 }
165 }
166 else if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_DOWNTO) { /*array*/
167 char *name;
168 int lim=Eval_Exp_VHDL(
169 (tree->NEXT->NEXT->DATA)->NEXT/*high bound*/,FOR_ENV);
170 long i;
171 for (i=Eval_Exp_VHDL(
172 (tree->NEXT->NEXT->DATA)->NEXT->NEXT/*low bound*/,FOR_ENV);
173 i<=lim; i++) {
174 memo_char=SEPAR; /* MBK variable it is for concatenation*/
175 SEPAR=' ';/*nameindex() must be compatible with vectorradical() */
176 name=nameindex(signame,i);
177 SEPAR=memo_char; /* put last value in MBK environment */
178 index=INDEX_START;
179 /*search sig*/
180 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) {
181 for (namechain=sig->NAMECHAIN;
182 namechain;
183 namechain=namechain->NEXT) {
184 if (((char*)namechain->DATA)==name) {break;}
185 }
186 if (namechain) break;
187 index++;
188 }
189 if (!sig) {
190 chain_list *namechain;
191 namechain=addchain(NULL,name);
192 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
193 sig=FIG->LOSIG;
194 }
195 sigchain=addchain(sigchain,sig);
196 }
197 }
198
199 else { /*bit vector*/
200 long bitnum=Eval_Exp_VHDL(tree->NEXT->NEXT->DATA,FOR_ENV);
201 char *name;
202 memo_char=SEPAR; /* MBK variable it is for concatenation*/
203 SEPAR=' '; /* nameindex() must be compatible with vectorradical() */
204 name=nameindex(signame,bitnum);
205 SEPAR=memo_char; /* put last value in MBK environment */
206 index=INDEX_START;
207 /*search sig*/
208 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) {
209 for (namechain=sig->NAMECHAIN; namechain; namechain=namechain->NEXT) {
210 if (((char*)namechain->DATA)==name) {break;}
211 }
212 if (namechain) break;
213 index++;
214 }
215 if (!sig) {
216 chain_list *namechain;
217 namechain=addchain(NULL,name);
218 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
219 sig=FIG->LOSIG;
220 }
221 sigchain=addchain(sigchain,sig);
222 }
223 }
224
225 else { /* a bit */
226 index=INDEX_START;
227 /*search sig*/
228 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) {
229 for (namechain=sig->NAMECHAIN; namechain; namechain=namechain->NEXT) {
230 if (((char*)namechain->DATA)==signame) {break;}
231 }
232 if (namechain) break;
233 index++;
234 }
235 if (!sig) {
236 chain_list *namechain;
237 namechain=addchain(NULL,signame);
238 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
239 sig=FIG->LOSIG;
240 }
241 sigchain=addchain(sigchain,sig);
242 }
243
244 return sigchain;
245 }
246
247
248
249 /****************************************************************************/
250 /* return the abl generic function of all created instances in fig */
251 /****************************************************************************/
252 extern tree_list *Get_Loins_Alliance(tree_list *tree)
253 {
254 tree_list *ret,*ret2;
255 ptype_list *q;
256 lofig_list *ins;
257 chain_list *sigchain,*signals;
258 char *modelname,*insname;
259 int lineno=0,limit,i; /*hidden in macro PUT_BIN */
260 char memo_char;
261 char* file;
262
263 if (!tree) {
264 return NULL;
265 /* fprintf(stderr,"Get_Loins_Alliance: NULL pointer\n");
266 EXIT(1);*/
267 }
268
269 switch (TOKEN(tree)) {
270 /*node*/
271 case GEN_TOKEN_NODE:
272 return Get_Loins_Alliance(tree->DATA);
273 break;
274 /*instance list connexions*/
275 case ';':
276 ret=Get_Loins_Alliance(tree->NEXT);
277 ret2=Get_Loins_Alliance(tree->NEXT->NEXT);
278 lineno=LINE(tree);
279 file=FILE_NAME(tree);
280 if (ret) {
281 if (ret2) return PUT_BIN(';',ret,ret2);
282 else return ret;
283 }
284 else return ret2;
285 break;
286 case GEN_TOKEN_FOR:
287 limit=Eval_Exp_VHDL(tree->NEXT->NEXT->NEXT,FOR_ENV);
288 ret=NULL;
289 lineno=LINE(tree);
290 file=FILE_NAME(tree);
291 FOR_ENV=addptype(FOR_ENV,0,tree->NEXT);
292 for (i=Eval_Exp_VHDL(tree->NEXT->NEXT,FOR_ENV); i<=limit; i++) {
293 FOR_ENV->TYPE=i;
294 ret2=Get_Loins_Alliance(tree->NEXT->NEXT->NEXT->NEXT);
295 if (ret) {
296 if (ret2) ret=PUT_BIN(';',ret,ret2);
297 }
298 else ret=ret2;
299 }
300 q=FOR_ENV;
301 FOR_ENV=FOR_ENV->NEXT;
302 q->NEXT=NULL;
303 freeptype (q);
304 return ret;
305 break;
306 case GEN_TOKEN_IF:
307 i=Eval_Exp_VHDL(tree->NEXT,FOR_ENV);
308 if (i) return Get_Loins_Alliance(tree->NEXT->NEXT);
309 else return NULL;
310 break;
311 case GEN_TOKEN_MAP:
312 insname=getname(tree->NEXT);
313 /*if we are in a loop put an index */
314 memo_char=SEPAR; /* MBK variable it is for concatenation*/
315 SEPAR='_'; /* compatible FCL */
316 if (FOR_ENV) insname=nameindex(insname,FOR_ENV->TYPE);
317 SEPAR=memo_char; /* put last value in MBK environment */
318 modelname=getname_of(tree->NEXT);
319 ins=getlofig(modelname,'P'); /* 'P' (partial) for only interface */
320 if (!ins) {
321 avt_errmsg(GNS_ERRMSG, "161", AVT_FATAL, modelname);
322 // fprintf(stderr,"Get_Loins: no model %s found\n",modelname);
323 EXIT(1);
324 }
325 signals=SigTree2chain(tree->NEXT->NEXT,NULL);
326 sigchain=Get_Losig_Alliance(ins->LOCON,signals,NULL);
327 FIG->LOINS=addloins(FIG,insname,ins,sigchain);
328 add_lofigchain(FIG->LOINS->LOCON,sigchain);
329 freechain(sigchain);
330 freechain(signals);
331 lineno=LINE(tree);
332 file=FILE_NAME(tree);
333 return PUT_ATO(GEN_TOKEN_LOINS,FIG->LOINS);
334 break;
335 default:
336 Error_Tree("Get_Loins_Alliance",tree);
337 EXIT(1); return NULL;
338 }
339 }
340
341
342 /****************************************************************************/
343 /* build all the locons of and its signals from tree pointing on port */
344 /****************************************************************************/
345 extern void Get_Signals_Alliance(tree_list *tree)
346 {
347 chain_list *namechain;
348 int index;
349 char *signame;
350 losig_list *sig;
351 char memo_char;
352
353 if (!tree) {
354 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 237);
355 // fprintf(stderr,"Get_Signals_Alliance: NULL pointer\n");
356 EXIT(1);
357 }
358 switch (TOKEN(tree)) {
359 /*node*/
360 case GEN_TOKEN_NODE:
361 Get_Signals_Alliance(tree->DATA);
362 break;
363 case ';':
364 Get_Signals_Alliance(tree->NEXT->NEXT);
365 Get_Signals_Alliance(tree->NEXT);
366 break;
367 case GEN_TOKEN_COMPONENT:
368 /*nothing to do*/
369 break;
370 case GEN_TOKEN_INOUT: case GEN_TOKEN_SIGNAL:
371 Get_Signals_Alliance(tree->NEXT);
372 break;
373 case GEN_TOKEN_IDENT: case '(':
374 signame=getname(tree);
375 /* search index number */
376 index=INDEX_START;
377 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) index++;
378 if (TOKEN(tree)=='(') { /* vector */
379 if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_TO) {
380 long i;
381 int lim=Eval_Exp_VHDL(tree->NEXT->NEXT->DATA->NEXT/*low bound*/,FOR_ENV);
382 for(i=
383 Eval_Exp_VHDL(tree->NEXT->NEXT->DATA->NEXT->NEXT/*high bound*/,FOR_ENV);
384 i>=lim; i--) {
385 char *name;
386 memo_char=SEPAR; /* MBK variable it is for concatenation*/
387 SEPAR=' '; /* nameindex() must be compatible with vectorradical() */
388 name=nameindex(signame,i);
389 SEPAR=memo_char; /* put last value in MBK environment */
390 namechain=addchain(NULL,name);
391 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
392 index++;
393 }
394 }
395 else if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_DOWNTO) {
396 long i;
397 int lim=Eval_Exp_VHDL(tree->NEXT->NEXT->DATA->NEXT/*high bound*/,FOR_ENV);
398 for(i=
399 Eval_Exp_VHDL(tree->NEXT->NEXT->DATA->NEXT->NEXT/*low bound*/,FOR_ENV);
400 i<=lim; i++) {
401 char *name;
402 memo_char=SEPAR; /* MBK variable it is for concatenation*/
403 SEPAR=' '; /* nameindex() must be compatible with vectorradical() */
404 name=nameindex(signame,i);
405 SEPAR=memo_char; /* put last value in MBK environment */
406 namechain=addchain(NULL,name);
407 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
408 index++;
409 }
410 }
411 else {
412 Error_Tree("Get_Signals_Alliance",tree->NEXT->NEXT->DATA);
413 EXIT(2);
414 }
415 }
416 else { /* one bit */
417 namechain=addchain(NULL,signame);
418 FIG->LOSIG=addlosig(FIG,index,namechain,INTERNAL);
419 }
420 break;
421 default:
422 Error_Tree("Get_Signals_Alliance",tree);
423 EXIT(1);
424 }
425 }
426
427
428 /****************************************************************************/
429 /* build one locon of fig (and also its external signal) */
430 /****************************************************************************/
431 extern void Get_Locon_Alliance(int dir, tree_list *tree)
432 {
433 char *conname;
434 chain_list *namechain;
435 losig_list *sig;
436 long index;
437 char memo_char;
438
439 if (!tree) {
440 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 238);
441 // fprintf(stderr,"Get_Locon_Alliance: NULL pointer\n");
442 EXIT(1);
443 }
444 switch (TOKEN(tree)) {
445 /*node */
446 case GEN_TOKEN_NODE:
447 Get_Locon_Alliance(dir,tree->DATA);
448 break;
449 case '(': case GEN_TOKEN_IDENT:
450 conname=getname(tree);
451 /* search new index */
452 index=INDEX_START;
453 for (sig=FIG->LOSIG; sig; sig=sig->NEXT) index++;
454 if (TOKEN(tree)=='(') {/*order of bit vector is very important for GENIUS*/
455 if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_TO) {
456 long i; /*help for verif in Mark_Loins() */
457 int lim;
458 tree=tree->NEXT->NEXT->DATA; /* TOKEN(tree)=GEN_TOKEN_TO */
459 lim=Eval_Exp_VHDL(tree->NEXT/*low bound*/,FOR_ENV);
460 memo_char=SEPAR; /* MBK variable it is for concatenation*/
461 SEPAR=' '; /* nameindex() must be compatible with vectorradical() */
462
463 for (i=Eval_Exp_VHDL(tree->NEXT->NEXT/*high bound*/,FOR_ENV); i>=lim; i--) {
464 char *name;
465 name=nameindex(conname,i);
466 namechain=addchain(NULL,name);
467 FIG->LOSIG=addlosig(FIG,index,namechain,EXTERNAL);/*WARN:no more capa*/
468 /*default addlocon set EXTERNAL*/
469 FIG->LOCON=addlocon(FIG,name,FIG->LOSIG,dir);
470 /*used by GENIUS*/
471 FIG->LOCON->USER=addptype(FIG->LOCON->USER,GENCONCHAIN,NULL);
472 FIG->LOCON->USER->DATA=addgenconchain(NULL, Duplicate_Tree(tree),
473 FIG->LOSIG, Duplicate_Tree(tree));
474 /*used by FCL*/
475 FIG->LOSIG->USER=addptype(FIG->LOSIG->USER,LOFIGCHAIN,NULL);
476 FIG->LOSIG->USER->DATA=addchain(FIG->LOSIG->USER->DATA,FIG->LOCON);
477 index++;
478 }
479 SEPAR=memo_char; /* put last value in MBK environment */
480 }
481 else if (TOKEN(tree->NEXT->NEXT->DATA)==GEN_TOKEN_DOWNTO) {
482 long i; /*help for verif in Mark_Loins() */
483 int lim;
484 tree=tree->NEXT->NEXT->DATA; /* TOKEN(tree)=GEN_TOKEN_DOWNTO */
485 lim=Eval_Exp_VHDL(tree->NEXT/*high bound*/,FOR_ENV);
486 memo_char=SEPAR; /* MBK variable it is for concatenation*/
487 SEPAR=' '; /* nameindex() must be compatible with vectorradical() */
488
489 for (i=Eval_Exp_VHDL(tree->NEXT->NEXT/*low bound*/,FOR_ENV); i<=lim; i++) {
490 char *name;
491 name=nameindex(conname,i);
492 namechain=addchain(NULL,name);
493 FIG->LOSIG=addlosig(FIG,index,namechain,EXTERNAL);/*WARN:no more capa*/
494 /*default addlocon set EXTERNAL*/
495 FIG->LOCON=addlocon(FIG,name,FIG->LOSIG,dir);
496 /*used by GENIUS*/
497 FIG->LOCON->USER=addptype(FIG->LOCON->USER,GENCONCHAIN,NULL);
498 FIG->LOCON->USER->DATA=addgenconchain(NULL, Duplicate_Tree(tree),
499 FIG->LOSIG, Duplicate_Tree(tree));
500 /*used by FCL*/
501 FIG->LOSIG->USER=addptype(FIG->LOSIG->USER,LOFIGCHAIN,NULL);
502 FIG->LOSIG->USER->DATA=addchain(FIG->LOSIG->USER->DATA,FIG->LOCON);
503 index++;
504 }
505
506 SEPAR=memo_char; /* put last value in MBK environment */
507 }
508 else {
509 Error_Tree("Get_Locon_Alliance",tree->NEXT->NEXT->DATA);
510 EXIT(2);
511 }}
512 else {
513 int lineno=LINE(tree);
514 char* file=FILE_NAME(tree);
515 namechain=addchain(NULL,conname);
516 FIG->LOSIG=addlosig(FIG,index,namechain,EXTERNAL); /*WARN:no more capa*/
517 /*default addlocon set EXTERNAL*/
518 FIG->LOCON=addlocon(FIG,conname,FIG->LOSIG,dir);
519 /*used by GENIUS*/
520 FIG->LOCON->USER=addptype(FIG->LOCON->USER,GENCONCHAIN,NULL);
521 FIG->LOCON->USER->DATA=addgenconchain(NULL, PUT_ATO(GEN_TOKEN_DIGIT,-1),
522 FIG->LOSIG, PUT_ATO(GEN_TOKEN_DIGIT,-1));
523 /*used by FCL*/
524 FIG->LOSIG->USER=addptype(FIG->LOSIG->USER,LOFIGCHAIN,NULL);
525 FIG->LOSIG->USER->DATA=addchain(FIG->LOSIG->USER->DATA,FIG->LOCON);
526 }
527 break;
528 default:
529 Error_Tree("Get_Locon_Alliance",tree);
530 EXIT(1);
531 }
532 }
533
534
535 /****************************************************************************/
536 /* build all the locons of and its signals from tree pointing on port */
537 /****************************************************************************/
538 extern void Get_Port_Alliance(tree_list *tree)
539 {
540 if (!tree) {
541 avt_errmsg(GNS_ERRMSG, "004", AVT_FATAL, 239);
542 // fprintf(stderr,"Get_Port_Alliance: NULL pointer\n");
543 EXIT(1);
544 }
545 switch (TOKEN(tree)) {
546 /*node*/
547 case GEN_TOKEN_NODE:
548 Get_Port_Alliance(tree->DATA);
549 break;
550 case GEN_TOKEN_PORT:
551 Get_Port_Alliance(tree->NEXT);
552 break;
553 case ',': /*it's a list of different connectors*/
554 Get_Port_Alliance(tree->NEXT->NEXT); /*to avoid reversion of addchain*/
555 Get_Port_Alliance(tree->NEXT);
556 break;
557 case GEN_TOKEN_SIGNAL:
558 Get_Port_Alliance(tree->NEXT);
559 break;
560 case GEN_TOKEN_IN:
561 Get_Locon_Alliance(IN,tree->NEXT);
562 break;
563 case GEN_TOKEN_OUT:
564 Get_Locon_Alliance(OUT,tree->NEXT);
565 break;
566 case GEN_TOKEN_INOUT:
567 Get_Locon_Alliance(INOUT,tree->NEXT);
568 break;
569 case GEN_TOKEN_TRISTATE:
570 Get_Locon_Alliance(TRISTATE,tree->NEXT);
571 break;
572 case GEN_TOKEN_TRANSCV:
573 Get_Locon_Alliance(TRANSCV,tree->NEXT);
574 break;
575 default:
576 Error_Tree("Get_Port_Alliance",tree);
577 EXIT(1);
578 }
579 }
580
581
582 /****************************************************************************/
583 /* put environment to good values */
584 /****************************************************************************/
585 extern void Env_Alliance(lofig_list *lofig)
586 {
587 FIG=lofig;
588 }
589
590