Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / api / tcl / avt_netlist.c
1 #include <stdio.h>
2 #include AVT_H
3 #include MUT_H
4 #include SPE_H
5 #include MSL_H
6 #include MLU_H
7 #include MCC_H
8 #include SIM_H
9
10 lofig_list *avt_GetNetlist(char *name)
11 {
12 lofig_list *fig = getloadedlofig(name);
13 float max_global_supply;
14
15 if (!fig) {
16 avt_errmsg(AVT_API_ERRMSG, "001", AVT_WARNING, name);
17 // fprintf (stdout, "ERROR: '%s' is not among the loaded netlists\n", name);
18 return NULL;
19 }
20
21 if (V_FLOAT_TAB[__SIM_POWER_SUPPLY].SET==0 && mbk_GetPowerSupply (fig, &max_global_supply))
22 MCC_VDDmax = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE = elpGeneral[elpGVDDMAX] = max_global_supply;
23
24 return fig;
25 }
26
27 void avt_DriveNetlist(lofig_list *lf, char *filename, char *format)
28 {
29 FILE *f;
30 int error=0;
31
32 if (lf==NULL) return;
33
34 if (strcasecmp(format,"spice")==0)
35 {
36 if ((f=mbkfopen(filename,NULL,WRITE_TEXT))!=NULL)
37 {
38 spicesavelofiginfile(lf, f, 0);
39 fclose(f);
40 }
41 else error=1;
42 }
43 else if (strcasecmp(format,"verilog")==0)
44 {
45 if ((f=mbkfopen(filename,NULL,WRITE_TEXT))!=NULL)
46 {
47 vlogsavelofig(lf, f);
48 fclose(f);
49 }
50 else error=1;
51 }
52 else if (strcasecmp(format,"vhdl")==0)
53 {
54 if ((f=mbkfopen(filename,NULL,WRITE_TEXT))!=NULL)
55 {
56 vhdlsavelofig(lf, f);
57 fclose(f);
58 }
59 else error=1;
60 }
61 else if (strcasecmp(format,"spef")==0)
62 {
63 if ((f=mbkfopen(filename,NULL,WRITE_TEXT))!=NULL)
64 {
65 spef_drive(lf, f);
66 fclose(f);
67 }
68 else error=1;
69 }
70 else
71 avt_errmsg(AVT_API_ERRMSG, "002", AVT_ERROR, format, filename);
72 // avt_error("avtapi", 2, AVT_ERROR, "unknown file format '%s' for '%s'\n", format, filename);
73
74 if (error)
75 avt_errmsg(AVT_API_ERRMSG, "003", AVT_ERROR, filename);
76 // avt_error("avtapi", 2, AVT_ERROR, "could not create file '%s'\n", filename);
77 }
78
79 void avt_DriveSignalInfo( lofig_list *lf, char *nameregex, char *filename )
80 {
81 losig_list *losig ;
82 chain_list *chain ;
83 FILE *ptf ;
84 num_list *node ;
85 ptype_list *ptl ;
86 chain_list *chlocon ;
87 locon_list *locon ;
88 chain_list *chnodename ;
89 char *name ;
90 lowire_list *wire ;
91 char s1[256], s2[256] ;
92 lonode_list *ptnode ;
93 chain_list *chctc ;
94 loctc_list *ctc ;
95 char needsepar='n';
96
97 if( lf == NULL )
98 return ;
99
100 ptf = mbkfopen( filename, NULL, WRITE_TEXT );
101 if( !ptf ) {
102 avt_errmsg(AVT_API_ERRMSG, "003", AVT_ERROR, filename);
103 //avt_error("avtapi", 2, AVT_ERROR, "could not create file '%s'\n", filename);
104 return ;
105 }
106
107 for( losig = lf->LOSIG ; losig ; losig = losig->NEXT ) {
108
109 for( chain = losig->NAMECHAIN ; chain ; chain = chain->NEXT ) {
110 if( mbk_TestREGEX( (char*)chain->DATA, nameregex ) )
111 break ;
112 }
113
114 if( chain ) {
115
116 if( needsepar == 'y' ) {
117 fprintf( ptf, "\n-------------------------------------------------\n\n" );
118 }
119 needsepar = 'y' ;
120
121 fprintf( ptf, "Signal %s\n\n", getsigname( losig ) );
122
123 ptl = getptype( losig->USER, LOFIGCHAIN );
124 if( ptl ) {
125 fprintf( ptf, "Connector list :\n\n" );
126 for( chlocon = (chain_list*)ptl->DATA ; chlocon ; chlocon = chlocon->NEXT ) {
127 locon = (locon_list*)chlocon->DATA ;
128 switch( locon->TYPE ) {
129 case 'I' :
130 fprintf( ptf, "instance %s", ((loins_list*)locon->ROOT)->INSNAME );
131 break ;
132 case 'E' :
133 fprintf( ptf, "external" );
134 break ;
135 case 'T' :
136 fprintf( ptf, "transistor %s", ((lotrs_list*)locon->ROOT)->TRNAME );
137 break ;
138 default :
139 fprintf( ptf, "unknown" );
140 }
141 fprintf( ptf, " -> %s\n", locon->NAME );
142
143 ptl = getptype( locon->USER, PNODENAME );
144 if( ptl )
145 chnodename = (chain_list*)ptl->DATA ;
146 else
147 chnodename = NULL ;
148
149 for( node = locon->PNODE ; node ; node = node->NEXT ) {
150 if( chnodename )
151 name = (char*)chnodename->DATA ;
152 else
153 name = "";
154 fprintf( ptf, " %ld %s\n", node->DATA, name );
155 if( chnodename )
156 chnodename = chnodename->NEXT ;
157 }
158 }
159 fprintf( ptf, "\n" );
160 }
161 else {
162 fprintf( ptf, "No connector on this signal\n\n" );
163 }
164
165 if( losig->PRCN ) {
166
167 for( wire = losig->PRCN->PWIRE ; wire ; wire = wire->NEXT ) {
168 ptnode = getlonode( losig, wire->NODE1 );
169 if( RCN_GETFLAG( ptnode->FLAG, RCN_FLAG_LOCON ) )
170 sprintf( s1, "%4ld*", ptnode->INDEX );
171 else
172 sprintf( s1, "%4ld ", ptnode->INDEX );
173 ptnode = getlonode( losig, wire->NODE2 );
174 if( RCN_GETFLAG( ptnode->FLAG, RCN_FLAG_LOCON ) )
175 sprintf( s2, "%4ld*", ptnode->INDEX );
176 else
177 sprintf( s2, "%4ld ", ptnode->INDEX );
178 fprintf( ptf, "w %s %s %g\n", s1, s2, wire->RESI );
179 }
180 fprintf( ptf, "\n" );
181
182 for( chctc = losig->PRCN->PCTC ; chctc ; chctc = chctc->NEXT ) {
183 ctc = (loctc_list*)chctc->DATA ;
184 ptnode = getlonode( losig, rcn_ctcnode( ctc, losig ) );
185 if( RCN_GETFLAG( ptnode->FLAG, RCN_FLAG_LOCON ) )
186 sprintf( s1, "%4ld*", ptnode->INDEX );
187 else
188 sprintf( s1, "%4ld ", ptnode->INDEX );
189 fprintf( ptf, "c %s %g\n", s1, ctc->CAPA );
190 }
191 }
192 }
193 }
194
195 fclose( ptf );
196 }
197
198 void avt_RemoveCapacitances(lofig_list *lf, char *nameregex)
199 {
200 losig_list *ls;
201 chain_list *cl;
202
203 if (lf==NULL) return;
204
205 for (ls=lf->LOSIG; ls!=NULL; ls=ls->NEXT)
206 {
207 if (ls->PRCN==NULL) continue;
208 ls->PRCN->RCCAPA=0;
209 if (ls->PRCN->PCTC==NULL) continue;
210
211 for (cl=ls->NAMECHAIN; cl!=NULL; cl=cl->NEXT)
212 if (mbk_TestREGEX((char *)cl->DATA, nameregex)) break;
213
214 if (cl!=NULL)
215 {
216 while( ls->PRCN->PCTC )
217 delloctc( (loctc_list*)ls->PRCN->PCTC->DATA );
218
219 rcn_mergectclosig(ls);
220 }
221 }
222 }
223
224 void avt_RemoveResistances(lofig_list *lf, char *nameregex)
225 {
226 losig_list *ls;
227 chain_list *cl;
228 loctc_list *lctc;
229 ptype_list *pt;
230 num_list *ln;
231
232 if (lf==NULL) return;
233
234 for (ls=lf->LOSIG; ls!=NULL; ls=ls->NEXT)
235 {
236 if (ls->PRCN==NULL) continue;
237 if (ls->PRCN->PWIRE==NULL) { rcn_mergectclosig(ls); continue; }
238
239 for (cl=ls->NAMECHAIN; cl!=NULL; cl=cl->NEXT)
240 if (mbk_TestREGEX((char *)cl->DATA, nameregex)) break;
241
242 if (cl!=NULL)
243 {
244 while( ls->PRCN->PWIRE )
245 dellowire(ls, ls->PRCN->PWIRE->NODE1, ls->PRCN->PWIRE->NODE2);
246
247 for (cl=ls->PRCN->PCTC; cl!=NULL; cl=cl->NEXT)
248 {
249 lctc=(loctc_list *)cl->DATA;
250 if (lctc->SIG1==ls)
251 lctc->NODE1=1;
252 else
253 lctc->NODE2=1;
254 }
255
256 if ((pt=getptype(ls->USER, LOFIGCHAIN))!=NULL) cl=(chain_list *)pt->DATA;
257 else cl=NULL;
258
259 while (cl!=NULL)
260 {
261 for (ln=((locon_list *)cl->DATA)->PNODE; ln!=NULL; ln=ln->NEXT)
262 ln->DATA=1;
263 cl=cl->NEXT;
264 }
265
266 ls->PRCN->NBNODE=2;
267 rcn_mergectclosig(ls);
268 }
269 }
270 }
271
272 void avt_FlattenNetlist(lofig_list *lf, char *level)
273 {
274 eqt_ctx *mc_ctx=NULL;
275 if (lf==NULL) return;
276 flatten_parameters (lf, NULL, NULL , 0, 0, 0, 0, 0, 0, &mc_ctx);
277 if (mc_ctx!=NULL) eqt_term(mc_ctx);
278
279 if (strcasecmp(level,"transistors")==0 || strcasecmp(level,"trs")==0)
280 rflattenlofig (lf, YES, NO);
281 else if (strcasecmp(level,"catalog")==0 || strcasecmp(level,"catal")==0)
282 rflattenlofig (lf, YES, YES);
283 else if (strcasecmp(level,"blackbox")==0 || strcasecmp(level,"bbox")==0)
284 flatOutsideList (lf);
285 else
286 flattenlofig (lf, level, YES);
287 }
288
289 void avt_ViewNetlist(char *name)
290 {
291 lofig_list *lf;
292 if ((lf=getloadedlofig(name))!=NULL)
293 viewlofig(lf);
294 }
295
296 void avt_ViewSignal(char *name, char *signal)
297 {
298 lofig_list *lf;
299 losig_list *ls;
300 if ((lf=getloadedlofig(name))!=NULL)
301 if ((ls=mbk_quickly_getlosigbyname(lf, signal))!=NULL)
302 {
303 rcn_flush_signal(lf, ls );
304 rcn_refresh_signal( lf, ls );
305 viewlosig(ls);
306 }
307 }
308
309 void avt_RemoveNetlist(char *name)
310 {
311 lofig_list *lf;
312 if ((lf=getloadedlofig(name))!=NULL)
313 unlocklofig(lf);
314 dellofig(name);
315 }
316
317 void avt_SetBlackBoxes(chain_list *cl)
318 {
319 SetBlackList(cl);
320 }
321
322 typedef struct
323 {
324 int tot_trans;
325 int tot_capa;
326 int tot_resi;
327 int tot_sig;
328 int tot_inst;
329 } stat_result;
330
331 static chain_list *disphier(lofig_list *lf, char *figname, char *pad, int count, stat_result *tot, int maxdepth, int depth, char *insnamestr)
332 {
333 ht *tab;
334 loins_list *li;
335 losig_list *ls;
336 int cnti;
337 stat_result sr, lsr;
338 char *model;
339 char *buf;
340 chain_list *lst=NULL, *cl;
341 loctc_list *lcl;
342 chain_list *inslist;
343 char *newinsnamestr;
344 chain_list *ptchain;
345 int len;
346
347
348 sr.tot_trans=sr.tot_capa=sr.tot_resi=sr.tot_sig=sr.tot_inst=0;
349
350 if (lf!=NULL)
351 {
352 tab=addht(10);
353 while (1)
354 {
355 for (li=lf->LOINS; li!=NULL && gethtitem(tab,li->FIGNAME)!=EMPTYHT; li=li->NEXT) ;
356 if (li!=NULL)
357 {
358 addhtitem(tab, li->FIGNAME, 1);
359 model=li->FIGNAME;
360 cnti=0;
361 len = 0;
362 inslist = NULL;
363 while (li!=NULL)
364 {
365 if (li->FIGNAME==model)
366 {
367 inslist = addchain(inslist, li->INSNAME);
368 len += strlen(li->INSNAME);
369 cnti++;
370 }
371 li=li->NEXT;
372 }
373 inslist = reverse(inslist);
374 newinsnamestr = mbkalloc(len + cnti + 1);
375 newinsnamestr[0] = 0;
376 for (ptchain = inslist; ptchain; ptchain = ptchain->NEXT)
377 {
378 strcat(newinsnamestr, (char *)ptchain->DATA);
379 strcat(newinsnamestr, ",");
380 }
381 newinsnamestr[len+cnti-1] = 0;
382 freechain(inslist);
383 strcat(pad,"| ");
384 lst=append(disphier(getloadedlofig(model), model, pad, cnti, tot, maxdepth, depth+1, newinsnamestr), lst);
385 mbkfree(newinsnamestr);
386 sr.tot_trans+=tot->tot_trans*cnti;
387 sr.tot_capa+=tot->tot_capa*cnti;
388 sr.tot_resi+=tot->tot_resi*cnti;
389 sr.tot_sig+=tot->tot_sig*cnti;
390 sr.tot_inst+=tot->tot_inst*cnti;
391 pad[strlen(pad)-2]='\0';
392 }
393 else break;
394 }
395 delht(tab);
396 sr.tot_trans+=(lsr.tot_trans=countchain((chain_list *)lf->LOTRS));
397 sr.tot_sig+=(lsr.tot_sig=countchain((chain_list *)lf->LOSIG));
398 sr.tot_inst+=(lsr.tot_inst=countchain((chain_list *)lf->LOINS));
399
400 lsr.tot_resi=lsr.tot_capa=0;
401 for (ls=lf->LOSIG; ls!=NULL; ls=ls->NEXT)
402 {
403 if (ls->PRCN!=NULL)
404 {
405 lsr.tot_resi+=countchain((chain_list *)ls->PRCN->PWIRE);
406 sr.tot_resi+=countchain((chain_list *)ls->PRCN->PWIRE);
407 if (ls->PRCN->PCTC!=NULL)
408 {
409 for (cl=ls->PRCN->PCTC; cl!=NULL; cl=cl->NEXT)
410 {
411 lcl=(loctc_list *)cl->DATA;
412 if (lcl->SIG1<lcl->SIG2)
413 {
414 lsr.tot_capa++;
415 sr.tot_capa++;
416 }
417 }
418 }
419 }
420 }
421 }
422 else
423 {
424 lsr.tot_trans=lsr.tot_capa=lsr.tot_resi=lsr.tot_sig=lsr.tot_inst=0;
425 }
426
427 memcpy(tot, &sr, sizeof(stat_result));
428 if (depth+1<=maxdepth)
429 {
430 if (insnamestr)
431 {
432 buf = mbkalloc(strlen(insnamestr) + 1024);
433 sprintf(buf,"%s(%d) %s (%s) global(%d trs, %d ins, %d resi, %d capa, %d sig) local(%d trs, %d ins, %d resi, %d capa, %d sig)",pad,count,figname, insnamestr, sr.tot_trans, sr.tot_inst, sr.tot_resi, sr.tot_capa, sr.tot_sig, lsr.tot_trans, lsr.tot_inst, lsr.tot_resi, lsr.tot_capa, lsr.tot_sig);
434 }
435 else
436 {
437 buf = mbkalloc(1024);
438 sprintf(buf,"%s(%d) %s global(%d trs, %d ins, %d resi, %d capa, %d sig) local(%d trs, %d ins, %d resi, %d capa, %d sig)",pad,count,figname, sr.tot_trans, sr.tot_inst, sr.tot_resi, sr.tot_capa, sr.tot_sig, lsr.tot_trans, lsr.tot_inst, lsr.tot_resi, lsr.tot_capa, lsr.tot_sig);
439 }
440 lst=append(addchain(NULL, strdup(buf)), lst);
441 mbkfree(buf);
442 }
443
444 return lst;
445 }
446
447 void avt_DisplayNetlistHierarchy(FILE *f, char *netlistname, int maxdepth)
448 {
449 chain_list *lst;
450 lofig_list *lf;
451 stat_result sr;
452 char pad[1024];
453
454 if ((lf=avt_GetNetlist(netlistname))==NULL) return;
455
456 strcpy(pad,"");
457 if (maxdepth<=0) maxdepth=10000000;
458 lst=disphier(lf, lf->NAME, pad, 1, &sr, maxdepth, 0, NULL);
459 while (lst!=NULL)
460 {
461 fprintf(f, "%s\n", (char *)lst->DATA);
462 free(lst->DATA);
463 lst=delchain(lst, lst);
464 }
465 }
466
467 #define COL_RESI_NAME 0
468 #define COL_RESI_VAL 1
469 #define COL_RESI_NODE 2
470
471 void avt_DisplayResistivePath(FILE *f, lofig_list *lf, char *connector1, char *connector2)
472 {
473 ptype_list *pt;
474 chain_list *phinterf=NULL, *realinterf=NULL, *cl, *ch;
475 num_list *nm;
476 locon_list *lc;
477 int i, done;
478 char *con[2], *net[2]={NULL, NULL};
479 long num[2]={-1, -1}, cnt;
480 losig_list *sig;
481 lowire_list *lw;
482
483 con[0]=mbk_decodeanyvector(connector1);
484 con[1]=mbk_decodeanyvector(connector2);
485 if ((pt=getptype(lf->USER, PH_INTERF))!=NULL) phinterf=(chain_list *)pt->DATA;
486 if ((pt=getptype(lf->USER, PH_REAL_INTERF))!=NULL) realinterf=(chain_list *)pt->DATA;
487
488 if (countchain(phinterf)==countchain(realinterf))
489 {
490 for (i=0; i<2; i++)
491 {
492 for (cl=realinterf, ch=phinterf; cl!=NULL && cl->DATA!=con[i]; cl=cl->NEXT, ch=ch->NEXT) ;
493 if (cl!=NULL)
494 {
495 net[i]=ch->DATA;
496 for (cl=phinterf, cnt=0; cl!=ch; cl=cl->NEXT)
497 if (cl->DATA==net[i]) cnt++;
498
499 for (lc=lf->LOCON; lc!=NULL && lc->NAME!=net[i]; lc=lc->NEXT) ;
500
501 if (lc!=NULL)
502 {
503 for (nm=lc->PNODE; nm!=NULL && cnt>0; nm=nm->NEXT, cnt--) ;
504 if (nm!=NULL)
505 num[i]=nm->DATA;
506 else
507 num[i]=-1;
508 sig=lc->SIG;
509 }
510 }
511 else
512 avt_errmsg(AVT_API_ERRMSG, "004", AVT_ERROR, con[i]);
513 }
514
515
516 if (net[0]!=NULL && num[0]==-1)
517 avt_errmsg(AVT_API_ERRMSG, "005", AVT_ERROR, con[0]);
518 if (net[1]!=NULL && num[1]==-1)
519 avt_errmsg(AVT_API_ERRMSG, "005", AVT_ERROR, con[1]);
520
521 done=0;
522 if (net[0]==net[1] && num[0]!=-1 && num[1]!=-1)
523 {
524 long a, nb;
525 char buf[512];
526 rcn_flush_signal(lf, sig );
527 rcn_refresh_signal( lf, sig );
528 cl=rcn_get_a_r_way(sig, num[0], num[1]);
529 if (cl!=NULL)
530 {
531 Board *b;
532 b=Board_CreateBoard();
533 Board_SetSize(b, COL_RESI_NAME, 20, 'l');
534 Board_SetSize(b, COL_RESI_VAL, 10, 'r');
535 Board_SetSize(b, COL_RESI_NODE, 10, 'l');
536 Board_NewLine(b);
537 Board_SetValue(b, COL_RESI_NAME, "Resistor Name");
538 Board_SetValue(b, COL_RESI_VAL, "Value");
539 Board_SetValue(b, COL_RESI_NODE, "Node");
540 Board_NewSeparation(b);
541 Board_NewLine(b);
542 sprintf(buf,"[%ld] %s", num[0], con[0]);
543 Board_SetValue(b, COL_RESI_NODE, buf);
544
545 a=num[0];
546 while (cl!=NULL)
547 {
548 lw=(lowire_list *)cl->DATA;
549 if (lw->NODE1!=a) nb=lw->NODE1; else nb=lw->NODE2;
550
551 Board_NewLine(b);
552
553 if ((pt=getptype(lw->USER, RESINAME))!=NULL)
554 Board_SetValue(b, COL_RESI_NAME, (char *)pt->DATA);
555
556 if (cl->NEXT==NULL)
557 sprintf(buf,"[%ld] %s", num[1], con[1]);
558 else
559 sprintf(buf,"[%ld]", nb);
560
561 Board_SetValue(b, COL_RESI_NODE, buf);
562 sprintf(buf,"%.1f", lw->RESI);
563 Board_SetValue(b, COL_RESI_VAL, buf);
564 a=nb;
565 cl=delchain(cl, cl);
566 }
567 Board_NewSeparation(b);
568 avt_fprintf(f, " *** Resistive path beetween connector '%s' and '%s'\n\n", con[0], con[1]);
569
570 Board_Display(f, b, "");
571 Board_FreeBoard(b);
572
573 avt_fprintf(f, "\n");
574 done=1;
575 }
576 }
577
578 if (!done)
579 fprintf(f, " *** No resistive path found beetween connector '%s' and '%s'\n", con[0], con[1]);
580 }
581 }