Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / yagle / yag_hierbeh.c
1 /****************************************************************************/
2 /* */
3 /* Produit : YAGLE v3.50 */
4 /* Fichier : yag_hierbeh.c */
5 /* */
6 /* Auteur(s) : Anthony LESTER le : 01/08/1999 */
7 /* */
8 /* Modifie par : le : ../../.... */
9 /* Modifie par : le : ../../.... */
10 /* Modifie par : le : ../../.... */
11 /* */
12 /****************************************************************************/
13
14 #include "yag_headers.h"
15
16 static void createTopLosig(loins_list *ptloins, lofig_list *pttoplofig);
17 static lofig_list *createTopLofig(lofig_list *ptlofig, char *name);
18 static losig_list *getExtSigFromName(lofig_list *ptlofig, char *name);
19 static lofig_list *giveInstanceLofig(loins_list *ptloins, int copytrans);
20
21 static long inssigindex;
22 static long topsigindex;
23
24 /****************************************************************************
25 * function yagSortModeledInstances() *
26 ****************************************************************************/
27 /* obtain list of instances without befig */
28 void
29 yagSortModeledInstances(lofig_list *ptlofig, chain_list **ptmodeled, chain_list **ptunmodeled)
30 {
31 befig_list *ptbefig;
32 loins_list *ptloins;
33 ht *befight;
34 chain_list *ptchain;
35 ptype_list *ptuser;
36
37 befight = addht(40);
38 for (ptchain = YAG_CONTEXT->YAGLE_INSTANCE_BEFIGS; ptchain; ptchain = ptchain->NEXT) {
39 ptbefig = (befig_list *)ptchain->DATA;
40 addhtitem(befight, ptbefig->NAME, 0);
41 }
42 for (ptloins = ptlofig->LOINS; ptloins; ptloins = ptloins->NEXT) {
43 ptuser = getptype(ptloins->USER, FCL_TRANSFER_PTYPE);
44 if (ptuser != NULL) {
45 if (((long)ptuser->DATA & FCL_NEVER) != 0) continue;
46 }
47 if (gethtitem(befight, ptloins->INSNAME) == EMPTYHT) {
48 *ptunmodeled = addchain(*ptunmodeled, ptloins);
49 }
50 else *ptmodeled = addchain(*ptmodeled, ptloins);
51 }
52 delht(befight);
53 }
54
55 /****************************************************************************
56 * function yagBuildHierarchy() *
57 ****************************************************************************/
58 /* create hierarchical figure from given instances */
59
60 lofig_list *
61 yagBuildHierarchy(cnsfig_list *ptcnsfig, lofig_list *ptlofig, lofig_list **ptptrootlofig, chain_list *instances)
62 {
63 lofig_list *ptcorelofig;
64 chain_list *ptchain;
65 chain_list *loconchain;
66 lotrs_list *pttrans;
67 loins_list *ptloins;
68 lofig_list *ptinsfig;
69 losig_list *pttopsig;
70 losig_list *ptlosig;
71 locon_list *ptlocon;
72 locon_list *ptintcon;
73 chain_list *sigchain;
74 ptype_list *ptuser;
75 loins_list *ptcoreins;
76 char buf[YAGBUFSIZE];
77 char *outname;
78
79 strcpy(buf, ptlofig->NAME);
80 strcat(buf, "_yagcore");
81 ptcorelofig = addlofig(namealloc(buf));
82
83
84 if (YAG_CONTEXT->YAG_OUTNAME == ptlofig->NAME) {
85 if (getenv("YAGLE_OUT_NAME"))
86 avt_errmsg(YAG_ERRMSG,"009",AVT_WARNING,outname);
87 strcpy(buf, ptlofig->NAME);
88 strcat(buf, "_yagroot");
89 outname = buf;
90 // because it's a ugly definition
91 avt_sethashvar("yagleOutputName",outname);
92 }
93 else
94 outname = YAG_CONTEXT->YAG_OUTNAME;
95
96 *ptptrootlofig = createTopLofig(ptlofig, namealloc(outname));
97
98
99 /* traverse the instances to create corresponding figures */
100
101 yagInitLosigVect();
102 for (ptchain = instances; ptchain; ptchain = ptchain->NEXT) {
103 inssigindex = 1;
104 ptloins = (loins_list *)ptchain->DATA;
105 createTopLosig(ptloins, *ptptrootlofig);
106 sigchain = NULL;
107 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
108 /* remove power supply markings */
109 if (ptlocon->DIRECTION == 'D' || ptlocon->DIRECTION == 'S') ptlocon->DIRECTION = 'I';
110
111 ptlosig = ptlocon->SIG;
112 pttopsig = (losig_list *)getptype(ptlosig->USER, YAG_TOPSIG_PTYPE)->DATA;
113 sigchain = addchain(sigchain, pttopsig);
114 }
115 sigchain = reverse(sigchain);
116 ptinsfig = giveInstanceLofig(ptloins, FALSE);
117 addloins(*ptptrootlofig, ptloins->INSNAME, ptinsfig, sigchain);
118 }
119 yagCloseLosigVect();
120
121 /* traverse external and internal connectors to identify external connections of core */
122
123 for (ptchain = instances; ptchain; ptchain = ptchain->NEXT) {
124 ptloins = (loins_list *)ptchain->DATA;
125 ptloins->USER = addptype(ptloins->USER, YAG_MARKINS_PTYPE, NULL);
126 }
127 yagInitLoconVect();
128 for (ptlocon = ptcnsfig->INTCON; ptlocon; ptlocon = ptlocon->NEXT) {
129 ptlosig = ptlocon->SIG;
130 loconchain = (chain_list *)getptype(ptlosig->USER, LOFIGCHAIN)->DATA;
131 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
132 ptintcon = (locon_list *)ptchain->DATA;
133 if (ptintcon->TYPE == 'I') {
134 ptloins = (loins_list *)ptintcon->ROOT;
135 if (getptype(ptloins->USER, YAG_MARKINS_PTYPE) != NULL) break;
136 }
137 }
138 if (ptchain == NULL) continue;
139 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
140 ptintcon = (locon_list *)ptchain->DATA;
141 if (ptintcon->TYPE == 'T') {
142 pttrans = (lotrs_list *)ptintcon->ROOT;
143 if ((ptuser = getptype(pttrans->USER, FCL_TRANSFER_PTYPE)) != NULL) {
144 if (((long)ptuser->DATA & FCL_NEVER) != 0) continue;
145 }
146 break;
147 }
148 else if (ptintcon->TYPE == 'I') {
149 ptloins = (loins_list *)ptintcon->ROOT;
150 if ((ptuser = getptype(ptloins->USER, FCL_TRANSFER_PTYPE)) != NULL) {
151 if (((long)ptuser->DATA & FCL_NEVER) != 0) continue;
152 }
153 if (getptype(ptloins->USER, YAG_MARKINS_PTYPE) != NULL) continue;
154 break;
155 }
156 }
157 if (ptchain != NULL) {
158 yagAddLoconVect(ptcorelofig, ptlocon->NAME, NULL, ptlocon->DIRECTION, YAG_VECTO, NULL, addptype(NULL, YAG_LOCON_PTYPE, ptlocon));
159 }
160 }
161 for (ptlocon = ptcnsfig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
162 ptlosig = ptlocon->SIG;
163 loconchain = (chain_list *)getptype(ptlosig->USER, LOFIGCHAIN)->DATA;
164 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
165 ptintcon = (locon_list *)ptchain->DATA;
166 if (ptintcon->TYPE == 'T') {
167 pttrans = (lotrs_list *)ptintcon->ROOT;
168 if ((ptuser = getptype(pttrans->USER, FCL_TRANSFER_PTYPE)) != NULL) {
169 if (((long)ptuser->DATA & FCL_NEVER) != 0) continue;
170 }
171 break;
172 }
173 else if (ptintcon->TYPE == 'I') {
174 ptloins = (loins_list *)ptintcon->ROOT;
175 if ((ptuser = getptype(ptloins->USER, FCL_TRANSFER_PTYPE)) != NULL) {
176 if (((long)ptuser->DATA & FCL_NEVER) != 0) continue;
177 }
178 if (getptype(ptloins->USER, YAG_MARKINS_PTYPE) != NULL) continue;
179 break;
180 }
181 }
182 if (ptchain != NULL) {
183 yagAddLoconVect(ptcorelofig, ptlocon->NAME, NULL, ptlocon->DIRECTION, YAG_VECTO, NULL, addptype(NULL, YAG_LOCON_PTYPE, ptlocon));
184 }
185 }
186 yagCloseLoconVect();
187 /*ptcorelofig->LOCON = (locon_list *)reverse((chain_list *)ptcorelofig->LOCON);*/
188 for (ptchain = instances; ptchain; ptchain = ptchain->NEXT) {
189 ptloins = (loins_list *)ptchain->DATA;
190 ptloins->USER = delptype(ptloins->USER, YAG_MARKINS_PTYPE);
191 }
192
193 /* add core instance */
194
195 sigchain = NULL;
196 for (ptlocon = ptcorelofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
197 ptlosig = ((locon_list *)getptype(ptlocon->USER, YAG_LOCON_PTYPE)->DATA)->SIG;
198 if ((ptuser = getptype(ptlosig->USER, YAG_TOPSIG_PTYPE)) != NULL) {
199 pttopsig = (losig_list *)ptuser->DATA;
200 }
201 else {
202 pttopsig = getExtSigFromName(*ptptrootlofig, ptlosig->NAMECHAIN->DATA);
203 }
204 sigchain = addchain(sigchain, pttopsig);
205 }
206 sigchain = reverse(sigchain);
207 sprintf(buf, "ins_%s", ptcorelofig->NAME);
208 ptcoreins = addloins(*ptptrootlofig, namealloc(buf), ptcorelofig, sigchain);
209 freechain(sigchain);
210 for (ptlosig = ptlofig->LOSIG; ptlosig; ptlosig = ptlosig->NEXT) {
211 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) != NULL) {
212 ptlosig->USER = delptype(ptlosig->USER, YAG_TOPSIG_PTYPE);
213 }
214 }
215
216 ptcorelofig->LOCON = (locon_list *)reverse((chain_list *)ptcorelofig->LOCON);
217 return ptcorelofig;
218 }
219
220 /****************************************************************************
221 * function createTopLosig() *
222 ****************************************************************************/
223 /* create signals in top figure for connecting an instance */
224
225 static void
226 createTopLosig(loins_list *ptloins, lofig_list *pttoplofig)
227 {
228 losig_list *ptlosig;
229 losig_list *pttopsig;
230 locon_list *ptlocon;
231
232 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
233 ptlosig = ptlocon->SIG;
234 if (getptype(ptlosig->USER, YAG_TOPSIG_PTYPE) == NULL) {
235 if ((ptlosig->TYPE == 'E') || (ptlosig->TYPE == 'D') || (ptlosig->TYPE == 'S')) {
236 pttopsig = getExtSigFromName(pttoplofig, (char *)ptlosig->NAMECHAIN->DATA);
237 }
238 if ((ptlosig->TYPE == 'I') || (pttopsig == NULL)) {
239 pttopsig = yagAddLosigVect(pttoplofig, topsigindex++, addchain(NULL, ptlosig->NAMECHAIN->DATA), 'I');
240 mbk_copylosiginfo(ptlosig, pttopsig);
241 }
242 ptlosig->USER = addptype(ptlosig->USER, YAG_TOPSIG_PTYPE, pttopsig);
243 }
244 }
245 }
246
247 /****************************************************************************
248 * function createTopLofig() *
249 ****************************************************************************/
250 /* create interface of top figure */
251
252 static lofig_list *
253 createTopLofig(lofig_list *ptlofig, char *name)
254 {
255 lofig_list *pttoplofig;
256 locon_list *ptlocon;
257 losig_list *ptlosig;
258 losig_list *pttopsig;
259
260 pttoplofig = addlofig(name);
261
262 topsigindex = 1;
263
264 yagInitLoconVect();
265 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
266 if (ptlocon->DIRECTION == 'D' || ptlocon->DIRECTION == 'S') ptlocon->DIRECTION = 'I';
267 ptlosig = ptlocon->SIG;
268 pttopsig = addlosig(pttoplofig, topsigindex++, addchain(NULL, ptlosig->NAMECHAIN->DATA), ptlosig->TYPE);
269 mbk_copylosiginfo(ptlosig, pttopsig);
270 yagAddLoconVect(pttoplofig, ptlocon->NAME, pttopsig, ptlocon->DIRECTION, YAG_VECTO, NULL, NULL);
271 }
272 /*pttoplofig->LOCON = (locon_list *)reverse((chain_list *)pttoplofig->LOCON);*/
273 yagCloseLoconVect();
274 return pttoplofig;
275 }
276
277 /****************************************************************************
278 * function getExtSigFromName() *
279 ****************************************************************************/
280 /* find an external signal given its name */
281
282 static losig_list *
283 getExtSigFromName(lofig_list *ptlofig, char *name)
284 {
285 locon_list *ptlocon;
286 losig_list *ptlosig;
287
288 for (ptlocon = ptlofig->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
289 ptlosig = ptlocon->SIG;
290 if (name == (char *)ptlosig->NAMECHAIN->DATA) return ptlosig;
291 }
292 return NULL;
293 }
294
295 /****************************************************************************
296 * function giveInstanceLofig() *
297 ****************************************************************************/
298 /* create external interface of an instance figure */
299
300 static lofig_list *
301 giveInstanceLofig(loins_list *ptloins, int copytrans)
302 {
303 locon_list *ptlocon;
304 lofig_list *ptinslofig;
305 losig_list *ptlosig;
306
307 if (copytrans) {
308 ptinslofig = addlofig(ptloins->INSNAME);
309 }
310 else {
311 if ((ptinslofig = getloadedlofig(ptloins->FIGNAME)) == NULL) {
312 ptinslofig = addlofig(ptloins->FIGNAME);
313 }
314 else return ptinslofig;
315 }
316
317 for (ptlocon = ptloins->LOCON; ptlocon; ptlocon = ptlocon->NEXT) {
318 ptlosig = addlosig(ptinslofig, inssigindex++, addchain(NULL, ptlocon->NAME), 'E');
319 addlocon(ptinslofig, ptlocon->NAME, ptlosig, ptlocon->DIRECTION);
320 }
321 /* ptinslofig->LOCON = (locon_list *)reverse((chain_list *)ptinslofig->LOCON); */
322
323 return ptinslofig;
324 }
325
326 /*---------------------------------------------------------------------------*
327 | Guess Connector direction |
328 *----------------------------------------------------------------------------*/
329 void
330 yagGuessRootConnectorDirections(lofig_list *ptrootlofig)
331 {
332 #define DIRONSIG_PTYPE 0xfab50420
333 #define POWINFO_PTYPE 0xfab50421
334 #define DIRONSIG_IN 1
335 #define DIRONSIG_OUT 2
336 #define EXTDIRONSIG_IN 4
337 #define EXTDIRONSIG_OUT 8
338 #define ALIMSIG 16
339
340 loins_list *li, *li0;
341 lofig_list *inslf;
342 locon_list *lc, *lc0;
343 losig_list *ls;
344 ht *fight;
345 ptype_list *pt, *pt0;
346 chain_list *cl, *ch;
347 long l;
348
349 for (li=ptrootlofig->LOINS; li!=NULL && strstr(li->INSNAME,"_yagcore")==NULL; li=li->NEXT) ;
350
351 if (li!=NULL) {
352 for (ls=ptrootlofig->LOSIG; ls!=NULL; ls=ls->NEXT) {
353 ls->USER=addptype(ls->USER, DIRONSIG_PTYPE, 0);
354 }
355
356 for (lc=li->LOCON; lc!=NULL; lc=lc->NEXT) {
357 pt=getptype(lc->SIG->USER, DIRONSIG_PTYPE);
358 l=(long)pt->DATA;
359 if (lc->DIRECTION==IN) l|=DIRONSIG_IN;
360 else if (lc->DIRECTION==OUT || lc->DIRECTION==INOUT || lc->DIRECTION==TRISTATE) l|=DIRONSIG_OUT;
361 else if (lc->DIRECTION!=UNKNOWN) l|=DIRONSIG_IN|DIRONSIG_OUT;
362 if (mbk_LosigIsVDD(lc->SIG) || mbk_LosigIsVSS(lc->SIG)) l|=ALIMSIG;
363 pt->DATA=(void *)l;
364 }
365
366 for (lc=ptrootlofig->LOCON; lc!=NULL; lc=lc->NEXT) {
367 pt=getptype(lc->SIG->USER, DIRONSIG_PTYPE);
368 l=(long)pt->DATA;
369 if (lc->DIRECTION==IN) l|=EXTDIRONSIG_IN;
370 else if (lc->DIRECTION==OUT || lc->DIRECTION==INOUT || lc->DIRECTION==TRISTATE) l|=EXTDIRONSIG_OUT;
371 if (mbk_LosigIsVDD(lc->SIG) || mbk_LosigIsVSS(lc->SIG)) {
372 l|=ALIMSIG;
373 if (lc->DIRECTION==UNKNOWN) lc->DIRECTION=IN;
374 }
375 pt->DATA=(void *)l;
376 }
377
378 fight=addht(10);
379
380 for (li0=ptrootlofig->LOINS; li0!=NULL; li0=li0->NEXT)
381 {
382 if (li0!=li && (inslf=getloadedlofig(li0->FIGNAME))!=NULL)
383 {
384 addhtitem(fight, li0->FIGNAME, (long)inslf);
385 for (lc=inslf->LOCON, lc0=li0->LOCON; lc!=NULL && lc0!=NULL; lc=lc->NEXT, lc0=lc0->NEXT)
386 {
387 if ((pt=getptype(lc->SIG->USER, DIRONSIG_PTYPE))==NULL)
388 pt=lc->USER=addptype(lc->USER, DIRONSIG_PTYPE, 0);
389 pt0=getptype(lc0->SIG->USER, DIRONSIG_PTYPE);
390 l=(long)pt->DATA | (long)pt0->DATA;
391 pt->DATA=(void *)l;
392 }
393 }
394 }
395
396 for (lc=ptrootlofig->LOCON; lc!=NULL; lc=lc->NEXT)
397 {
398 if (lc->DIRECTION==UNKNOWN)
399 {
400 pt=getptype(lc->SIG->USER, DIRONSIG_PTYPE);
401 l=(long)pt->DATA;
402 if (!((l & (DIRONSIG_IN|DIRONSIG_OUT))==(DIRONSIG_IN|DIRONSIG_OUT)))
403 {
404 if ((l & DIRONSIG_IN)==DIRONSIG_IN) lc->DIRECTION=IN;
405 else if ((l & DIRONSIG_OUT)==DIRONSIG_OUT) lc->DIRECTION=OUT;
406 else lc->DIRECTION=IN;
407 }
408 }
409 }
410
411 for (ls=ptrootlofig->LOSIG; ls!=NULL; ls=ls->NEXT)
412 {
413 ls->USER=delptype(ls->USER, DIRONSIG_PTYPE);
414 }
415
416 for (cl=ch=GetAllHTElems(fight); cl!=NULL; cl=cl->NEXT)
417 {
418 inslf=(lofig_list *)cl->DATA;
419 for (lc=inslf->LOCON; lc!=NULL; lc=lc->NEXT)
420 {
421 if (mbk_LosigIsVDD(lc->SIG) || mbk_LosigIsVSS(lc->SIG))
422 lc->DIRECTION=IN;
423 else if (lc->DIRECTION==UNKNOWN)
424 {
425 pt=getptype(lc->USER, DIRONSIG_PTYPE);
426 l=(long)pt->DATA;
427 if ((l & ALIMSIG)==ALIMSIG) lc->DIRECTION=IN;
428 else if ((l & (DIRONSIG_IN|DIRONSIG_OUT))==(DIRONSIG_IN|DIRONSIG_OUT))
429 lc->DIRECTION=TRANSCV; //INOUT;
430 else if ((l & DIRONSIG_IN)==DIRONSIG_IN)
431 if ((l & EXTDIRONSIG_IN)==EXTDIRONSIG_IN)
432 lc->DIRECTION=IN;
433 else
434 lc->DIRECTION=OUT;
435 else if ((l & DIRONSIG_OUT)==DIRONSIG_OUT)
436 if ((l & EXTDIRONSIG_IN)==EXTDIRONSIG_IN)
437 lc->DIRECTION=OUT;
438 else
439 lc->DIRECTION=IN;
440 else
441 lc->DIRECTION=IN; // i don't know
442 }
443 lc->USER=delptype(lc->USER, DIRONSIG_PTYPE);
444 }
445 }
446 freechain(ch);
447 delht(fight);
448
449 for (li0=ptrootlofig->LOINS; li0!=NULL; li0=li0->NEXT)
450 if (li0!=li && (inslf=getloadedlofig(li0->FIGNAME))!=NULL)
451 for (lc=inslf->LOCON, lc0=li0->LOCON; lc!=NULL && lc0!=NULL; lc=lc->NEXT, lc0=lc0->NEXT)
452 lc0->DIRECTION=lc->DIRECTION;
453 }
454 #undef DIRONSIG_PTYPE
455 #undef POWINFO_PTYPE
456 #undef DIRONSIG_IN
457 #undef DIRONSIG_OUT
458 #undef EXTDIRONSIG_IN
459 #undef EXTDIRONSIG_OUT
460 #undef ALIMSIG
461 }