2 /****************************************************************************/
4 /* Chaine de CAO & VLSI Alliance */
6 /* Produit : GENIUS v1.00 */
7 /* Fichier : gen_verif_PortMap.c */
9 /* Auteur(s) : Francois DONNET le : 10/06/1999 */
11 /* (c) copyright 1999 Laboratoire MASI equipe CAO & VLSI */
12 /* Tous droits reserves */
13 /* Support : e-mail alliance-support@asim.lip6.fr */
16 /****************************************************************************/
26 #include "gen_verif_utils.h"
27 #include "gen_verif_exp_VHDL.h"
28 #include "gen_verif_vector.h"
29 #include "gen_verif_exclude.h"
30 #include "gen_verif_PortMap.h"
35 /***************************************************************************/
36 /* change a tree of generic variables in a list of ptypeput on top of var */
37 /***************************************************************************/
38 extern ptype_list
*GenTree2chain(tree_list
*tree
, ptype_list
*var
)
41 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 192);
42 // fprintf(stderr,"GenTree2chain: NULL pointer\n");
45 switch (TOKEN(tree
)) {
46 /* as an ABL this token is a node */
48 return GenTree2chain(tree
->DATA
,var
);
50 case GEN_TOKEN_GENERIC
:
51 return GenTree2chain(tree
->NEXT
,var
);
57 var
=GenTree2chain(tree
->NEXT
->NEXT
,var
); /*not to reverse order*/
58 return GenTree2chain(tree
->NEXT
,var
);
60 case GEN_TOKEN_VARIABLE
: case GEN_TOKEN_INTEGER
:
61 return GenTree2chain(tree
->NEXT
,var
);
64 return addptype(var
,RAND_BYTE
,tree
);
67 Error_Tree("GenTree2chain",tree
);
73 /***************************************************************************/
74 /* Verify if port map of instance matches with component model and */
75 /* entity signals Sig and generic variables env */
76 /***************************************************************************/
77 static inline tree_list
*Compare_PortMap(tree_list
*instance
,
78 tree_list
*model
, ptype_list
*env_inst
,
79 ptype_list
*env_model
, chain_list
*Sig
)
81 int /*array_sig,array_mod,*/type
;
84 if (!instance
|| !model
) {
85 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 193);
86 // fprintf(stderr,"Compare_PortMap: NULL pointer\n");
89 switch (TOKEN(instance
)) {
90 /* as an ABL this token is a node */
92 if (TOKEN(model
)!=GEN_TOKEN_NODE
) {
93 Error_Tree("Compare_PortMap",model
);
96 Compare_PortMap(instance
->DATA
,model
->DATA
,env_inst
,env_model
,Sig
);
100 if (TOKEN(model
)!=',') {
101 Error_Tree("Compare_PortMap",model
);
104 /* no use to catch result because here it doesn't change*/
105 Compare_PortMap(instance
->NEXT
,model
->NEXT
,env_inst
,env_model
,Sig
);
106 Compare_PortMap(instance
->NEXT
->NEXT
,model
->NEXT
->NEXT
,env_inst
,env_model
,Sig
);
110 /* PORT MAP(sig1,sig2,...,sigN) */
111 case GEN_TOKEN_SIGNAL
:
112 if (TOKEN(model
)!=GEN_TOKEN_SIGNAL
) {
113 Error_Tree("Compare_PortMap",model
);
116 /*result could change only here*/
117 instance
->NEXT
=Compare_PortMap(instance
->NEXT
,model
->NEXT
,env_inst
,env_model
,Sig
);
121 case GEN_TOKEN_IDENT
: case '(':
122 sig
=fetch_inlist(instance
,Sig
);/*TOKEN(sig)=IN,OUT,INOUT...*/
123 if (!sig
) return instance
;
126 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 194);
127 // fprintf(stderr,"Compare_PortMap: NULL pointer\n");
130 sig
=sig
->NEXT
->DATA
;/*TOKEN(sig)=IDENT or '('-->vector */
132 /*compare size of vectors*/
133 if (TOKEN(instance
)=='(' && Bound_Vector(instance
,sig
,env_inst
)) {
134 avt_errmsg(GNS_ERRMSG
, "124", AVT_ERROR
, FILE_NAME(instance
),LINE(instance
),getname(instance
),LINE(sig
));
135 /* fprintf(stderr,"%s:%d: array of signal '%s' out of bounds with model line %d\n",
136 FILE_NAME(instance),LINE(instance),getname(instance),LINE(sig));*/
139 else if (TOKEN(instance
)==GEN_TOKEN_IDENT
&& TOKEN(sig
)=='(') { /*signal unsized*/
140 int lineno
=LINE(instance
);
141 char *file
=FILE_NAME(instance
);
142 tree_list
*size
=Duplicate_Tree(sig
->NEXT
->NEXT
);/*take sizeof model*/
143 instance
=PUT_BIN('(',instance
,size
);
146 array_mod=Verif_Vector(model->NEXT,env_model);
147 array_sig=Size_Vector(instance,env_inst);
149 if (array_sig!=array_mod) {
150 if (Nb_Vector_Vars()>1)
152 fprintf(stderr,"%s:%d: size of signal '%s' doesn't match with size of '%s' (%d!=%d)\n",
153 FILE_NAME(instance),LINE(instance),getname(instance),getname(model->NEXT),array_mod,array_sig);
158 Compare_Type(model
,instance
,type
);
161 Error_Tree("Compare_PortMap",instance
);
162 EXIT(2); return NULL
;
167 /***************************************************************************/
168 /* return the signal located at the right side of equipotential matching */
169 /* the connector model, env is list of variables */
170 /* return NULL if not found or error in size of model */
171 /***************************************************************************/
172 static inline tree_list
*Seek_Equi(tree_list
*tree
, tree_list
*model
,
173 ptype_list
*env
, chain_list
*Sig
)
177 if (!tree
|| !model
) {
178 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 195);
179 // fprintf(stderr,"Seek_Equi: NULL pointer\n");
182 switch (TOKEN(tree
)) {
183 /* as an ABL this token is a node */
185 return Seek_Equi(tree
->DATA
,model
,env
,Sig
);
188 con
=Seek_Equi(tree
->NEXT
,model
,env
,Sig
);
189 if (!con
) con
=Seek_Equi(tree
->NEXT
->NEXT
,model
,env
,Sig
);
193 con
=Seek_Equi(tree
->NEXT
,model
,env
,Sig
); /*TOKEN(con)=IDENT or '('*/
195 if (Compare_Vector(model
/*TOKEN=IDENT or '('*/,con
,env
,env
)) {
196 avt_errmsg(GNS_ERRMSG
, "125", AVT_ERROR
, FILE_NAME(tree
),LINE(tree
),getname(model
),LINE(model
));
197 /* fprintf(stderr,"%s:%d: array doesn't match for '%s' (line model %d)\n",
198 FILE_NAME(tree),LINE(tree),getname(model),LINE(model));*/
202 /*if direction are inverted in port map and component-->invert signal*/
203 else if (TOKEN(model
)=='(' && TOKEN(con
)=='('
204 && ((TOKEN(model
->NEXT
->NEXT
->DATA
)==GEN_TOKEN_TO
205 && TOKEN(con
->NEXT
->NEXT
->DATA
)==GEN_TOKEN_DOWNTO
)
206 || (TOKEN(model
->NEXT
->NEXT
->DATA
)==GEN_TOKEN_DOWNTO
207 && TOKEN(con
->NEXT
->NEXT
->DATA
)==GEN_TOKEN_TO
))) {
209 con
=tree
->NEXT
->NEXT
->DATA
; /*TOKEN(con)=IDENT or '('*/
210 if (TOKEN(con
/*catch signal*/)==GEN_TOKEN_IDENT
) {
212 char *file
=FILE_NAME(con
); /*for PUT_BIN macro*/
213 int lineno
=LINE(con
); /*for PUT_BIN macro*/
214 sig
=fetch_inlist(con
/*IDENT or '('*/,Sig
);
215 /*TOKEN(sig)=IN,OUT,INOUT...*/
216 if (!sig
|| !sig
->NEXT
) {
217 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 196);
218 // fprintf(stderr,"Seek_Equi: NULL pointer\n");
221 sig
=sig
->NEXT
->DATA
; /*TOKEN(sig)=IDENT or '('-->vector */
222 if (TOKEN(sig
)=='(') /*put an array*/
223 tree
->NEXT
->NEXT
->DATA
=PUT_BIN('(',tree
->NEXT
->NEXT
->DATA
,
224 Duplicate_Tree(sig
->NEXT
->NEXT
));
227 con
=tree
->NEXT
->NEXT
->DATA
; /*TOKEN(con)=IDENT or '('*/
228 /*there is already an array*/
229 if (TOKEN(con
)=='(') {
231 con
=con
->NEXT
->NEXT
->DATA
; /*TOKEN(con)=GEN_TOKEN_TO or GEN_TOKEN_DOWNTO*/
233 if (TOKEN(con
)==GEN_TOKEN_TO
) TOKEN(con
)=GEN_TOKEN_DOWNTO
;
234 else if (TOKEN(con
)==GEN_TOKEN_DOWNTO
) TOKEN(con
)=GEN_TOKEN_TO
;
236 Error_Tree("Seek_Equi",con
);
239 save
=con
->NEXT
->DATA
; /*expression*/
240 con
->NEXT
->DATA
=con
->NEXT
->NEXT
->DATA
; /*expression*/
241 con
->NEXT
->NEXT
->DATA
=save
; /*expression*/
243 /*there is no array still*/
244 else if (TOKEN(con
)!=GEN_TOKEN_IDENT
) {
245 Error_Tree("Seek_Equi",con
);
249 return tree
->NEXT
->NEXT
->DATA
; /*we are interested in signals*/
254 con
=Seek_Equi(tree
->NEXT
,model
,env
,Sig
); /*TOKEN(con)=IDENT*/
255 if (con
) return tree
;
257 case GEN_TOKEN_IDENT
:
258 if (getname(tree
)==getname(model
)) return tree
;
262 Error_Tree("Seek_Equi",tree
);
263 EXIT(2); return NULL
;
269 /***************************************************************************/
270 /* Sort the equipotentials of instance in order of model */
271 /* env contains the list of generic variables */
272 /***************************************************************************/
273 static inline tree_list
*Sort_Equi(tree_list
*instance
, tree_list
*model
,
274 ptype_list
*env
, chain_list
*Sig
)
278 tree_list
*res1
,*res2
,*found
;
280 if (!instance
|| !model
) {
281 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 197);
282 // fprintf(stderr,"Sort_Equi: NULL pointer\n");
285 switch (TOKEN(model
)) {
286 /* as an ABL this token is a node */
288 return Sort_Equi(instance
,model
->DATA
,env
,Sig
);
291 res1
=Sort_Equi(instance
,model
->NEXT
,env
,Sig
);
292 res2
=Sort_Equi(instance
,model
->NEXT
->NEXT
,env
,Sig
);
293 lineno
=LINE(res1
);/* used in PUT_BIN()*/
294 file
=FILE_NAME(res1
);
295 return PUT_BIN(',',res1
,res2
);
297 case GEN_TOKEN_SIGNAL
:
298 found
=Seek_Equi(instance
,model
->NEXT
->DATA
->NEXT
->DATA
/*TOKEN=IDENT or '('*/,env
,Sig
);
300 avt_errmsg(GNS_ERRMSG
, "126", AVT_ERROR
, FILE_NAME(instance
),LINE(instance
),getname(model
->NEXT
));
301 /* fprintf(stderr,"%s:%d: connector '%s' is missing in left side of instance\n",
302 FILE_NAME(instance),LINE(instance),getname(model->NEXT));*/
304 return Duplicate_Tree(model
);
306 lineno
=LINE(found
);/* used in PUT_UNI()*/
307 file
=FILE_NAME(found
);
308 return PUT_UNI(GEN_TOKEN_SIGNAL
,Duplicate_Tree(found
));
311 Error_Tree("Sort_Equi",model
);
312 EXIT(2); return NULL
;
317 /***************************************************************************/
318 /* Compare the number of argument between instance and model */
319 /* return 1 if different else return 0 */
320 /***************************************************************************/
321 static inline int Compare_NumArgs(tree_list
*instance
, tree_list
*model
)
323 if (!instance
|| !model
) {
324 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 198);
325 // fprintf(stderr,"Compare_NumArgs: NULL pointer\n");
328 switch (TOKEN(instance
)) {
329 /* as an ABL this token is a node */
331 if (TOKEN(model
)!=GEN_TOKEN_NODE
) {
332 Error_Tree("Compare_NumArgs",model
);
335 return Compare_NumArgs(instance
->DATA
,model
->DATA
);
338 if (TOKEN(model
)!=',') {
339 avt_errmsg(GNS_ERRMSG
, "127", AVT_ERROR
, FILE_NAME(instance
),LINE(instance
),LINE(model
));
340 /* fprintf(stderr,"%s:%d: too many connections in Port Map. Component line %d\n",
341 FILE_NAME(instance),LINE(instance),LINE(model));*/
345 if (Compare_NumArgs(instance
->NEXT
,model
->NEXT
)) return 1;
346 else return Compare_NumArgs(instance
->NEXT
->NEXT
,model
->NEXT
->NEXT
);
349 /* PORT MAP(sig1,sig2,...,sigN) or PORT MAP(con1=>sig1,...,conN=>sigN) */
350 case GEN_TOKEN_SIGNAL
: case GEN_TOKEN_EQUI
:
351 if (TOKEN(model
)==',') {
352 avt_errmsg(GNS_ERRMSG
, "128", AVT_ERROR
, FILE_NAME(instance
),LINE(instance
),LINE(model
));
353 /* fprintf(stderr,"%s:%d: not enough connections in Port Map. Component line %d\n",
354 FILE_NAME(instance),LINE(instance),LINE(model));*/
361 Error_Tree("Compare_NumArgs",instance
);
366 /***************************************************************************/
367 /* return 1 if tree contains an equi else return 0 */
368 /***************************************************************************/
369 static inline int Detect_Equi(tree_list
*tree
)
372 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 199);
373 // fprintf(stderr,"Detect_Equi: NULL pointer\n");
376 switch (TOKEN(tree
)) {
377 /* as an ABL this token is a node */
379 return Detect_Equi(tree
->DATA
);
382 return Detect_Equi(tree
->NEXT
);
384 case GEN_TOKEN_SIGNAL
:
391 Error_Tree("Detect_Equi",tree
);
397 /***************************************************************************/
398 /* Give real dimension to signal unsized */
399 /***************************************************************************/
400 static inline tree_list
* Give_Dimension(tree_list
*tree
,chain_list
*Sig
)
405 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 200);
406 // fprintf(stderr,"Give_Dimension: NULL pointer\n");
409 switch (TOKEN(tree
)) {
410 /* as an ABL this token is a node */
412 tree
->DATA
=Give_Dimension(tree
->DATA
,Sig
);
416 Give_Dimension(tree
->NEXT
,Sig
);
417 Give_Dimension(tree
->NEXT
->NEXT
,Sig
);
420 case GEN_TOKEN_SIGNAL
:
421 Give_Dimension(tree
->NEXT
,Sig
);
425 Give_Dimension(tree
->NEXT
->NEXT
,Sig
);
432 case GEN_TOKEN_IDENT
:
433 ret
=fetch_inlist(tree
, Sig
); /* TOKEN(ret)=SIGNAL */
435 ret
=ret
->NEXT
->DATA
; /* TOKEN(ret)='(' or TOKEN(ret)=IDENT */
436 if (TOKEN(ret
)=='(') {
437 ret
=Duplicate_Tree(ret
);
445 Error_Tree("Give_Dimension",tree
);
446 EXIT(2); return NULL
;
451 /***************************************************************************/
452 /* Verify that all instances of tree match with components Comp and generic*/
453 /* variables and signals Sig */
454 /* result put on top of Ins */
455 /***************************************************************************/
456 extern chain_list
*Verif_Instance(tree
,Sig
,env
,Comp
,Ins
)
459 chain_list
*Sig
,*Comp
,*Ins
;
462 chain_list
*Ins2
; /*garbage just to free mem*/
463 tree_list
*component
,*port
;
464 ptype_list
*env_component
,*p
,*q
;
468 /* fprintf(stderr,"Verif_Instance: NULL pointer\n");
472 switch (TOKEN(tree
)) {
473 /* as an ABL this token is a node */
475 return Verif_Instance(tree
->DATA
,Sig
,env
,Comp
,Ins
);
477 case GEN_TOKEN_EXCLUDE
:
478 Ins
= Verif_Instance(tree
->NEXT
,Sig
,env
,Comp
,Ins
);
482 Ins
=Verif_Instance(tree
->NEXT
,Sig
,env
,Comp
,Ins
);
483 return Verif_Instance(tree
->NEXT
->NEXT
,Sig
,env
,Comp
,Ins
);
486 return Verif_Instance(tree
->NEXT
,Sig
,env
,Comp
,Ins
);
488 case GEN_TOKEN_IDENT
:
489 return put_inlist(tree
,Ins
);
492 Ins
=Verif_Instance(tree
->NEXT
,Sig
,env
,Comp
,Ins
);
494 /*to alert if 2 times the same name is used*/
495 if ((ope1
=Is_Exclude(getname(tree
->NEXT
)))) {
496 /*copy MAP and a NODE*/
497 tree_list
*map
=addtree(FILE_NAME(tree
),LINE(tree
),GEN_TOKEN_MAP
,NULL
,tree
->NEXT
);
498 tree_list
*node
=addtree(FILE_NAME(tree
),LINE(tree
),GEN_TOKEN_NODE
,map
,NULL
);
499 /*scratch and insertion of exclude in tree*/
501 tree
->TOKEN
=GEN_TOKEN_EXCLUDE
;
504 /*we were at MAP level*/
509 component
=fetch_inlist(getident_of(tree
->NEXT
),Comp
);/*TOKEN(component)=NODE*/
511 if (!component
) return Ins
;
512 /* test for BUG!!! */
513 if (!component
->NEXT
|| !component
->NEXT
->NEXT
||
514 !component
->NEXT
->NEXT
->DATA
) {
515 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 201);
516 // fprintf(stderr,"Verif_Instance: NULL pointer in component list\n");
519 port
=component
->NEXT
->NEXT
->DATA
;
520 if (TOKEN(port
)!=GEN_TOKEN_PORT
) {
521 Error_Tree("Verif_Instance",port
);
525 if (Compare_NumArgs(tree
->NEXT
->NEXT
,port
->NEXT
)) return Ins
;
526 /*no use to continue because number of arguments are different*/
527 env_component
=GenTree2chain(component
->NEXT
,NULL
);
528 /* to accord values with global environment */
529 for (q
=env_component
;q
;q
=q
->NEXT
) {
530 char *name
=getname(q
->DATA
);
531 for (p
=env
;p
;p
=p
->NEXT
) if (getname(p
->DATA
)==name
) break;
532 if (p
) q
->TYPE
=p
->TYPE
;
534 /* give a size to signal vector without */
535 Give_Dimension(tree
->NEXT
->NEXT
,Sig
);
536 if (Detect_Equi(tree
->NEXT
->NEXT
)) {
537 /* PORT MAP(con3=>sig3,...,con1=>sig1) ---> PORT MAP(sig1,sig2,...,sigN) */
539 res
=Sort_Equi(tree
->NEXT
->NEXT
,port
->NEXT
,env_component
,Sig
);
540 Free_Tree(tree
->NEXT
->NEXT
->DATA
);
541 tree
->NEXT
->NEXT
->DATA
=res
;
543 if (error
==Get_Error()) {
544 Compare_PortMap(tree
->NEXT
->NEXT
,port
->NEXT
,env
,env_component
,Sig
);
546 freeptype(env_component
);
550 Verif_Bool_VHDL(tree
->NEXT
,env
);
551 return Verif_Instance(tree
->NEXT
->NEXT
,Sig
,env
,Comp
,Ins
);
554 ope1
=Verif_Exp_VHDL(tree
->NEXT
->NEXT
,env
);
555 ope2
=Verif_Exp_VHDL(tree
->NEXT
->NEXT
->NEXT
,env
);
557 fprintf(stderr,"%s:%d: bounds of FOR are inverted\n",FILE_NAME(tree),LINE(tree));
562 avt_errmsg(GNS_ERRMSG
, "004", AVT_FATAL
, 202);
563 // fprintf(stderr,"Verif_Instance: NULL pointer in FOR\n");
566 // zinaps: removed Verif_HighBound_FOR(tree->NEXT->NEXT->NEXT,env);
567 /*to check if variable isn't already used and for is in bounds*/
568 /*lower bound of for*/
569 env
=put_value(tree
->NEXT
->DATA
,ope1
,env
);
570 Ins
=Verif_Instance(tree
->NEXT
->NEXT
->NEXT
->NEXT
,Sig
,env
,Comp
,Ins
);
571 /*upper bound of for*/
573 Ins2
=Verif_Instance(tree
->NEXT
->NEXT
->NEXT
->NEXT
,Sig
,env
,Comp
,NULL
);
574 /*no use to control 2 times name of instances*/
576 /*remove variable of for*/
582 Error_Tree("Verif_Instance",tree
);
583 EXIT(2); return NULL
;