Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / yagle / yag_split.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_split.c */
7 /* */
8 /* (c) copyright 1994 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* Auteur(s) : Anthony LESTER le : 01/08/1999 */
13 /* */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
17 /* */
18 /****************************************************************************/
19
20 #include "yag_headers.h"
21
22 static void transferLotrsInsfig(loins_list *ptgnsloins, lofig_list *ptinsfig, lofig_list *ptlofig, int copytrans);
23 static void transferLoinsInsfig(loins_list *ptgnsloins, lofig_list *ptinsfig, lofig_list *ptlofig, int copytrans);
24 static void createTopLosig(loins_list *ptloins, lofig_list *pttoplofig);
25 static lofig_list *createTopLofig(lofig_list *ptlofig, char *name);
26 static losig_list *getExtSigFromName(lofig_list *ptlofig, char *name);
27 static lofig_list *giveInstanceLofig(loins_list *ptloins, int copytrans);
28 static losig_list *giveLoinsLosig(lofig_list *ptinsfig, losig_list *ptoldsig);
29
30 static long topsigindex;
31 static long inssigindex;
32 static ht *inssight;
33 static chain_list *insextsigchain;
34
35 /* connector direction bit patterns */
36 /* bit 0 : input */
37 /* bit 1 : output */
38 /* bit 2 : not tristate */
39
40 #define HCON_IN 1
41 #define HCON_OUT 6
42 #define HCON_INOUT 7
43 #define HCON_OUTHZ 2
44 #define HCON_INOUTHZ 3
45
46
47 /****************************************************************************
48 * function yagCutLofig() *
49 ****************************************************************************/
50 /* create hierarchical figure from GENIUS or FCL instances */
51
52 lofig_list *
53 yagCutLofig(inffig_list *ifl, lofig_list *ptlofig, chain_list *instances, lofig_list **ptpttopfig, int copytrans)
54 {
55 chain_list *ptchain;
56 loins_list *ptloins;
57 loins_list *ptprevloins, *ptnextloins;
58 lofig_list *ptinsfig;
59 losig_list *pttopsig;
60 losig_list *ptlosig;
61 losig_list *ptprevsig;
62 locon_list *ptlocon;
63 chain_list *sigchain;
64 chain_list *savechain;
65 ptype_list *ptuser;
66 lotrs_list *ptlotrs;
67 lotrs_list *ptprevlotrs, *ptnextlotrs;
68 locon_list *ptnextlocon;
69 locon_list *oldloconlist;
70 loins_list *ptcoreins;
71 losig_list *sigarray[4];
72 char *name;
73 char buf[YAGBUFSIZE];
74 int i;
75
76 /* remove the rcnet */
77 /*
78 lofigchain( ptlofig );
79 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
80 if (ptlosig->PRCN) freelorcnet(ptlosig);
81 ptlosig->PRCN = NULL;
82 }
83 */
84
85 /* remove the old lofigchain */
86
87 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
88 if ((ptuser = getptype(ptlosig->USER, LOFIGCHAIN)) != NULL) {
89 freechain(ptuser->DATA);
90 ptlosig->USER = delptype(ptlosig->USER, LOFIGCHAIN);
91 }
92 }
93
94 /* remove power supply markings */
95
96 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
97 ptlosig = ptlocon->SIG;
98 if (ptlosig->TYPE != 'E') {
99 ptlosig->TYPE = 'E';
100 ptlocon->DIRECTION = 'I';
101 }
102 }
103
104 if (getptype(ptlofig->USER, PH_INTERF) != NULL) {
105 ptlofig->USER = delptype(ptlofig->USER, PH_INTERF);
106 }
107 if (getptype(ptlofig->USER, PH_REAL_INTERF) != NULL) {
108 ptlofig->USER = delptype(ptlofig->USER, PH_REAL_INTERF);
109 }
110
111 name = ptlofig->NAME;
112 delhtitem(HT_LOFIG, name);
113
114 strcpy(buf, name);
115 strcat(buf, "_yagcore");
116 ptlofig->NAME = namealloc(buf);
117 addhtitem(HT_LOFIG, ptlofig->NAME, (long)ptlofig);
118
119 strcpy(buf, name);
120 strcat(buf, "_yaglo");
121 *ptpttopfig = createTopLofig(ptlofig, namealloc(buf));
122
123 insextsigchain = NULL;
124
125 /* traverse the instances to create corresponding figures */
126 /* corresponding transistors are removed from core figure */
127
128 yagInitLosigVect();
129 for (ptchain = instances; ptchain; ptchain = ptchain->NEXT) {
130 inssigindex = 1;
131 ptloins = (loins_list *)ptchain->DATA;
132 createTopLosig(ptloins, *ptpttopfig);
133 sigchain = NULL;
134 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
135 /* remove power supply markings */
136 if (ptlocon->DIRECTION == 'D' || ptlocon->DIRECTION == 'S') ptlocon->DIRECTION = 'I';
137
138 ptlosig = ptlocon->SIG;
139 pttopsig = (losig_list *)getptype(ptlosig->USER, YAG_TOPSIG_PTYPE)->DATA;
140 sigchain = addchain(sigchain, pttopsig);
141 }
142 sigchain = reverse(sigchain);
143 ptinsfig = giveInstanceLofig(ptloins, copytrans);
144 addloins(*ptpttopfig, ptloins->INSNAME, ptinsfig, sigchain);
145 transferLotrsInsfig(ptloins, ptinsfig, ptlofig, copytrans);
146 transferLoinsInsfig(ptloins, ptinsfig, ptlofig, copytrans);
147 }
148 yagCloseLosigVect();
149
150 /* delete transistors marked for deletion */
151 ptprevlotrs = NULL;
152 for (ptlotrs = ptlofig->LOTRS; ptlotrs; ptlotrs = ptnextlotrs) {
153 ptnextlotrs = ptlotrs->NEXT;
154 if (ptlotrs->TYPE == 0) {
155 if (ptprevlotrs == NULL) ptlofig->LOTRS = ptlotrs->NEXT;
156 else ptprevlotrs->NEXT = ptlotrs->NEXT;
157 delloconuser( ptlotrs->GRID );
158 mbkfree(ptlotrs->GRID);
159 delloconuser( ptlotrs->SOURCE );
160 mbkfree(ptlotrs->SOURCE);
161 delloconuser( ptlotrs->DRAIN );
162 mbkfree(ptlotrs->DRAIN);
163 if( ptlotrs->BULK ) {
164 delloconuser( ptlotrs->BULK );
165 mbkfree( ptlotrs->BULK );
166 }
167 mbkfree(ptlotrs);
168 }
169 else ptprevlotrs = ptlotrs;
170 }
171
172 /* delete instances marked for deletion */
173 ptprevloins = NULL;
174 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptnextloins) {
175 ptnextloins = ptloins->NEXT;
176 if (ptloins->FIGNAME == NULL) {
177 if (ptprevloins == NULL) ptlofig->LOINS = ptloins->NEXT;
178 else ptprevloins->NEXT = ptloins->NEXT;
179 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptnextlocon) {
180 ptnextlocon = ptlocon->NEXT;
181 delloconuser(ptlocon);
182 mbkfree(ptlocon);
183 }
184 mbkfree(ptloins);
185 }
186 else ptprevloins = ptloins;
187 }
188
189 /* traverse transistors in core figure to identify external connections */
190
191 for (ptlotrs = ptlofig->LOTRS; ptlotrs; ptlotrs = ptlotrs->NEXT) {
192
193 sigarray[0] = ptlotrs->GRID->SIG;
194 sigarray[1] = ptlotrs->SOURCE->SIG;
195 sigarray[2] = ptlotrs->DRAIN->SIG;
196 if (ptlotrs->BULK != NULL) {
197 sigarray[3] = ptlotrs->BULK->SIG;
198 }
199 else sigarray[3] = NULL;
200
201 for (i = 0; i < 4; i++) {
202 ptlosig = sigarray[i];
203 if (ptlosig == NULL) continue;
204 if (ptlosig->TYPE == 'I' && getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
205 ptlosig->TYPE ='E';
206 addlocon(ptlofig, ptlosig->NAMECHAIN->DATA, ptlosig, 'X');
207 if (getptype(ptlosig->USER, YAG_MARKSIG_PTYPE) == NULL) {
208 ptlosig->USER = addptype(ptlosig->USER, YAG_MARKSIG_PTYPE, NULL);
209 }
210 }
211 if (ptlosig->TYPE != 'I' ) {
212 if (getptype(ptlosig->USER, YAG_MARKSIG_PTYPE) == NULL) {
213 ptlosig->USER = addptype(ptlosig->USER, YAG_MARKSIG_PTYPE, NULL);
214 }
215 }
216 }
217 }
218 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptloins->NEXT) {
219 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
220 ptlosig = ptlocon->SIG;
221 if (ptlosig->TYPE == 'I' && getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
222 ptlosig->TYPE ='E';
223 addlocon(ptlofig, ptlosig->NAMECHAIN->DATA, ptlosig, 'X');
224 if (getptype(ptlosig->USER, YAG_MARKSIG_PTYPE) == NULL) {
225 ptlosig->USER = addptype(ptlosig->USER, YAG_MARKSIG_PTYPE, NULL);
226 }
227 }
228 if (ptlosig->TYPE != 'I' ) {
229 if (getptype(ptlosig->USER, YAG_MARKSIG_PTYPE) == NULL) {
230 ptlosig->USER = addptype(ptlosig->USER, YAG_MARKSIG_PTYPE, NULL);
231 }
232 }
233 }
234 }
235
236 /* remove unwanted external connections and sort the rest */
237
238 yagInitLoconVect();
239 oldloconlist = ptlofig->LOCON;
240 ptlofig->LOCON = NULL;
241 for (ptlocon = oldloconlist; ptlocon; ptlocon = ptnextlocon) {
242 ptnextlocon = ptlocon->NEXT;
243 if (getptype(ptlocon->SIG->USER, YAG_MARKSIG_PTYPE) != NULL) {
244 yagAddGivenLoconVect(ptlofig, ptlocon, YAG_VECTO);
245 }
246 else {
247 if (ptlocon->PNODE) delrcnlocon(ptlocon);
248 delloconuser(ptlocon);
249 mbkfree(ptlocon);
250 }
251 }
252 yagCloseLoconVect();
253 /*ptlofig->LOCON = (locon_list *)reverse((chain_list *)ptlofig->LOCON);*/
254
255 /* add core instance */
256
257 sigchain = NULL;
258 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
259 ptlosig = ptlocon->SIG;
260 if ((ptuser = getptype(ptlosig->USER, YAG_TOPSIG_PTYPE)) != NULL) {
261 pttopsig = (losig_list *)ptuser->DATA;
262 }
263 else {
264 ptlosig->USER = delptype(ptlosig->USER, YAG_MARKSIG_PTYPE);
265 pttopsig = getExtSigFromName(*ptpttopfig, ptlosig->NAMECHAIN->DATA);
266 }
267 sigchain = addchain(sigchain, pttopsig);
268 }
269 sigchain = reverse(sigchain);
270 sprintf(buf, "ins_%s", ptlofig->NAME);
271 ptcoreins = addloins(*ptpttopfig, namealloc(buf), ptlofig, sigchain);
272 freechain(sigchain);
273 ptlofig->LOCON = (locon_list *)reverse((chain_list *)ptlofig->LOCON);
274
275 /* delete old signals connected only on instances */
276
277 lofigchain( ptlofig );
278 for (ptchain = insextsigchain; ptchain; ptchain = ptchain->NEXT) {
279 ptlosig = (losig_list *)ptchain->DATA;
280 if (getptype(ptlosig->USER, YAG_MARKSIG_PTYPE) == NULL) {
281 savechain = (chain_list *)getptype(ptlosig->USER, LOFIGCHAIN)->DATA;
282 freeptype(ptlosig->USER);
283 ptlosig->USER = NULL;
284 ptlosig->USER = addptype(ptlosig->USER, LOFIGCHAIN, savechain);
285 dellosig(ptlofig, ptlosig->INDEX);
286 }
287 else ptlosig->USER = delptype(ptlosig->USER, YAG_MARKSIG_PTYPE);
288 }
289
290 /* delete unused signals */
291 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
292 ptchain = (chain_list *)getptype(ptlosig->USER, LOFIGCHAIN)->DATA;
293 if (yagCountChains(ptchain) == 0) {
294 if (ptlosig == ptlofig->LOSIG) {
295 ptlofig->LOSIG = ptlosig->NEXT;
296 }
297 else ptprevsig->NEXT = ptlosig->NEXT;
298 ptlosig->INDEX = 0;
299 }
300 else ptprevsig = ptlosig;
301 }
302
303 /* restore power supply markings */
304 yagFindSupplies(ifl, ptlofig, TRUE);
305 yagFindInternalSupplies(ifl, ptlofig, TRUE);
306
307 return ptlofig;
308 }
309
310 /****************************************************************************
311 * function transferLotrsInsfig() *
312 ****************************************************************************/
313 /* transfer transistors from old figure to new instance figures */
314
315 static void
316 transferLotrsInsfig(loins_list *ptgnsloins, lofig_list *ptinsfig, lofig_list *ptlofig, int copytrans)
317 {
318 chain_list *translist;
319 ptype_list *ptuser;
320 chain_list *ptchain;
321 lotrs_list *ptlotrs;
322 losig_list *ptlosig;
323 losig_list *ptprevious = NULL;
324 losig_list *ptgridsig, *ptsourcesig, *ptdrainsig, *ptbulksig;
325
326 ptuser = getptype(ptgnsloins->USER, FCL_TRANSLIST_PTYPE);
327 if (ptuser == NULL) {
328 yagBug(DBG_NULL_PTR, "markLotrsLoins", NULL, NULL, 0);
329 }
330 translist = (chain_list *)ptuser->DATA;
331
332 if (copytrans) inssight = addht(1000);
333
334 for (ptchain = translist; ptchain; ptchain = ptchain->NEXT) {
335 ptlotrs = (lotrs_list *)ptchain->DATA;
336
337 if (copytrans) {
338 ptlosig = ptlotrs->GRID->SIG;
339 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
340 ptgridsig = getExtSigFromName(ptinsfig, (char *)ptlosig->NAMECHAIN->DATA);
341 }
342 else ptgridsig = giveLoinsLosig(ptinsfig, ptlosig);
343
344 ptlosig = ptlotrs->SOURCE->SIG;
345 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
346 ptsourcesig = getExtSigFromName(ptinsfig, (char *)ptlosig->NAMECHAIN->DATA);
347 }
348 else ptsourcesig = giveLoinsLosig(ptinsfig, ptlosig);
349
350 ptlosig = ptlotrs->DRAIN->SIG;
351 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
352 ptdrainsig = getExtSigFromName(ptinsfig, (char *)ptlosig->NAMECHAIN->DATA);
353 }
354 else ptdrainsig = giveLoinsLosig(ptinsfig, ptlosig);
355
356 if (ptlotrs->BULK != NULL) {
357 ptlosig = ptlotrs->BULK->SIG;
358 if (ptlosig == NULL) ptbulksig = NULL;
359 else if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
360 ptbulksig = getExtSigFromName(ptinsfig, (char *)ptlosig->NAMECHAIN->DATA);
361 }
362 else ptbulksig = giveLoinsLosig(ptinsfig, ptlosig);
363 }
364 else ptbulksig = NULL;
365
366 addlotrs(ptinsfig, ptlotrs->TYPE, ptlotrs->X, ptlotrs->Y,
367 ptlotrs->WIDTH, ptlotrs->LENGTH, ptlotrs->PS, ptlotrs->PD,
368 ptlotrs->XS, ptlotrs->XD,
369 ptgridsig, ptsourcesig, ptdrainsig, ptbulksig, ptlotrs->TRNAME);
370 }
371
372 /* mark transistor for deletion */
373 ptlotrs->TYPE = 0;
374 }
375
376 /* delete corresponding signal in old lofig except for internal supplies */
377
378 if (copytrans) {
379 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
380 if (gethtitem(inssight, (void *)ptlosig->INDEX) != EMPTYHT && (ptlosig->TYPE == 'I' || ptlosig->TYPE == 'E')) {
381 if (ptlosig == ptlofig->LOSIG) {
382 ptlofig->LOSIG = ptlosig->NEXT;
383 }
384 else ptprevious->NEXT = ptlosig->NEXT;
385 ptlosig->INDEX = 0;
386 }
387 else ptprevious = ptlosig;
388 }
389 }
390
391 if (copytrans) delht(inssight);
392 }
393
394 /****************************************************************************
395 * function transferLoinsInsfig() *
396 ****************************************************************************/
397 /* transfer instances from old figure to new instance figures */
398
399 static void
400 transferLoinsInsfig(loins_list *ptgnsloins, lofig_list *ptinsfig, lofig_list *ptlofig, int copytrans)
401 {
402 chain_list *inslist;
403 ptype_list *ptuser;
404 chain_list *ptchain;
405 chain_list *sigchain = NULL;
406 loins_list *ptloins;
407 locon_list *ptlocon;
408 losig_list *ptlosig;
409 losig_list *ptprevious = NULL;
410
411 ptuser = getptype(ptgnsloins->USER, FCL_INSLIST_PTYPE);
412 if (ptuser == NULL) return;
413 inslist = (chain_list *)ptuser->DATA;
414
415 if (copytrans) inssight = addht(1000);
416
417 for (ptchain = inslist; ptchain; ptchain = ptchain->NEXT) {
418 ptloins = (loins_list *)ptchain->DATA;
419
420 if (copytrans) {
421 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
422 ptlosig = ptlocon->SIG;
423 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
424 sigchain = addchain(sigchain, getExtSigFromName(ptinsfig, (char *)ptlosig->NAMECHAIN->DATA));
425 }
426 else sigchain = addchain(sigchain, giveLoinsLosig(ptinsfig, ptlosig));
427 }
428 sigchain = reverse(sigchain);
429 addloins(ptinsfig, ptloins->INSNAME, getlofig(ptloins->FIGNAME, 'P'), sigchain);
430 }
431
432 /* mark instance for deletion */
433 ptloins->FIGNAME = NULL;
434 }
435
436 /* delete corresponding signal in old lofig except for internal supplies */
437
438 if (copytrans) {
439 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
440 if (gethtitem(inssight, (void *)ptlosig->INDEX) != EMPTYHT && (ptlosig->TYPE == 'I' || ptlosig->TYPE == 'E')) {
441 if (ptlosig == ptlofig->LOSIG) {
442 ptlofig->LOSIG = ptlosig->NEXT;
443 }
444 else ptprevious->NEXT = ptlosig->NEXT;
445 ptlosig->INDEX = 0;
446 }
447 else ptprevious = ptlosig;
448 }
449 }
450
451 if (copytrans) delht(inssight);
452 }
453
454 /****************************************************************************
455 * function createTopLosig() *
456 ****************************************************************************/
457 /* create signals in top figure for connecting an instance */
458
459 static void
460 createTopLosig(loins_list *ptloins, lofig_list *pttoplofig)
461 {
462 losig_list *ptlosig;
463 losig_list *pttopsig;
464 locon_list *ptlocon;
465
466 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
467 ptlosig = ptlocon->SIG;
468 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) == NULL) {
469 if ((ptlosig->TYPE == 'E') || (ptlosig->TYPE == 'D') || (ptlosig->TYPE == 'S')) {
470 pttopsig = getExtSigFromName(pttoplofig, (char *)ptlosig->NAMECHAIN->DATA);
471 }
472 if ((ptlosig->TYPE == 'I') || (pttopsig == NULL)) {
473 pttopsig = yagAddLosigVect(pttoplofig, topsigindex++, addchain(NULL, ptlosig->NAMECHAIN->DATA), 'I');
474 mbk_copylosiginfo(ptlosig, pttopsig);
475 }
476 ptlosig->USER = addptype(ptlosig->USER, YAG_TOPSIG_PTYPE, pttopsig);
477 insextsigchain = addchain(insextsigchain, ptlosig);
478 }
479 }
480 }
481
482 /****************************************************************************
483 * function createTopLofig() *
484 ****************************************************************************/
485 /* create interface of top figure */
486
487 static lofig_list *
488 createTopLofig(lofig_list *ptlofig, char *name)
489 {
490 lofig_list *pttoplofig;
491 locon_list *ptlocon;
492 losig_list *ptlosig;
493 losig_list *pttopsig;
494
495 pttoplofig = addlofig(name);
496
497 topsigindex = 1;
498
499 yagInitLoconVect();
500 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
501 ptlosig = ptlocon->SIG;
502 pttopsig = addlosig(pttoplofig, topsigindex++, addchain(NULL, ptlosig->NAMECHAIN->DATA), ptlosig->TYPE);
503 mbk_copylosiginfo(ptlosig, pttopsig);
504 yagAddLoconVect(pttoplofig, ptlocon->NAME, pttopsig, ptlocon->DIRECTION, YAG_VECTO, NULL, NULL);
505 }
506 /*pttoplofig->LOCON = (locon_list *)reverse((chain_list *)pttoplofig->LOCON);*/
507 yagCloseLoconVect();
508 return pttoplofig;
509 }
510
511 /****************************************************************************
512 * function getExtSigFromName() *
513 ****************************************************************************/
514 /* find an external signal given its name */
515
516 static losig_list *
517 getExtSigFromName(lofig_list *ptlofig, char *name)
518 {
519 locon_list *ptlocon;
520 losig_list *ptlosig;
521
522 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
523 ptlosig = ptlocon->SIG;
524 if (name == (char *)ptlosig->NAMECHAIN->DATA) return ptlosig;
525 }
526 return NULL;
527 }
528
529 /****************************************************************************
530 * function giveInstanceLofig() *
531 ****************************************************************************/
532 /* create external interface of an instance figure */
533
534 static lofig_list *
535 giveInstanceLofig(loins_list *ptloins, int copytrans)
536 {
537 locon_list *ptlocon;
538 lofig_list *ptinslofig;
539 losig_list *ptlosig;
540
541 if (copytrans) {
542 ptinslofig = addlofig(ptloins->INSNAME);
543 }
544 else {
545 if ((ptinslofig = getloadedlofig(ptloins->FIGNAME)) == NULL) {
546 ptinslofig = addlofig(ptloins->FIGNAME);
547 }
548 else return ptinslofig;
549 }
550
551 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
552 ptlosig = addlosig(ptinslofig, inssigindex++, addchain(NULL, ptlocon->NAME), 'E');
553 addlocon(ptinslofig, ptlocon->NAME, ptlosig, ptlocon->DIRECTION);
554 }
555 ptinslofig->LOCON = (locon_list *)reverse((chain_list *)ptinslofig->LOCON);
556
557 return ptinslofig;
558 }
559
560 /****************************************************************************
561 * function giveLoinsLosig() *
562 ****************************************************************************/
563 /* given a signal index in old figure return corresponding */
564 /* signal in an instance figure. The hash table is checked */
565 /* to see if signal already created. if not then it is */
566 /* created it and correspondance is added to hash table */
567
568 static losig_list *
569 giveLoinsLosig(lofig_list *ptinsfig, losig_list *ptoldsig)
570 {
571 losig_list *ptinssig;
572
573 ptinssig = (losig_list *)gethtitem(inssight, (void *)ptoldsig->INDEX);
574 if (ptinssig == (losig_list *)EMPTYHT) {
575 ptinssig = addlosig(ptinsfig, inssigindex++, addchain(NULL, ptoldsig->NAMECHAIN->DATA), 'I');
576 addhtitem(inssight, (void *)ptoldsig->INDEX, (long)ptinssig);
577 }
578 return ptinssig;
579 }
580
581 /****************************************************************************
582 * function yagBuildGeniusBehHierarchy() *
583 ****************************************************************************/
584 /* build structural figure for behavioural hierarchy */
585
586 lofig_list *
587 yagBuildGeniusBehHierarchy(lofig_list *pttoplofig, lofig_list *ptcorelofig, chain_list *instances, char *name)
588 {
589 lofig_list *hBehFig;
590 loins_list *ptrecins;
591 loins_list *ptloins;
592 chain_list *ptchain;
593 locon_list *ptextcon;
594 locon_list *ptlocon;
595 losig_list *ptlosig;
596 chain_list *loconchain;
597 int direction;
598 // char buf[YAGBUFSIZE];
599
600 /* duplicate logical hierarchical figure */
601
602 hBehFig = rduplofig(pttoplofig);
603 delhtitem(HT_LOFIG, hBehFig->NAME);
604 hBehFig->NAME = namealloc(name);
605 addhtitem(HT_LOFIG, hBehFig->NAME, (long)hBehFig);
606 lofigchain(hBehFig);
607
608 /* group instances with identical models unless already done */
609
610 if (hBehFig->LOINS->FIGNAME == hBehFig->LOINS->INSNAME) {
611 for (ptchain = instances; ptchain; ptchain = ptchain->NEXT) {
612 ptrecins = (loins_list *)ptchain->DATA;
613 for (ptloins = hBehFig->LOINS; ptloins; ptloins = ptloins->NEXT) {
614 if (ptloins->INSNAME == ptrecins->INSNAME) break;
615 }
616 if (ptloins != NULL) ptloins->FIGNAME = ptrecins->FIGNAME;
617 }
618 }
619
620 /* orient the core instance */
621
622 ptcorelofig->LOCON = (locon_list *)reverse((chain_list *)ptcorelofig->LOCON);
623 for (ptloins = hBehFig->LOINS; ptloins; ptloins = ptloins->NEXT) {
624 if (ptloins->FIGNAME == ptcorelofig->NAME) break;
625 }
626 if (ptloins != NULL) {
627 ptextcon = ptcorelofig->LOCON;
628 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
629 ptlocon->DIRECTION = ptextcon->DIRECTION;
630 if (ptlocon->DIRECTION == 'D' || ptlocon->DIRECTION == 'S' || ptlocon->DIRECTION == 'X') {
631 ptlocon->DIRECTION = 'I';
632 }
633 ptextcon = ptextcon->NEXT;
634 }
635 }
636 ptcorelofig->LOCON = (locon_list *)reverse((chain_list *)ptcorelofig->LOCON);
637
638 /* orient the interface */
639
640 for (ptextcon = hBehFig->LOCON; ptextcon; ptextcon = ptextcon->NEXT) {
641 direction = 0;
642 ptlosig = ptextcon->SIG;
643 loconchain = (chain_list *)getptype(ptlosig->USER, LOFIGCHAIN)->DATA;
644 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
645 ptlocon = (locon_list *)ptchain->DATA;
646 if (ptlocon->TYPE == 'I') {
647 switch (ptlocon->DIRECTION) {
648 case 'I': direction |= HCON_IN; break;
649 case 'O': direction |= HCON_OUT; break;
650 case 'B': direction |= HCON_INOUT; break;
651 case 'Z': direction |= HCON_OUTHZ; break;
652 case 'T': direction |= HCON_INOUTHZ; break;
653 }
654 }
655 }
656 switch (direction) {
657 case HCON_IN: ptextcon->DIRECTION = 'I'; break;
658 case HCON_OUT: ptextcon->DIRECTION = 'O'; break;
659 case HCON_INOUT: ptextcon->DIRECTION = 'B'; break;
660 case HCON_OUTHZ: ptextcon->DIRECTION = 'Z'; break;
661 case HCON_INOUTHZ: ptextcon->DIRECTION = 'T'; break;
662 }
663 }
664
665 /* update model chain */
666
667 freechain (hBehFig->MODELCHAIN);
668 hBehFig->MODELCHAIN = NULL;
669
670 for (ptloins = hBehFig->LOINS; ptloins != NULL; ptloins = ptloins->NEXT) {
671 for (ptchain = hBehFig->MODELCHAIN; ptchain != NULL; ptchain = ptchain->NEXT)
672 if (ptchain->DATA == ptloins->FIGNAME)
673 break;
674 if (ptchain == NULL)
675 hBehFig->MODELCHAIN = addchain (hBehFig->MODELCHAIN, ptloins->FIGNAME);
676 }
677
678 return hBehFig;
679 }