1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_lofig.c */
8 /* (c) copyright 1993 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
12 /* Auteur(s) : Marc LAURENTIN le : 27/01/1993 */
14 /* Modifie par : Anthony LESTER le : 20/11/1994 */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
18 /****************************************************************************/
20 #include "yag_headers.h"
22 lofig_list
*YAG_HEAD_MODEL
= NULL
;
24 static lofig_list
*cnsmodToLomod
__P((cone_list
*ptcone
, int index
));
25 static int coneConnect
__P((cone_list
*ptcone
));
26 static int coneIsEmpty
__P((cone_list
*ptcone
));
27 static void saveVbeConeModel
__P((cone_list
*ptcone
, int index
));
28 static void prepConeExt
__P((cone_list
*ptcone
));
29 static void restoreConeExt
__P((cone_list
*ptcone
));
30 static void delOutconeForVst
__P((cnsfig_list
*ptcnsfig
));
31 static void genCatal
__P((lofig_list
*headModel
));
32 static void prepConeMemory
__P((cone_list
*ptcone
));
33 static void restoreConeMemory
__P((cone_list
*ptcone
));
34 static void addGlueCones
__P((cnsfig_list
*ptcnsfig
));
35 static void removeGlueCones
__P((cnsfig_list
*ptcnsfig
));
36 static void addCellInstances
__P((lofig_list
*ptlofig
, cnsfig_list
*ptcnsfig
, long vddSigIndex
, long vssSigIndex
));
37 static lofig_list
*cellToLomod
__P((cell_list
*ptcell
));
38 static chain_list
*labelEnum
__P((char *root
, long num
));
40 /****************************************************************************
41 * function yagBuildLofig(); *
42 ****************************************************************************/
44 yagBuildLofig(ptcnsfig
, ptlotrsfig
)
45 cnsfig_list
*ptcnsfig
;
46 lofig_list
*ptlotrsfig
;
50 lofig_list
*tabModel
[200]; /* table des model:index donne par modelTable*/
51 edge_list
*tabIncone
[500];
56 cone_list
*ptcone
, *ptxcone
;
60 chain_list
*signame
= NULL
;
78 /* disable global analysis of any cones built */
79 save_USE_FCF
= YAG_CONTEXT
->YAG_USE_FCF
;
80 YAG_CONTEXT
->YAG_USE_FCF
= FALSE
;
82 funcTable
= addht(100); /* table des occurences de modeles (stat..)*/
83 modelTable
= addht(100); /* correspondance model <-> index */
85 /*-----------------------------------------------------------------+
86 | On supprime iterativement les outcones qui pointe sur des cones |
87 | qui n'ont pas de sorties, ceci pour que la netlist structurelle |
88 | soit avalable par Asimut ou par SaX |
89 +----------------------------------------------------------------*/
90 delOutconeForVst(ptcnsfig
);
92 /*--------------------------------------------------------+
93 | On associe a chaque cone son modele (char * ~= structrel|
94 | Si le model est nouveau , il est ajoute a la table de |
95 | hasch modelTable avec un index qui est incremente. |
96 | et le model logique MBK est cree |
97 | Le pointeur sur le model logique (MBK) est ajoute dans |
98 | un tableau de pointeur, dont l'index est celui precite |
99 | ON accedera donc au pointeur de model en cherchant |
100 | table[i] avec i = le res du hash sur l'expression du |
102 | Enfin, le vbe du model est crache sur disque |
103 +--------------------------------------------------------*/
105 addGlueCones(ptcnsfig
);
107 for(ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
109 if (ptcone
->CELLS
!= NULL
) {
110 for (ptchain
= ptcone
->CELLS
; ptchain
; ptchain
= ptchain
->NEXT
) {
111 ptcell
= (cell_list
*)ptchain
->DATA
;
112 if ((ptcell
->TYPE
& ~CNS_UNKNOWN
) >= 128 && ptcell
->BEFIG
== NULL
) break;
114 if (ptchain
== NULL
) continue;
116 if ((ptcone
->TYPE
& CNS_POWER
) != 0) continue;
117 if (ptcone
->OUTCONE
== NULL
&& (ptcone
->TYPE
& YAG_GLUECONE
) == 0) continue;
118 if (coneIsEmpty(ptcone
) == 0) continue;
119 if (coneConnect(ptcone
) == 0) continue;
121 if ((ptcone
->TYPE
& CNS_EXT
) == CNS_EXT
) prepConeExt(ptcone
);
122 if ((ptcone
->TYPE
& (CNS_MEMSYM
|CNS_LATCH
)) == CNS_MEMSYM
)
123 prepConeMemory(ptcone
);
125 yagMakeConeModel(ptcone
);
126 ptuser
= getptype(ptcone
->USER
, YAG_MODEL_PTYPE
);
127 if (ptuser
== NULL
) continue;
128 expr
= (char*)ptuser
->DATA
;
129 value
= gethtitem(funcTable
,expr
);
131 if(value
== EMPTYHT
) { /* Nouveau model de cone */
132 addhtitem(funcTable
, expr
, 1);
133 addhtitem(modelTable
, expr
, modelIdx
);
134 ptfig
= cnsmodToLomod(ptcone
, modelIdx
);
136 saveVbeConeModel(ptcone
, modelIdx
);
137 tabModel
[modelIdx
++] = ptfig
;
139 else sethtitem(funcTable
,expr
,value
+1);
142 /*-----------------------------------------------------+
143 | On cree la figure proprement dit |
144 +-----------------------------------------------------*/
145 sprintf(buf
, "%s_yagh", ptcnsfig
->NAME
);
146 ptlofig
= addlofig(namealloc(buf
));
148 /*--------------------------------------------------+
149 | Signaux de la figure |
150 +--------------------------------------------------*/
151 for(ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
154 if (ptcone
->CELLS
!= NULL
) {
155 for (ptchain
= ptcone
->CELLS
; ptchain
; ptchain
= ptchain
->NEXT
) {
156 ptcell
= (cell_list
*)ptchain
->DATA
;
157 if ((ptcell
->TYPE
& ~CNS_UNKNOWN
) >= 128 && ptcell
->BEFIG
== NULL
) break;
159 if (ptchain
== NULL
&& (ptcone
->TYPE
& YAG_CELLOUT
) == 0) continue;
161 if (ptcone
->OUTCONE
== NULL
&& (ptcone
->TYPE
& YAG_GLUECONE
) == 0) continue;
162 if ((ptcone
->TYPE
& CNS_POWER
) == CNS_POWER
) continue;
163 if (coneIsEmpty(ptcone
) == 0) continue;
165 signame
= addchain(NULL
, (void *)ptcone
->NAME
);
167 if ((ptcone
->TYPE
& CNS_EXT
) != 0)
168 ptsig
= addlosig(ptlofig
, ptcone
->INDEX
, signame
, EXTERNAL
);
169 else ptsig
= addlosig(ptlofig
, ptcone
->INDEX
, signame
, INTERNAL
);
171 rcn_addcapa(ptsig
, yagGetConeCapa(ptcone
, ptlofig
));
174 /*---------------------------------------------------------+
175 | Connecteurs externes: Ceux sur lequel un cone est monte |
176 | sont craches tels quel puisque un signal ( un cone) leur |
177 | associe. Pour les autres (fin de branche EXT sur lequel ,|
178 | il n'y a pas de cone -xor de connecteur=contre exemple-) |
180 | un signal supplementaire, dont on range l'index dans un |
181 | user MBK_SIG du connecteur |
182 +---------------------------------------------------------*/
183 for (ptcon
= ptcnsfig
->LOCON
; ptcon
!= NULL
; ptcon
= ptcon
->NEXT
) {
185 if (ptcon
->DIRECTION
== 'X') continue; /* Transparence */
187 if (ptcon
->DIRECTION
== CNS_VDDC
|| ptcon
->DIRECTION
== CNS_VSSC
) {
188 if (ptcon
->DIRECTION
== CNS_VDDC
&& !vddDone
&& !YAG_CONTEXT
->YAG_NO_SUPPLY
) {
190 if (YAG_CONTEXT
->YAG_ONE_SUPPLY
) {
194 else name
= ptcon
->NAME
;
195 ptsig
= addlosig(ptlofig
, nbSig
, addchain(NULL
, name
), EXTERNAL
);
197 if (ptcon
->SIG
->PRCN
!= NULL
) capa
= rcn_getcapa(ptlotrsfig
, ptcon
->SIG
);
199 rcn_addcapa(ptsig
, capa
);
200 addlocon(ptlofig
, name
, getlosig(ptlofig
,vddSigIndex
), 'I');
203 else if (ptcon
->DIRECTION
== CNS_VSSC
&& !vssDone
&& !YAG_CONTEXT
->YAG_NO_SUPPLY
) {
205 if (YAG_CONTEXT
->YAG_ONE_SUPPLY
) {
209 else name
= ptcon
->NAME
;
210 ptsig
= addlosig(ptlofig
, nbSig
, addchain(NULL
, name
), EXTERNAL
);
212 if (ptcon
->SIG
->PRCN
!= NULL
) capa
= rcn_getcapa(ptlotrsfig
, ptcon
->SIG
);
214 rcn_addcapa(ptsig
, capa
);
215 addlocon(ptlofig
, name
, getlosig(ptlofig
,vssSigIndex
), 'I');
221 ptuser
= getptype(ptcon
->USER
, CNS_EXT
);
222 /* connecteur sur lequel est monte un cone */
224 if (ptuser
!= NULL
) {
225 ptcone
= (cone_list
*)ptuser
->DATA
;
226 if (coneIsEmpty(ptcone
) != 0) /* si cone non vide */
227 addlocon(ptlofig
, ptcon
->NAME
, getlosig(ptlofig
, ptcone
->INDEX
), ptcon
->DIRECTION
);
229 ptsig
= addlosig(ptlofig
, nbSig
, addchain(NULL
, (void*)ptcon
->NAME
), EXTERNAL
);
231 if (ptcon
->SIG
->PRCN
!= NULL
) capa
= rcn_getcapa(ptlotrsfig
, ptcon
->SIG
);
233 rcn_addcapa(ptsig
, capa
);
234 addlocon(ptlofig
, ptcon
->NAME
, getlosig(ptlofig
, nbSig
), ptcon
->DIRECTION
);
235 ptcon
->USER
= addptype(ptcon
->USER
, CNS_SIGNAL
, (void*)nbSig
);
239 else { /* les autres */
240 ptsig
= addlosig(ptlofig
, nbSig
, NULL
, EXTERNAL
);
242 if (ptcon
->SIG
->PRCN
!= NULL
) capa
= rcn_getcapa(ptlotrsfig
, ptcon
->SIG
);
244 rcn_addcapa(ptsig
, capa
);
245 addlocon(ptlofig
, ptcon
->NAME
, getlosig(ptlofig
, nbSig
), ptcon
->DIRECTION
);
246 ptcon
->USER
= addptype(ptcon
->USER
, CNS_SIGNAL
, (void*)nbSig
);
251 /*-----------------------------------------------------+
252 | On change temporairement l'index de tous les cones |
253 | VDD ou VSS. Leur index prend la valeur de l'index |
254 | du signal associe aux connecteurs ext d'alimentation |
255 +-----------------------------------------------------*/
256 for (ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
257 if((ptcone
->TYPE
& CNS_VDD
) == CNS_VDD
) {
258 ptcone
->USER
= addptype(ptcone
->USER
, YAG_OLDINDEX_PTYPE
, (void*)ptcone
->INDEX
);
259 ptcone
->INDEX
= vddSigIndex
;
261 else if ((ptcone
->TYPE
& CNS_VSS
) == CNS_VSS
) {
262 ptcone
->USER
= addptype(ptcone
->USER
, YAG_OLDINDEX_PTYPE
, (void*)ptcone
->INDEX
);
263 ptcone
->INDEX
= vssSigIndex
;
268 /*----------------------------------------------------+
269 | on crache les instances |
270 +----------------------------------------------------*/
271 for (ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
273 if (ptcone
->CELLS
!= NULL
) {
274 for (ptchain
= ptcone
->CELLS
; ptchain
; ptchain
= ptchain
->NEXT
) {
275 ptcell
= (cell_list
*)ptchain
->DATA
;
276 if ((ptcell
->TYPE
& ~CNS_UNKNOWN
) >= 128 && ptcell
->BEFIG
== NULL
) break;
278 if (ptchain
== NULL
) continue;
280 if (ptcone
->OUTCONE
== NULL
&& (ptcone
->TYPE
& YAG_GLUECONE
) == 0) continue;
281 if (coneIsEmpty(ptcone
) == 0) continue;
282 if (coneConnect(ptcone
) == 0) continue;
283 if ((ptcone
->TYPE
& CNS_POWER
) == CNS_POWER
) continue;
285 ptuser
= getptype(ptcone
->USER
, YAG_MODEL_PTYPE
);
287 if (ptuser
== NULL
) {
288 yagBug(DBG_NO_CONEMODEL
,"yagBuildLofig",ptcone
->NAME
,NULL
,0);
291 /*------------------------------------------------------------------+
292 | On recupere le lomodele du cone a partir du model passe dans TsH |
293 +------------------------------------------------------------------*/
294 model
= (char *)ptuser
->DATA
;
295 nbModel
= gethtitem(modelTable
, model
);
296 ptfig
= tabModel
[nbModel
];
298 /*-------------------------------------------+
299 | On constitue un tableau ordonnee de incone |
300 +-------------------------------------------*/
302 for(ptedge
= ptcone
->INCONE
; ptedge
!= NULL
; ptedge
= ptedge
->NEXT
) {
303 if((ptedge
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) continue ;
304 if((ptedge
->TYPE
& YAG_NOT_FUNCTIONAL
) == YAG_NOT_FUNCTIONAL
) continue ;
305 if((ptedge
->TYPE
& CNS_POWER
) == CNS_POWER
) continue ;
306 if((ptedge
->TYPE
& (CNS_BLEEDER
|CNS_FEEDBACK
)) != 0) continue ;
308 ptuser
= getptype(ptedge
->USER
, YAG_WEIGHT_PTYPE
);
309 i
= (int)((long)ptuser
->DATA
);
310 tabIncone
[i
] = ptedge
;
314 /*-----------------------------------------+
315 | On fabrique la chainlist des entrees |
316 +-----------------------------------------*/
318 for (i
=1; i
<=nbEdge
; i
++) {
319 ptedge
= tabIncone
[i
];
321 if ((ptedge
->TYPE
& CNS_CONE
) != 0) {
322 ptxcone
= ptedge
->UEDGE
.CONE
;
323 sigchain
= addchain(sigchain
, (void*)getlosig(ptlofig
, ptxcone
->INDEX
));
325 else { /* Entree de type Connecteur */
326 ptcon
= ptedge
->UEDGE
.LOCON
;
327 /*-----------------------------------------------------+
328 | Si un cone est monte sur le connecteur , ATTENTION , |
329 | C'est peut etre un cone vide |
330 +-----------------------------------------------------*/
331 if ((ptuser
= getptype(ptcon
->USER
, CNS_EXT
)) != NULL
) {
332 ptxcone
= (cone_list
*)ptuser
->DATA
;
334 if (coneIsEmpty(ptxcone
) != 0) { /* si cone non vide */
335 sigchain
= addchain(sigchain
, (void*)getlosig(ptlofig
, ptxcone
->INDEX
));
337 else { /* si cone vide, le signal
338 qui y est attache n'a pas ete declare mais
339 un signal a ete creee pour le connecteur */
340 ptuser
= getptype(ptcon
->USER
, CNS_SIGNAL
);
341 sigchain
=addchain(sigchain
, (void*)getlosig(ptlofig
,(long)ptuser
->DATA
));
344 else { /* Pas de cone monte sur le connecteur -> comme cone vide */
345 ptuser
= getptype(ptcon
->USER
,CNS_SIGNAL
);
346 sigchain
=addchain(sigchain
, (void*)getlosig(ptlofig
,(long)ptuser
->DATA
));
351 /* ON RAJOUTE la SORTIE VDD et VSS puis on fait le ADDLOINS*/
354 char insname
[YAGBUFSIZE
];
355 sigchain
= addchain(sigchain
,(void*)getlosig(ptlofig
,ptcone
->INDEX
));
356 sigchain
= addchain(sigchain
,(void*)getlosig(ptlofig
,vddSigIndex
));
357 sigchain
= addchain(sigchain
,(void*)getlosig(ptlofig
,vssSigIndex
));
358 sprintf(insname
,"yagins_%s",yagVectorizeName(ptcone
->NAME
));
359 addloins(ptlofig
,namealloc(insname
),ptfig
,sigchain
);
363 addCellInstances(ptlofig
, ptcnsfig
, vddSigIndex
, vssSigIndex
);
365 /*----------------------------------------------------+
366 | On remet en place les index des cones alimentation |
367 | et les con EXT contenant un connecteur 'T' |
368 +----------------------------------------------------*/
369 for (ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
370 if ((ptcone
->TYPE
& CNS_POWER
) == CNS_POWER
) {
371 ptuser
= getptype(ptcone
->USER
, YAG_OLDINDEX_PTYPE
);
372 ptcone
->INDEX
= (long)ptuser
->DATA
;
373 ptcone
->USER
= delptype(ptcone
->USER
, YAG_OLDINDEX_PTYPE
);
375 else if ((ptcone
->TYPE
& CNS_EXT
) == CNS_EXT
) {
376 restoreConeExt(ptcone
);
378 else if ((ptcone
->TYPE
& (CNS_MEMSYM
|CNS_LATCH
)) == CNS_MEMSYM
) {
379 restoreConeMemory(ptcone
);
384 removeGlueCones(ptcnsfig
);
386 sortlocon(&ptlofig
->LOCON
);
387 genCatal(YAG_HEAD_MODEL
);
389 ptcnsfig
->USER
= addptype(ptcnsfig
->USER
, YAG_CONE_NETLIST_PTYPE
, ptlofig
);
391 YAG_CONTEXT
->YAG_USE_FCF
= save_USE_FCF
;
394 /****************************************************************************
395 * function cnsmodToLomod(); *
396 ****************************************************************************/
397 /*--------------------------------------------------------------------------+
398 | Fabrique un lofig contenant essentiellement l'interface du cone |
399 +--------------------------------------------------------------------------*/
401 cnsmodToLomod(ptcone
, index
)
408 char figname
[YAGBUFSIZE
];
413 for(ptincone
= ptcone
->INCONE
; ptincone
!= NULL
; ptincone
= ptincone
->NEXT
) {
415 if((ptincone
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) continue;
416 if((ptincone
->TYPE
& YAG_NOT_FUNCTIONAL
) == YAG_NOT_FUNCTIONAL
) continue;
417 if((ptincone
->TYPE
& CNS_POWER
) == CNS_POWER
) continue;
418 if((ptincone
->TYPE
& (CNS_BLEEDER
|CNS_FEEDBACK
)) != 0) continue;
420 ptuser
= getptype(ptincone
->USER
,YAG_WEIGHT_PTYPE
);
422 yagBug(DBG_NO_INCONEUSER
,"cnsmodToLomod",ptcone
->NAME
,"YAG_WEIGHT_PTYPE",0);
424 poids
= (long)ptuser
->DATA
;
426 if (poids
> nbIn
) nbIn
= poids
;
429 sprintf(figname
,"%s_model_%d", CNS_HEADCNSFIG
->NAME
, index
);
431 YAG_HEAD_MODEL
= addlomodel(YAG_HEAD_MODEL
, namealloc(figname
));
432 ptfig
= YAG_HEAD_MODEL
;
434 for(i
=1; i
<=nbIn
; i
++) addlosig(ptfig
, i
, (void*)NULL
, EXTERNAL
);
436 addlosig(ptfig
, nbIn
+1, (void *)NULL
, EXTERNAL
); /* f */
437 addlosig(ptfig
, nbIn
+2, (void *)NULL
, EXTERNAL
); /* vdd */
438 addlosig(ptfig
, nbIn
+3, (void *)NULL
, EXTERNAL
); /* vss */
440 for (i
=1; i
<=nbIn
; i
++) {
442 sprintf(buff
, "in%d", i
);
443 addlocon(ptfig
, namealloc(buff
), getlosig(ptfig
,i
), 'I');
446 if((ptcone
->TYPE
& CNS_TRI
) == CNS_TRI
) addlocon(ptfig
, namealloc("f"), getlosig(ptfig
,nbIn
+1), 'Z');
447 else addlocon(ptfig
, namealloc("f"), getlosig(ptfig
,nbIn
+1), 'O');
449 addlocon(ptfig
, namealloc("vdd"), getlosig(ptfig
,nbIn
+2), 'I');
450 addlocon(ptfig
, namealloc("vss"), getlosig(ptfig
,nbIn
+3),'I');
454 /****************************************************************************
455 * function coneConnect(); *
456 ****************************************************************************/
457 /*-------------------------------------------------------------------------+
458 | Retourne 0 si le cone est un cone connecteur ie il possede une branche |
459 | functionnelle unique qui est la branche maillon connecteur |
460 | -1 si le cone possede au moins une branche functionnele qui |
461 | n'est pas externe. |
462 +-------------------------------------------------------------------------*/
467 branch_list
*ptbranch
;
468 short coneconnect
= 0;
471 if ((ptcone
->TYPE
& CNS_EXT
) != CNS_EXT
) return(-1);
473 if(ptcone
->BREXT
==NULL
) return(-1);
475 for (ptbranch
= ptcone
->BRVDD
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
476 if ((ptbranch
->TYPE
& CNS_NOT_FUNCTIONAL
) == 0) funcpath
++;
478 for (ptbranch
= ptcone
->BRVSS
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
479 if ((ptbranch
->TYPE
& CNS_NOT_FUNCTIONAL
) == 0) funcpath
++;
481 for (ptbranch
= ptcone
->BREXT
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
482 if (ptbranch
->LINK
->NEXT
== NULL
) coneconnect
++;
486 if (funcpath
!= 0) return(-1);
487 else if (coneconnect
== 1) return(0);
489 yagBug(DBG_MULT_CON
, "coneConnect", ptcone
->NAME
, NULL
, 0);
494 /****************************************************************************
495 * function coneIsEmpty(); *
496 ****************************************************************************/
501 if ((ptcone
->BRVDD
== NULL
)
502 && (ptcone
->BRVSS
== NULL
)
503 && (ptcone
->BREXT
== NULL
)
504 && (ptcone
->BRGND
== NULL
)
505 && (ptcone
->INCONE
== NULL
)
506 && (ptcone
->OUTCONE
== NULL
))
511 /****************************************************************************
512 * function vbeConeModel(); *
513 ****************************************************************************/
514 /*--------------------------------------------------------------------------+
515 | Sauvegarde sur disque le comportemental Vhdl d'un model de cone |
516 +-------------------------------------------------------------------------*/
518 saveVbeConeModel(ptcone
, index
)
529 char figname
[YAGBUFSIZE
];
530 char newName
[YAGBUFSIZE
];
534 /*--------------------------------------------------------------+
535 | On renomme temporairement tous les cones ou les connecteurs |
536 | qui sont en entree du cone. On parcourt les incones dont on |
537 | connait le poids, et in renomme le cone/connect correspondant |
538 | par un ("in%s",poids) comme pour les instances |
539 | La sortie s'appellera invariablement 'f' |
540 +--------------------------------------------------------------*/
541 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
542 if ((ptin
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) continue;
543 if ((ptin
->TYPE
& YAG_NOT_FUNCTIONAL
) == YAG_NOT_FUNCTIONAL
) continue;
544 if ((ptin
->TYPE
& CNS_POWER
) == CNS_POWER
) continue;
545 if ((ptin
->TYPE
& (CNS_BLEEDER
|CNS_FEEDBACK
)) != 0) continue;
547 if ((ptin
->TYPE
& CNS_CONE
) != 0) {
548 ptincone
= ptin
->UEDGE
.CONE
;
549 ptincone
->USER
= addptype(ptincone
->USER
, YAG_OLDNAME_PTYPE
, (void *)ptincone
->NAME
);
550 ptuser
= getptype(ptin
->USER
, YAG_WEIGHT_PTYPE
);
551 poids
= (long)ptuser
->DATA
;
552 sprintf(newName
, "in%ld", poids
);
553 ptincone
->NAME
= namealloc(newName
);
556 ptcon
= ptin
->UEDGE
.LOCON
;
557 ptcon
->USER
= addptype(ptcon
->USER
, YAG_OLDNAME_PTYPE
, (void *)ptcon
->NAME
);
558 ptuser
= getptype(ptin
->USER
, YAG_WEIGHT_PTYPE
);
559 poids
= (long)ptuser
->DATA
;
560 sprintf(newName
, "in%ld", poids
);
561 ptcon
->NAME
= namealloc(newName
);
565 /*-----------------------------------------------------+
566 | Ecriture du modele sur disque |
567 +-----------------------------------------------------*/
569 sprintf(figname
, "%s_model_%d", CNS_HEADCNSFIG
->NAME
, index
);
570 if ((ptbefig
= yagMakeLatchBehaviour(ptcone
, FALSE
)) == NULL
) {
571 ptbefig
= beh_addbefig(NULL
, figname
);
572 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
573 if ((ptin
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) continue;
574 if ((ptin
->TYPE
& YAG_NOT_FUNCTIONAL
) == YAG_NOT_FUNCTIONAL
) continue;
575 if ((ptin
->TYPE
& (CNS_BLEEDER
|CNS_FEEDBACK
)) != 0) continue;
577 if ((ptin
->TYPE
& (CNS_POWER
|CNS_CONE
)) != 0) {
578 name
= ptin
->UEDGE
.CONE
->NAME
;
580 else name
= ptin
->UEDGE
.LOCON
->NAME
;
582 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, name
, 'I', 'B');
583 ptbefig
->BERIN
= beh_addberin(ptbefig
->BERIN
, name
);
586 if ((ptcone
->TYPE
& CNS_LATCH
) != 0 || (ptcone
->TYPE
& CNS_PRECHARGE
) != 0) {
587 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, "f", 'O', 'B');
588 expr
= createAtom("aux");
589 ptbefig
->BEOUT
= beh_addbeout(ptbefig
->BEOUT
, "f", expr
, NULL
, 0);
590 biexpr
= yagMakeLatchExpr(ptcone
);
591 ptbefig
->BEREG
= beh_addbereg(ptbefig
->BEREG
, "aux", biexpr
, NULL
,0);
593 else if ((ptcone
->TYPE
& CNS_TRI
) == CNS_TRI
) {
594 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, "f", 'Z', 'W');
595 biexpr
= yagMakeTristateExpr(ptcone
);
596 ptbefig
->BEBUS
= beh_addbebus(ptbefig
->BEBUS
, "f", biexpr
, NULL
, 'W',0);
598 else if ((ptcone
->TYPE
& CNS_CONFLICT
) == CNS_CONFLICT
) {
599 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, "f", 'Z', 'W');
600 biexpr
= yagMakeTristateExpr(ptcone
);
601 ptbefig
->BEBUS
= beh_addbebus(ptbefig
->BEBUS
, "f", biexpr
, NULL
, 'W',0);
604 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, "f", 'O', 'B');
605 expr
= yagMakeDualExpr(ptcone
);
606 ptbefig
->BEOUT
= beh_addbeout(ptbefig
->BEOUT
, "f", expr
, NULL
, 0);
609 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, CNS_VDDNAME
, 'I', 'B');
610 ptbefig
->BEPOR
= beh_addbepor(ptbefig
->BEPOR
, CNS_VSSNAME
, 'I', 'B');
612 ptbefig
->NAME
= figname
;
613 savebefig(ptbefig
, 0);
614 beh_frebefig(ptbefig
);
616 /*----------------------------------------------------------+
617 | On remet tous les noms en place |
618 +----------------------------------------------------------*/
619 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
620 if ((ptin
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) continue;
621 if ((ptin
->TYPE
& YAG_NOT_FUNCTIONAL
) == YAG_NOT_FUNCTIONAL
) continue;
622 if ((ptin
->TYPE
& CNS_POWER
) == CNS_POWER
) continue;
623 if ((ptin
->TYPE
& (CNS_BLEEDER
|CNS_FEEDBACK
)) != 0) continue;
625 if ((ptin
->TYPE
& CNS_CONE
) != 0) {
626 ptincone
= ptin
->UEDGE
.CONE
;
627 ptuser
= getptype(ptincone
->USER
, YAG_OLDNAME_PTYPE
);
628 ptincone
->NAME
= (char *)ptuser
->DATA
;
629 ptincone
->USER
= delptype(ptincone
->USER
, YAG_OLDNAME_PTYPE
);
632 ptcon
= ptin
->UEDGE
.LOCON
;
633 ptuser
= getptype(ptcon
->USER
, YAG_OLDNAME_PTYPE
);
634 ptcon
->NAME
= (char *)ptuser
->DATA
;
635 ptcon
->USER
= delptype(ptcon
->USER
, YAG_OLDNAME_PTYPE
);
640 /****************************************************************************
641 * function prepConeExt(); *
642 ****************************************************************************/
643 /*--------------------------------------------------------------------------+
644 | sauvegarde puis supprime de la liste des branche, la branche qui contient|
645 | un conecteur T , des cone montes sur un connecteur T. L'entree contenant |
646 | le connecteur T est elle type IGNORE . Il va de soit que ces modif ne |
647 | doivent etre que temporaires |
648 +--------------------------------------------------------------------------*/
655 branch_list
*ptbranch
;
658 ptuser
= getptype(ptcone
->USER
, CNS_EXT
);
659 ptcon
= (locon_list
*)((chain_list
*)ptuser
->DATA
)->DATA
;
661 if (ptcon
->DIRECTION
== 'I' || ptcon
->DIRECTION
== 'O') return;
663 for (ptbranch
= ptcone
->BREXT
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
664 if (ptbranch
->LINK
->NEXT
!= NULL
) continue;
665 ptbranch
->TYPE
|= CNS_IGNORE
;
666 ptincone
= yagGetEdge(ptcone
->INCONE
, ptbranch
->LINK
->ULINK
.LOCON
);
667 ptincone
->TYPE
|= CNS_IGNORE
;
671 /****************************************************************************
672 * function restoreConeExt(); *
673 ****************************************************************************/
674 /*-------------------------------------------------------------------------+
675 | Remet en place la branche contenant le connecteur INOUT supprimee par la |
676 | function prepConeExt. |
677 +--------------------------------------------------------------------------*/
679 restoreConeExt(ptcone
)
684 branch_list
*ptbranch
;
687 ptuser
= getptype(ptcone
->USER
, CNS_EXT
);
688 ptcon
= (locon_list
*)((chain_list
*)ptuser
->DATA
)->DATA
;
690 if (ptcon
->DIRECTION
== 'I' || ptcon
->DIRECTION
== 'O') return;
692 for (ptbranch
= ptcone
->BREXT
; ptbranch
!= NULL
; ptbranch
= ptbranch
->NEXT
) {
693 if (ptbranch
->LINK
->NEXT
!= NULL
) continue;
694 ptbranch
->TYPE
&= ~CNS_IGNORE
;
695 ptincone
= yagGetEdge(ptcone
->INCONE
, ptbranch
->LINK
->ULINK
.LOCON
);
696 ptincone
->TYPE
&= ~CNS_IGNORE
;
700 /****************************************************************************
701 * function delOutConeForVst() *
702 ****************************************************************************/
703 /*------------------------------------------------------------------------+
704 | Suprime les outcone pointant sur des cones sans sorties. Fonction |
705 | iterative, puisque d'une passe a l'autre, les cones perdent des outcones|
706 +------------------------------------------------------------------------*/
708 delOutconeForVst(ptcnsfig
)
709 cnsfig_list
*ptcnsfig
;
715 cone_list
*ptoutcone
;
718 while (change
== 0) {
722 for (ptcone
= ptcnsfig
->CONE
; ptcone
!= NULL
; ptcone
= ptcone
->NEXT
) {
723 if (ptcone
->OUTCONE
!= NULL
) continue;
725 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
726 if ((ptin
->TYPE
& CNS_EXT
) == CNS_EXT
) continue;
728 ptincone
= ptin
->UEDGE
.CONE
;
729 for (ptout
= ptincone
->OUTCONE
; ptout
!= NULL
; ptout
= ptout
->NEXT
) {
730 if ((ptout
->TYPE
& CNS_EXT
) == CNS_EXT
) continue;
732 ptoutcone
= ptout
->UEDGE
.CONE
;
733 if (ptoutcone
== ptcone
) {
734 ptincone
->OUTCONE
= deledge(ptincone
->OUTCONE
, ptout
);
744 /****************************************************************************
745 * function genCatal(); *
746 ****************************************************************************/
747 /*--------------------------------------------------------------------------+
748 | Genere le fichier CATAL contenant la liste des modeles suivi de ' C' |
749 +-------------------------------------------------------------------------*/
752 lofig_list
*headModel
;
757 if ((ptCatal
= mbkfopen(CATAL
, NULL
, WRITE_TEXT
)) == NULL
) {
758 avt_errmsg(YAG_ERRMSG
, "006", AVT_ERROR
, CATAL
);
762 for (ptlofig
= headModel
; ptlofig
!= NULL
; ptlofig
= ptlofig
->NEXT
)
763 fprintf(ptCatal
, "%s C\n", ptlofig
->NAME
);
765 if (fclose(ptCatal
) != 0)
766 avt_errmsg(YAG_ERRMSG
, "007", AVT_ERROR
, CATAL
);
769 /****************************************************************************
770 * function prepConeMemory(); *
771 ****************************************************************************/
772 /*--------------------------------------------------------------------------+
773 | Cette function fait en sorte que le cone ressemble temporairement a un |
775 +--------------------------------------------------------------------------*/
777 prepConeMemory(ptcone
)
780 branch_list
*ptbranch
;
783 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
784 if ((ptin
->TYPE
& CNS_LOOP
) != CNS_LOOP
) ptin
->TYPE
|= CNS_IGNORE
;
787 /* ignore all branches of more than one link */
788 for (ptbranch
= ptcone
->BRVDD
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
789 if (ptbranch
->LINK
->NEXT
!= NULL
) {
790 ptbranch
->TYPE
|= CNS_IGNORE
;
793 for (ptbranch
= ptcone
->BRVSS
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
794 if (ptbranch
->LINK
->NEXT
!= NULL
) {
795 ptbranch
->TYPE
|= CNS_IGNORE
;
800 /****************************************************************************
801 * function restoreConeMemory(); *
802 ****************************************************************************/
804 restoreConeMemory(ptcone
)
807 branch_list
*ptbranch
;
810 for (ptin
= ptcone
->INCONE
; ptin
!= NULL
; ptin
= ptin
->NEXT
) {
811 if ((ptin
->TYPE
& CNS_LOOP
) != CNS_LOOP
) ptin
->TYPE
&= ~CNS_IGNORE
;
814 for (ptbranch
= ptcone
->BRVDD
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
815 if ((ptbranch
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) {
816 ptbranch
->TYPE
&= ~(CNS_IGNORE
);
819 for (ptbranch
= ptcone
->BRVSS
; ptbranch
; ptbranch
= ptbranch
->NEXT
) {
820 if ((ptbranch
->TYPE
& CNS_IGNORE
) == CNS_IGNORE
) {
821 ptbranch
->TYPE
&= ~(CNS_IGNORE
);
826 /****************************************************************************
827 * function addGlueCones(); *
828 ****************************************************************************/
830 addGlueCones(ptcnsfig
)
831 cnsfig_list
*ptcnsfig
;
834 cone_list
*headgluecone
;
838 ptuser
= getptype(ptcnsfig
->USER
, YAG_GLUECONE_PTYPE
);
839 if (ptuser
!= NULL
) {
840 headgluecone
= (cone_list
*)ptuser
->DATA
;
841 for (ptcone
= ptcnsfig
->CONE
; ptcone
->NEXT
; ptcone
= ptcone
->NEXT
);
842 ptcone
->NEXT
= headgluecone
;
843 index
= ptcone
->INDEX
+ 1;
844 for (ptcone
= headgluecone
; ptcone
; ptcone
= ptcone
->NEXT
) {
845 ptcone
->INDEX
= index
++;
850 /****************************************************************************
851 * function removeGlueCones(); *
852 ****************************************************************************/
854 removeGlueCones(ptcnsfig
)
855 cnsfig_list
*ptcnsfig
;
858 cone_list
*headgluecone
;
861 ptuser
= getptype(ptcnsfig
->USER
, YAG_GLUECONE_PTYPE
);
862 if (ptuser
!= NULL
) {
863 headgluecone
= (cone_list
*)ptuser
->DATA
;
864 for (ptcone
= ptcnsfig
->CONE
; ptcone
->NEXT
!= headgluecone
; ptcone
= ptcone
->NEXT
);
870 addCellInstances(ptlofig
, ptcnsfig
, vddSigIndex
, vssSigIndex
)
872 cnsfig_list
*ptcnsfig
;
880 chain_list
*cellsiglist
;
881 chain_list
*sigchain
;
883 char insname
[YAGBUFSIZE
];
886 modelTable
= addht(20);
887 for (ptcell
= ptcnsfig
->CELL
; ptcell
; ptcell
= ptcell
->NEXT
) {
888 if (ptcell
->BEFIG
== NULL
&& (ptcell
->TYPE
& ~CNS_UNKNOWN
) >= 128) continue;
890 ptmodel
= (lofig_list
*)gethtitem(modelTable
, (void *)ptcell
->TYPE
);
891 if (ptmodel
== (lofig_list
*)EMPTYHT
) {
892 ptmodel
= cellToLomod(ptcell
);
893 addhtitem(modelTable
, (void *)ptcell
->TYPE
, (long)ptmodel
);
895 cellsiglist
= (chain_list
*)getptype(ptcell
->USER
, YAG_SIGLIST_PTYPE
)->DATA
;
896 for (ptchain
= cellsiglist
; ptchain
; ptchain
= ptchain
->NEXT
) {
897 ptsig
= (losig_list
*)ptchain
->DATA
;
898 ptcone
= (cone_list
*)getptype(ptsig
->USER
, YAG_CONE_PTYPE
)->DATA
;
899 sigchain
= addchain(sigchain
, getlosig(ptlofig
, ptcone
->INDEX
));
901 sigchain
= reverse(sigchain
);
902 sigchain
= addchain(sigchain
, getlosig(ptlofig
, vddSigIndex
));
903 sigchain
= addchain(sigchain
, getlosig(ptlofig
, vssSigIndex
));
904 sprintf(insname
, "yagins_%s", ptcell
->BEFIG
->NAME
);
905 addloins(ptlofig
, namealloc(insname
), ptmodel
, sigchain
);
917 char figname
[YAGBUFSIZE
];
920 long numset
, numreset
;
922 switch (ptcell
->TYPE
& YAG_CELLMASK
) {
924 sprintf(figname
, "%s_ms_sc", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
925 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, NULL
, NULL
, "mem", "q", "qn", TRUE
, NULL
);
927 case YAG_CELL_MSS_SC
:
928 sprintf(figname
, "%s_mss_sc", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
929 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", "s", NULL
, NULL
, "mem", "q", "qn", TRUE
, NULL
);
931 case YAG_CELL_MSR_SC
:
932 sprintf(figname
, "%s_msr_sc", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
933 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, "r", NULL
, "mem", "q", "qn", TRUE
, NULL
);
935 case YAG_CELL_MSNR_SC
:
936 sprintf(figname
, "%s_msnr_sc", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
937 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, NULL
, "nr", "mem", "q", "qn", TRUE
, NULL
);
939 case YAG_CELL_MS_SC_RT
:
940 sprintf(figname
, "%s_ms_sc_rt", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
941 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, NULL
, NULL
, "mem", "q", "qn", FALSE
, NULL
);
943 case YAG_CELL_MSS_SC_RT
:
944 sprintf(figname
, "%s_mss_sc_rt", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
945 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", "s", NULL
, NULL
, "mem", "q", "qn", FALSE
, NULL
);
947 case YAG_CELL_MSR_SC_RT
:
948 sprintf(figname
, "%s_msr_sc_rt", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
949 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, "r", NULL
, "mem", "q", "qn", FALSE
, NULL
);
951 case YAG_CELL_MSNR_SC_RT
:
952 sprintf(figname
, "%s_msnr_sc_rt", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
953 ptbefig
= yagBuildBefigMSSC(figname
, NULL
, NULL
, "d", "ck", NULL
, NULL
, "nr", "mem", "q", "qn", FALSE
, NULL
);
955 case YAG_CELL_MSDIFF
:
956 sprintf(figname
, "%s_msdiff", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
957 ptbefig
= yagBuildBefigMSDIFF(figname
, "d", "ck", "mem", "q", "qn", NULL
);
960 sprintf(figname
, "%s_fft2", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
961 ptbefig
= yagBuildBefigFFT2(figname
, NULL
, NULL
, "d", "cpn", "ld", "re", "mem", "q", "qn", NULL
);
964 sprintf(figname
, "%s_fd2r", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
965 ptbefig
= yagBuildBefigFD2R(figname
, NULL
, NULL
, "d", "cpn", "re", "mem", "q", "qn", NULL
);
968 sprintf(figname
, "%s_fd2s", YAG_CONTEXT
->YAG_CURCNSFIG
->NAME
);
969 ptbefig
= yagBuildBefigFD2S(figname
, NULL
, NULL
, "d", "cpn", "re", "mem", "q", "qn", NULL
);
972 if ((ptcell
->TYPE
& ~CNS_UNKNOWN
) < 128) {
973 yagBug(DBG_ILL_CELLTYPE
, "cellToLomod", NULL
, NULL
, 0);
975 else if ((ptbefig
= fclGetBefig(ptcell
->BEFIG
->NAME
)) == NULL
) {
976 yagBug(DBG_ILL_CELLTYPE
, "cellToLomod", NULL
, NULL
, 0);
978 strcpy(figname
, ptbefig
->NAME
);
980 savebefig(ptbefig
, 0);
982 YAG_HEAD_MODEL
= addlomodel(YAG_HEAD_MODEL
, namealloc(figname
));
983 ptlofig
= YAG_HEAD_MODEL
;
985 for (ptbepor
= ptbefig
->BEPOR
; ptbepor
; ptbepor
= ptbepor
->NEXT
) {
986 ptlosig
= addlosig(ptlofig
, index
++, NULL
, EXTERNAL
);
987 switch (ptbepor
->DIRECTION
) {
988 case 'I': direction
= IN
; break;
989 case 'O': direction
= OUT
; break;
990 case 'Z': direction
= TRISTATE
; break;
991 case 'B': direction
= INOUT
; break;
992 case 'T': direction
= TRANSCV
; break;
994 addlocon(ptlofig
, ptbepor
->NAME
, ptlosig
, direction
);
996 ptlofig
->LOCON
= (locon_list
*)reverse((chain_list
*)ptlofig
->LOCON
);
999 beh_frebefig(ptbefig
);
1005 labelEnum(root
, num
)
1009 chain_list
*labels
= NULL
;
1013 for (i
=1; i
<= num
; i
++) {
1014 sprintf(buf
, "%s%d", root
, i
);
1015 labels
= addchain(labels
, namealloc(buf
));