1 /*
2  *  $Id: DEF_drive.c,v 1.12 2007/10/22 12:57:58 jpc Exp $
3  *
4  *  /----------------------------------------------------------------\
5  *  |                                                                |
6  *  |        A l l i a n c e   C A D   S y s t e m                   |
7  *  |  S i l i c o n   E n s e m b l e / A l l i a n c e             |
8  *  |                                                                |
9  *  |  Author    :                      Jean-Paul CHAPUT             |
10  *  |  E-mail    :         alliance-users@asim.lip6.fr             |
11  *  | ============================================================== |
12  *  |  C Module  :         "./DEF_drive.c"                           |
13  *  | ************************************************************** |
14  *  |  U p d a t e s                                                 |
15  *  |                                                                |
16  *  \----------------------------------------------------------------/
17  */
18 
19 
20 # include  "debugoff.h"
21 # include  "util_Defs.h"
22 # include  "DEF_drive.h"
23 
24 
25 /*  ------------------------------------------------------------------
26  *  Internal types and defines.
27  */
28 
29 #   define        C_DIRECTION_NONE      ((char)0)
30 #   define        C_DIRECTION_INPUT     ((char)1)
31 #   define        C_DIRECTION_OUTPUT    ((char)2)
32 #   define        C_DIRECTION_TRISTATE  ((char)3)
33 #   define        C_DIRECTION_INOUT     ((char)4)
34 #   define        C_DIRECTION_FEEDTHRU  ((char)5)
35 
36 #   define        C_USE_NONE            ((char)0)
37 #   define        C_USE_SIGNAL          ((char)1)
38 #   define        C_USE_ANALOG          ((char)2)
39 #   define        C_USE_POWER           ((char)3)
40 #   define        C_USE_GROUND          ((char)4)
41 #   define        C_USE_CLOCK           ((char)5)
42 
43 #   define        TTERM_SIZE            1024
44 
45 #   define        PTYPE_PHFIG           1024
46 #   define        PTYPE_LOFIG           1025
47 
48 #   define        F_REGULAR_NET         0x00000001
49 #   define        F_SPECIAL_NET         0x00000002
50 
51 #   define        F_SEG_WIDTH           0x00000001
52 #   define        F_SEG_STRIPE          0x00000002
53 
54 
55 /*  ------------------------------------------------------------------
56  *  Internal types.
57  */
58 
59   typedef struct row_s {
60             char *rowName;
61             char *rowType;
62             long  x;
63             long  y;
64             long  orient;
65             long  doNumber;
66             long  byNumber;
67             long  stepX;
68             long  stepY;
69     struct row_s *next;
70   } row_t;
71 
72   typedef struct track_s {
73             char  axisName;
74             long  start;
75             long  doNumber;
76             long  step;
77             char *routingLayers;
78             long  x;
79             long  y;
80     struct track_s *next;
81   } track_t;
82 
83   typedef struct blockage_s {
84             long  x;
85             long  y;
86             long  width;
87             long  height;
88     struct blockage_s *next;
89   } blockage_t;
90 
91 
92 /*  ------------------------------------------------------------------
93  *  Internal variables.
94  */
95 
96   static              FILE *DEF_FILE;
97   static              long  LV_Flags      = 0L;
98   static              long  LV_localFlags = 0L;
99   static              char *LV_name;
100   static struct      lofig *LV_lofig;
101   static struct      phfig *LV_phfig;
102   static struct      row_s *LV_row;
103   static struct    track_s *LV_track;
104   static struct blockage_s *LV_blockage;
105   static struct  authtable *LV_htTerm;
106   static              char  routingLayers3[256] = "ALU1 ALU2 ALU3";
107   static              char  routingLayers4[256] =
108                              "ALU1 ALU2 ALU3 ALU4";
109   static              char  routingLayers6[256] =
110                              "ALU1 ALU2 ALU3 ALU4 ALU5 ALU6";
111 
112 
113 /*  ------------------------------------------------------------------
114  *  Local functions.
115  */
116 
117   static   struct phins *getphinslink       __FP((struct loins *apLoins));
118   static           void  buildphinslinks    __FP((void));
119   static           void  buildtterm         __FP((void));
120   static           void  freetterm          __FP((void));
121   static           void  freephinslinks     __FP((void));
122   static           void  swapOrient         __FP((char *apSameOrient,
123                                                   char *apOppositeOrient));
124   static           char  normOrient         __FP((char aOrient));
125   static           long  orientPhfig        __FP((struct phfig *apPhfig,
126                                                           char *apSameOrient,
127                                                           char *apOppositeOrient));
128   static           char *DIRtoa             __FP((char acDIR));
129   static           char *USEtoa             __FP((char acUSE));
130   static           char *strLCat            __FP((char *asLine,
131                                                   char *asEl,
132                                                   long *aplLine,
133                                                   long  alMax));
134   static           void  fprintDIEAREA      __FP((void));
135   static   struct row_s *newrow             __FP((void));
136   static           void  freerow            __FP((void));
137   static           void  ref2ROW            __FP((void));
138   static   struct row_s *getBaseRow         __FP((long  aX,
139                                                   long  aY,
140                                                   char  aOrient));
141   static           void  fprintROWS         __FP((void));
142   static struct track_s *newtrack           __FP((void));
143   static           void  freetrack          __FP((void));
144   static           void  ref2TRACK          __FP((void));
145   static           void  fprintTRACKS       __FP((void));
146   static struct blockage_s *newblockage     __FP((void));
147   static           void  freeblockage       __FP((void));
148   static           void  ref2BLOCKAGE       __FP((void));
149   static           void  fprintBLOCKAGE     __FP((void));
150   static           void  fprintVIAMATRIX    __FP((char aType,
151                                                   long aWidth,
152                                                   long aHeight));
153   static           void  fprintVIAS         __FP((void));
154   static           long  checkPhins         __FP((struct phins *apPhins));
155   static           void  fprintCOMPONENTS   __FP((void));
156   static           void  fprintPIN          __FP((struct locon *apLocon,
157                                                   struct phcon *apPhcon,
158                                                           char *asState));
159   static           void  fprintPINS         __FP((void));
160   static           void  fprintWIRESEG      __FP((struct phseg *apPhseg,
161                                                           long  aFlags));
162   static           void  fprintWIREVIA      __FP((struct phvia *apPhvia,
163                                                           long  aFlags));
164   static           void  fprintWIRES        __FP((struct losig *apLosig));
165   static           void  fprintNET          __FP((struct losig *apLoSig,
166                                                           char  aUse));
167   static           void  fprintNETS         __FP((void));
168   static           void  fprintSPECIALNETS  __FP((void));
169   static           void  fprintDEF          __FP((void));
170 
171 
172 /*
173  *  /----------------------------------------------------------------\
174  *  |                   Functions Definitions                        |
175  *  \----------------------------------------------------------------/
176  */
177 
178 /*  ------------------------------------------------------------------
179  *  Function  :  "getphinslink()".
180  */
181 
getphinslink(apLoins)182 static struct phins *getphinslink(apLoins)
183   struct loins *apLoins;
184 {
185   struct ptype *pType;
186 
187 
188   if ((pType = getptype (apLoins->USER, PTYPE_PHFIG)) == NULL)
189     return (NULL);
190 
191   return ((struct phins*)pType->DATA);
192 }
193 
194 
195 /*  ------------------------------------------------------------------
196  *  Function  :  "buildphinslinks()".
197  */
198 
buildphinslinks()199 static void  buildphinslinks()
200 {
201   struct loins *pLoins;
202   struct phins *pPhins;
203           long  flag;
204 
205 
206   flag = FALSE;
207 
208   /* Check if there is a physical figure. */
209   if (!LV_phfig) return;
210 
211   for (pLoins = LV_lofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) {
212     if ((pPhins = findphins (LV_phfig, pLoins->INSNAME))) {
213       if (pLoins->FIGNAME != pPhins->FIGNAME) {
214         flag = TRUE;
215 
216         eprinth (NULL);
217         eprintf ("Instances of \"%s\" have NOT the same physical",
218                  pLoins->INSNAME);
219         eprintf (" and logical model :\n");
220         eprintf ("  logical := \"%s\"",    pLoins->FIGNAME);
221         eprintf (" physical := \"%s\".\n", pPhins->FIGNAME);
222 
223         continue;
224       }
225 
226       pLoins->USER = addptype (pLoins->USER, PTYPE_PHFIG, (void*)pPhins);
227       pPhins->USER = addptype (pPhins->USER, PTYPE_LOFIG, (void*)pLoins);
228     }
229   }
230 
231 
232   /* Check if all physical instances are in the netlist. */
233 
234 
235   for (pPhins = LV_phfig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) {
236     if (!getptype (pPhins->USER, PTYPE_LOFIG)) {
237       if (!flag) {
238         /* Print the head error message. */
239         flag = TRUE;
240 
241         eprinth (NULL);
242         eprintf ("The following physical instances are not in the");
243         eprintf (" netlist :\n");
244       }
245 
246       eprintf ("- \"%s\" (model \"%s\").\n",
247                pPhins->INSNAME, pPhins->FIGNAME);
248     }
249   }
250 
251 
252   if (flag) EXIT (1);
253 }
254 
255 
256 /*  ------------------------------------------------------------------
257  *  Function  :  "freephinslinks()".
258  */
259 
freephinslinks()260 static void  freephinslinks()
261 {
262   struct loins *pLoins;
263   struct phins *pPhins;
264 
265 
266   /* Check if there is a physical figure. */
267   if (!LV_phfig) return;
268 
269   for (pLoins = LV_lofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) {
270     if (pLoins->USER)
271       pLoins->USER = delptype (pLoins->USER, PTYPE_PHFIG);
272   }
273 
274 
275   for (pPhins = LV_phfig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) {
276     if (pPhins->USER)
277       pPhins->USER = delptype (pPhins->USER, PTYPE_LOFIG);
278   }
279 }
280 
281 
282 /*  ------------------------------------------------------------------
283  *  Function  :  "buildtterm()".
284  */
285 
buildtterm()286 static void  buildtterm()
287 {
288   struct locon *pLocon;
289 
290 
291   LV_htTerm = createauthtable (TTERM_SIZE);
292 
293   for (pLocon = LV_lofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) {
294     addauthelem (LV_htTerm, getsigname (pLocon->SIG), (long)pLocon->NAME);
295   }
296 }
297 
298 
299 /*  ------------------------------------------------------------------
300  *  Function  :  "freetterm()".
301  */
302 
freetterm()303 static void  freetterm()
304 {
305   destroyauthtable (LV_htTerm);
306 }
307 
308 
309 
310 /*  ------------------------------------------------------------------
311  *  Function  :  "swapOrient()".
312  */
313 
swapOrient(apSameOrient,apOppositeOrient)314 static void  swapOrient(apSameOrient, apOppositeOrient)
315   char *apSameOrient;
316   char *apOppositeOrient;
317 {
318   char  tmpOrient;
319 
320    tmpOrient        = *apSameOrient;
321   *apSameOrient     = *apOppositeOrient;
322   *apOppositeOrient =  tmpOrient;
323 }
324 
325 
326 /*  ------------------------------------------------------------------
327  *  Function  :  "normOrient()".
328  */
329 
normOrient(aOrient)330 static char  normOrient(aOrient)
331   char  aOrient;
332 {
333   char  normOrient;
334 
335 
336   switch (aOrient) {
337     default:
338     case DEF_N:  normOrient = DEF_N;  break;
339     case DEF_FN: normOrient = DEF_N;  break;
340     case DEF_FS: normOrient = DEF_FS; break;
341     case DEF_S:  normOrient = DEF_FS; break;
342     case DEF_W:  normOrient = DEF_W;  break;
343     case DEF_FW: normOrient = DEF_W;  break;
344     case DEF_E:  normOrient = DEF_FE; break;
345     case DEF_FE: normOrient = DEF_FE; break;
346   }
347 
348   return (normOrient);
349 }
350 
351 
352 /*  ------------------------------------------------------------------
353  *  Function  :  "getOppositeOrient()".
354  */
355 
getOppositeOrient(aOrient)356 static char  getOppositeOrient(aOrient)
357   char  aOrient;
358 {
359   char  oppositeOrient;
360 
361 
362   switch (aOrient) {
363     default:
364     case DEF_N:  oppositeOrient = DEF_FS; break;
365     case DEF_FN: oppositeOrient = DEF_FS; break;
366     case DEF_FS: oppositeOrient = DEF_N;  break;
367     case DEF_S:  oppositeOrient = DEF_N;  break;
368     case DEF_W:  oppositeOrient = DEF_FE; break;
369     case DEF_FW: oppositeOrient = DEF_FE; break;
370     case DEF_E:  oppositeOrient = DEF_W;  break;
371     case DEF_FE: oppositeOrient = DEF_W;  break;
372   }
373 
374   return (oppositeOrient);
375 }
376 
377 
378 /*  ------------------------------------------------------------------
379  *  Function  :  "orientPhfig()".
380  */
381 
orientPhfig(apPhfig,apSameOrient,apOppositeOrient)382 static long  orientPhfig(apPhfig, apSameOrient, apOppositeOrient)
383   struct phfig *apPhfig;
384           char *apSameOrient;
385           char *apOppositeOrient;
386 {
387   struct ePow_s *plPow;
388            long  sliceHeight;
389 
390 
391   plPow = buildPow (apPhfig, ALU1, C_POWER_HORIZONTAL, "");
392 
393   sliceHeight = (apPhfig->YAB2 - apPhfig->YAB1) / MBK_Y_SLICE;
394 
395   if (!plPow) {
396     if (LV_Flags & F_TRUST_ORIENT) {
397       *apSameOrient     = DEF_N;
398       *apOppositeOrient = DEF_FS;
399 
400       return (FALSE);
401     }
402 
403     eprinth (NULL);
404     eprintf ("\n  Model \"%s\" have no horizontal ALU1 power supplies.",
405              apPhfig->NAME);
406     eprintf ("\n  Can't guess allowed orientations.\n");
407     EXIT (1);
408   }
409 
410 
411   switch (plPow->Type) {
412     default:
413     case C_POWER_ISVSS:
414       *apSameOrient     = DEF_N;
415       *apOppositeOrient = DEF_FS;
416       break;
417     case C_POWER_ISVDD:
418       *apSameOrient     = DEF_FS;
419       *apOppositeOrient = DEF_N;
420       break;
421   }
422 
423   if (!(sliceHeight % 2))
424     *apOppositeOrient = *apSameOrient;
425 
426 
427   freePow (plPow);
428 
429   return (TRUE);
430 }
431 
432 
433 /*  ------------------------------------------------------------------
434  *  Function  :  "DIRtoa()".
435  */
436 
DIRtoa(acDIR)437 static char *DIRtoa(acDIR)
438   char  acDIR;
439 {
440   switch(acDIR) {
441     case C_DIRECTION_NONE:     return((char*)NULL);
442     case C_DIRECTION_INPUT:    return("INPUT");
443     case C_DIRECTION_OUTPUT:   return("OUTPUT");
444     case C_DIRECTION_TRISTATE: return("OUTPUT");
445     case C_DIRECTION_INOUT:    return("INOUT");
446     case C_DIRECTION_FEEDTHRU: return("FEEDTHRU");
447   }
448   return((char*)NULL);
449 }
450 
451 
452 /*  ------------------------------------------------------------------
453  *  Function  :  "USEtoa()".
454  */
455 
USEtoa(acUSE)456 static char *USEtoa(acUSE)
457   char  acUSE;
458 {
459   switch(acUSE) {
460     case C_USE_NONE:   return((char*)NULL);
461     case C_USE_SIGNAL: return("SIGNAL");
462     case C_USE_ANALOG: return("ANALOG");
463     case C_USE_POWER:  return("POWER");
464     case C_USE_GROUND: return("GROUND");
465     case C_USE_CLOCK:  return("CLOCK");
466   }
467 
468   return((char*)NULL);
469 }
470 
471 
472 /*  ------------------------------------------------------------------
473  *  Function  :  "strLCat()".
474  */
475 
strLCat(asLine,asEl,aplLine,alMax)476 static char *strLCat(asLine, asEl, aplLine, alMax)
477   char *asLine, *asEl;
478   long *aplLine, alMax;
479 {
480   long  lCopy;
481 
482 
483   /* Copy the string `asEl' if there is enougth place. */
484   lCopy = m_Min(alMax - *aplLine - 1, strlen(asEl));
485   strncpy(asLine + *aplLine, asEl, lCopy);
486   *aplLine += lCopy;
487 
488   /* Terminate the string by a zero. */
489   asLine[(*aplLine)] = (char)0;
490 
491   return(asLine);
492 }
493 
494 
495 /*  ------------------------------------------------------------------
496  *  Function  :  "fprintDIEAREA()".
497  */
498 
fprintDIEAREA()499 static void  fprintDIEAREA()
500 {
501   if (LV_phfig) {
502     fprintf (DEF_FILE,
503              "\nDIEAREA ( %ld %ld ) ( %ld %ld ) ;\n",
504              MBK2DEF_length (LV_phfig->XAB1),
505              MBK2DEF_length (LV_phfig->YAB1),
506              MBK2DEF_length (LV_phfig->XAB2),
507              MBK2DEF_length (LV_phfig->YAB2));
508   }
509 }
510 
511 
512 /*  ------------------------------------------------------------------
513  *  Function  :  "newrow()".
514  */
515 
newrow()516 static struct row_s *newrow()
517 {
518   struct row_s *pRow;
519 
520   pRow = (row_t*)mbkalloc (sizeof (row_t));
521   pRow->next = LV_row;
522 
523   return (LV_row = pRow);
524 }
525 
526 
527 /*  ------------------------------------------------------------------
528  *  Function  :  "freerow()".
529  */
530 
freerow()531 static void  freerow()
532 {
533   struct row_s *pRow;
534 
535   while (LV_row) {
536     pRow = LV_row->next;
537 
538     mbkfree (LV_row->rowName);
539     mbkfree (LV_row->rowType);
540     mbkfree (LV_row);
541 
542     LV_row = pRow;
543   }
544 }
545 
546 
547 /*  ------------------------------------------------------------------
548  *  Function  :  "ref2ROW()".
549  */
550 
ref2ROW()551 static void  ref2ROW()
552 {
553   struct phref *pPhref;
554   struct row_s *pRow;
555 
556 
557   if (LV_phfig) {
558     for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) {
559       if (!strncmp (pPhref->NAME, "row_", 4)) {
560         pRow = newrow ();
561 
562         MBK2DEF_row (pPhref,
563                      &pRow->rowName,
564                      &pRow->rowType,
565                      &pRow->orient,
566                      &pRow->doNumber,
567                      &pRow->byNumber,
568                      &pRow->stepX,
569                      &pRow->stepY,
570                      &pRow->x,
571                      &pRow->y);
572       }
573     }
574   }
575 }
576 
577 
578 /*  ------------------------------------------------------------------
579  *  Function  :  "hasROW()".
580  */
581 
hasROW(apPhfig)582 extern long  hasROW(apPhfig)
583   struct phfig *apPhfig;
584 {
585   struct phref *pPhref;
586 
587 
588   for (pPhref = apPhfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) {
589     if (!strncmp (pPhref->NAME, "row_", 4)) {
590       return (TRUE);
591     }
592   }
593 
594   return(FALSE);
595 }
596 
597 
598 /*  ------------------------------------------------------------------
599  *  Function  :  "buildROWS()".
600  */
601 
buildROWS(apPhfig)602 extern long  buildROWS(apPhfig)
603   struct phfig *apPhfig;
604 {
605   struct phins *pIns;
606           long  iRow;
607           long  rowGridX0, rowGridY0, rowGridIns, rowSizeX, rowSizeY;
608           char  sameOrient, oppositeOrient;
609           char  rowName[1024];
610 
611 
612   if (hasROW(apPhfig)) return (FALSE);
613 
614 
615   pIns           = NULL;
616 
617   rowGridX0      = apPhfig->XAB1;
618   rowGridY0      = apPhfig->YAB1;
619       sameOrient = DEF_N;
620   oppositeOrient = DEF_FS;
621 
622   rowSizeX       = (apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID;
623   rowSizeY       = (apPhfig->YAB2 - apPhfig->YAB1) / MBK_Y_SLICE;
624 
625 
626   for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) {
627     /* Skip unpitched instances. */
628     if ((pIns->XINS - apPhfig->XAB1) % MBK_X_GRID) continue;
629     if ((pIns->YINS - apPhfig->YAB1) % MBK_X_GRID) continue;
630 
631     if (!orientPhfig (getphfig (pIns->FIGNAME, 'A'),
632                       &sameOrient,
633                       &oppositeOrient)) continue;
634 
635     mprintf2 ("  o  Taking \"%s\" as reference for the ROW grid.\n",
636               pIns->INSNAME);
637 
638     rowGridX0  = apPhfig->XAB1;
639     rowGridY0  = apPhfig->YAB1
640                + (pIns->YINS - apPhfig->YAB1) % MBK_Y_SLICE;
641 
642     rowSizeX   = (apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID;
643     rowSizeY   = (apPhfig->YAB2 - rowGridY0)     / MBK_Y_SLICE;
644 
645     rowGridIns = (pIns->YINS - rowGridY0) / MBK_Y_SLICE;
646 
647     switch (pIns->TRANSF) {
648       default:
649       case SYM_X:
650       case NOSYM:
651         break;
652       case SYM_Y:
653       case SYMXY:
654         swapOrient (&sameOrient, &oppositeOrient);
655         break;
656       /* We do not allow rotated instances. */
657       case ROT_P:
658       case ROT_M:
659       case SY_RP:
660       case SY_RM: continue;
661     }
662 
663     __DBG (
664       fflush (stdout);
665       fprintf (stderr, "pIns->YINS     := %ld.\n", pIns->YINS);
666       fprintf (stderr, "apPhfig->YAB1  := %ld.\n", apPhfig->YAB1);
667       fprintf (stderr, "rowGridY0      := %ld.\n", rowGridY0);
668       fprintf (stderr, "rowGridIns     := %ld.\n", rowGridIns);
669       fflush (stderr);
670     )
671     if (rowGridIns % 2)
672       swapOrient (&sameOrient, &oppositeOrient);
673 
674     break;
675   }
676 
677 
678   /* Restore the opposite orient, when the cell is 2*N slices tall. */
679   oppositeOrient = getOppositeOrient (sameOrient);
680 
681   for (iRow = 0; iRow < rowSizeY; iRow++) {
682     sprintf (rowName, "ROW_%ld", iRow);
683 
684     DEF2MBK_row (apPhfig,
685                  rowName,
686                  "core",
687                  (iRow % 2) ? oppositeOrient : sameOrient,
688                  rowSizeX,
689                  1,
690                  MBK2DEF_length (MBK_X_GRID),
691                  MBK2DEF_length (MBK_Y_SLICE),
692                  rowGridX0,
693                  rowGridY0 + iRow * MBK_Y_SLICE
694                  );
695   }
696 
697 
698   return (TRUE);
699 }
700 
701 
702 /*  ------------------------------------------------------------------
703  *  Function  :  "getBaseRow()".
704  */
705 
getBaseRow(aX,aY,aOrient)706 static struct row_s *getBaseRow(aX, aY, aOrient)
707   long  aX, aY;
708   char  aOrient;
709 {
710   struct row_s *pRow;
711           long  rowMax;
712           char  orient;
713 
714 
715   for (pRow = LV_row; pRow != NULL; pRow = pRow->next) {
716     orient = normOrient (aOrient);
717 
718     switch (aOrient) {
719       case DEF_N:
720       case DEF_FN:
721       case DEF_FS:
722       case DEF_S:
723         if (pRow->y != aY) continue;
724         rowMax = DEF2MBK_length (pRow->stepX) * pRow->doNumber;
725 
726         if ((aX < pRow->x) || (aX > pRow->x + rowMax)) continue;
727 
728         if (pRow->orient == orient) return (pRow);
729         break;
730       case DEF_W:
731       case DEF_E:
732       case DEF_FW:
733       case DEF_FE:
734         if (pRow->x != aX) continue;
735         rowMax = DEF2MBK_length (pRow->stepY) * pRow->byNumber;
736 
737         if ((aY < pRow->y) || (aY > pRow->y + rowMax)) continue;
738 
739         if (pRow->orient == orient)
740           return (pRow);
741         break;
742     }
743   }
744 
745 
746   return (NULL);
747 }
748 
749 
750 /*  ------------------------------------------------------------------
751  *  Function  :  "fprintROWS()".
752  */
753 
fprintROWS()754 static void  fprintROWS ()
755 {
756   struct row_s *pRow;
757 
758 
759   for (pRow = LV_row; pRow != NULL; pRow = pRow->next) {
760     fprintf (DEF_FILE,
761              "ROW %s %s %ld %ld %s DO %ld BY %ld STEP %ld %ld ;\n",
762              pRow->rowName,
763              pRow->rowType,
764              pRow->x,
765              pRow->y,
766              DEF_orient2a(pRow->orient),
767              pRow->doNumber,
768              pRow->byNumber,
769              pRow->stepX,
770              pRow->stepY);
771   }
772 }
773 
774 
775 /*  ------------------------------------------------------------------
776  *  Function  :  "newtrack()".
777  */
778 
newtrack()779 static struct track_s *newtrack()
780 {
781   struct track_s *pTrack;
782 
783   pTrack = (track_t*)mbkalloc (sizeof (track_t));
784   pTrack->next = LV_track;
785 
786   return (LV_track = pTrack);
787 }
788 
789 
790 /*  ------------------------------------------------------------------
791  *  Function  :  "freetrack()".
792  */
793 
freetrack()794 static void  freetrack()
795 {
796   struct track_s *pTrack;
797 
798   while (LV_track) {
799     pTrack = LV_track->next;
800 
801     mbkfree (LV_track->routingLayers);
802     mbkfree (LV_track);
803 
804     LV_track = pTrack;
805   }
806 }
807 
808 
809 /*  ------------------------------------------------------------------
810  *  Function  :  "ref2TRACK()".
811  */
812 
ref2TRACK()813 static void  ref2TRACK()
814 {
815   struct   phref *pPhref;
816   struct track_s *pTrack;
817 
818 
819   if (LV_phfig) {
820     for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) {
821       if (!strncmp (pPhref->NAME, "tracks.", 7)) {
822         pTrack = newtrack ();
823 
824         MBK2DEF_track (pPhref,
825                        &pTrack->axisName,
826                        &pTrack->start,
827                        &pTrack->doNumber,
828                        &pTrack->step,
829                        &pTrack->routingLayers,
830                        &pTrack->x,
831                        &pTrack->y);
832       }
833     }
834   }
835 }
836 
837 
838 /*  ------------------------------------------------------------------
839  *  Function  :  "buildTRACKS()".
840  */
841 
buildTRACKS(apPhfig,aFlags)842 extern long  buildTRACKS(apPhfig, aFlags)
843   struct phfig *apPhfig;
844           long  aFlags;
845 {
846   long  tracksX, tracksY, startX, startY;
847   char *routingLayers;
848 
849 
850   tracksX = ((apPhfig->XAB2 - apPhfig->XAB1) / MBK_X_GRID) - 1;
851   tracksY = ((apPhfig->YAB2 - apPhfig->YAB1) / MBK_X_GRID) - 1;
852   startX  =   apPhfig->XAB1 + MBK_X_GRID;
853   startY  =   apPhfig->YAB1 + MBK_X_GRID;
854 
855   routingLayers = routingLayers6;
856   if (aFlags & F_LAYERS_3) {
857     routingLayers = routingLayers3;
858   }
859   if (aFlags & F_LAYERS_4) {
860     routingLayers = routingLayers4;
861   }
862 
863 
864   /* Allocate the horizontal tracks. */
865   DEF2MBK_track (apPhfig,
866                  "Y",
867                  MBK2DEF_length (startY),
868                  tracksY,
869                  MBK2DEF_length (MBK_X_GRID),
870                  routingLayers,
871                  apPhfig->XAB1,
872                  apPhfig->YAB1 + MBK_X_GRID);
873 
874 
875   /* Allocate the vertical tracks. */
876   DEF2MBK_track (apPhfig,
877                  "X",
878                  MBK2DEF_length (startX),
879                  tracksX,
880                  MBK2DEF_length (MBK_X_GRID),
881                  routingLayers,
882                  apPhfig->XAB1 + MBK_X_GRID,
883                  apPhfig->YAB1);
884 
885 
886   return (TRUE);
887 }
888 
889 
890 /*  ------------------------------------------------------------------
891  *  Function  :  "fprintTRACKS()".
892  */
893 
fprintTRACKS()894 static void  fprintTRACKS ()
895 {
896   struct track_s *pTrack;
897 
898 
899   for (pTrack = LV_track; pTrack != NULL; pTrack = pTrack->next) {
900     fprintf (DEF_FILE,
901              "TRACKS %c %ld DO %ld STEP %ld LAYER %s ;\n",
902              pTrack->axisName,
903              pTrack->start,
904              pTrack->doNumber,
905              pTrack->step,
906              pTrack->routingLayers);
907   }
908 
909 
910   fprintf (DEF_FILE, "\n\n");
911 }
912 
913 
914 /*  ------------------------------------------------------------------
915  *  Function  :  "newblockage()".
916  */
917 
newblockage()918 static struct blockage_s *newblockage()
919 {
920   struct blockage_s *pBlockage;
921 
922   pBlockage = (blockage_t*)mbkalloc (sizeof (blockage_t));
923   pBlockage->next = LV_blockage;
924 
925   return (LV_blockage = pBlockage);
926 }
927 
928 
929 /*  ------------------------------------------------------------------
930  *  Function  :  "freeblockage()".
931  */
932 
freeblockage()933 static void  freeblockage()
934 {
935   struct blockage_s *pBlockage;
936 
937   while (LV_blockage) {
938     pBlockage = LV_blockage->next;
939 
940     mbkfree (LV_blockage);
941 
942     LV_blockage = pBlockage;
943   }
944 }
945 
946 
947 /*  ------------------------------------------------------------------
948  *  Function  :  "ref2BLOCKAGE()".
949  */
950 
ref2BLOCKAGE()951 static void  ref2BLOCKAGE()
952 {
953   struct   phref *pPhref;
954   struct blockage_s *pBlockage;
955 
956 
957   if (LV_phfig) {
958     for (pPhref = LV_phfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) {
959       if (!strncmp (pPhref->NAME, "blockage.", 9)) {
960         pBlockage = newblockage ();
961 
962         MBK2DEF_blockage (pPhref,
963                           &pBlockage->x,
964                           &pBlockage->y,
965                           &pBlockage->width,
966                           &pBlockage->height);
967       }
968     }
969   }
970 }
971 
972 
973 /*  ------------------------------------------------------------------
974  *  Function  :  "fprintBLOCKAGE()".
975  */
976 
fprintBLOCKAGE()977 static void  fprintBLOCKAGE()
978 {
979   struct blockage_s *pBlockage;
980                long  layer;
981 
982 
983   for (pBlockage = LV_blockage;
984        pBlockage != NULL; pBlockage = pBlockage->next) {
985 
986     if (pBlockage == LV_blockage) {
987       fprintf (DEF_FILE,   "    - _BLOCKAGE_RESERVED");
988       fprintf (DEF_FILE, "\n      + ROUTED ");
989     } else {
990       fprintf (DEF_FILE, "\n      NEW ");
991     }
992 
993     for (layer = 1; layer < 7; layer++) {
994       if (layer != 1)
995         fprintf (DEF_FILE, "\n      NEW ");
996 
997       fprintf (DEF_FILE,
998                "ALU%ld %ld + SHAPE BLOCKAGEWIRE ( %ld %ld ) ( %ld * )",
999                layer,
1000                pBlockage->height,
1001                pBlockage->x,
1002                pBlockage->y + pBlockage->height / 2,
1003                pBlockage->x + pBlockage->width);
1004     }
1005   }
1006 
1007   if (LV_blockage)
1008     fprintf (DEF_FILE, "\n      + SOURCE DIST + USE GROUND + WEIGHT 0 ;\n");
1009 }
1010 
1011 
1012 /*  ------------------------------------------------------------------
1013  *  Function  :  "fprintVIAMATRIX()".
1014  */
1015 
fprintVIAMATRIX(aType,aWidth,aHeight)1016 static void  fprintVIAMATRIX (aType, aWidth, aHeight)
1017   char  aType;
1018   long  aWidth;
1019   long  aHeight;
1020 {
1021   long  xCutNB, yCutNB, xCut, yCut;
1022 
1023 
1024   xCutNB = (aWidth  / MBKSCALE(5)) / 2;
1025   yCutNB = (aHeight / MBKSCALE(5)) / 2;
1026 
1027 
1028   for (xCut = - xCutNB; xCut <= xCutNB; xCut++) {
1029     for (yCut = - yCutNB; yCut <= yCutNB; yCut++) {
1030       fprintf (DEF_FILE, "    + RECT %s ( %ld %ld ) ( %ld %ld )\n",
1031                DEF_layer2a (aType),
1032                MBK2DEF_length (xCut - SCALE_X / 2),
1033                MBK2DEF_length (yCut - SCALE_X / 2),
1034                MBK2DEF_length (xCut + SCALE_X / 2),
1035                MBK2DEF_length (yCut + SCALE_X / 2));
1036     }
1037   }
1038 }
1039 
1040 
1041 /*  ------------------------------------------------------------------
1042  *  Function  :  "fprintVIAS()".
1043  */
1044 
fprintVIAS()1045 static void  fprintVIAS()
1046 {
1047   struct tLoseg_s *pTLoseg;
1048   struct eMVIA_s  *pMVIA;
1049             long   nVIA, flagDefault, width, height;
1050             char   viaName[1024];
1051 
1052 
1053   pTLoseg    = gettloseg (LV_phfig);
1054 
1055   if (pTLoseg) {
1056     nVIA = 0;
1057 
1058     __DBG(
1059       fflush (stdout);
1060       fprintf (stderr, "pTLoseg := 0x%08lx\n", (unsigned long)pTLoseg);
1061       fprintf (stderr, "tMVIA   := 0x%08lx\n", (unsigned long)pTLoseg->tMVIA);
1062       fflush (stderr);
1063     )
1064 
1065     for (pMVIA = pTLoseg->tMVIA; pMVIA != NULL; pMVIA = pMVIA->next)
1066       { nVIA++; }
1067 
1068     fprintf (DEF_FILE, "VIAS %ld ;\n", nVIA);
1069 
1070     for (pMVIA = pTLoseg->tMVIA; pMVIA != NULL; pMVIA = pMVIA->next) {
1071       flagDefault =    (pMVIA->width  <= MBKSCALE(2))
1072                     && (pMVIA->height <= MBKSCALE(2));
1073 
1074       __DBG(
1075         if (!flagDefault) {
1076           fprintf (stderr, "macro VIA : %d (%ldx%ld)\n",
1077                            (int)pMVIA->type, pMVIA->width, pMVIA->height);
1078         }
1079       )
1080 
1081       width  = MBKSCALE(2);
1082       height = MBKSCALE(2);
1083 
1084       fprintf (DEF_FILE, "  - %s", DEF_via2a (pMVIA->type,
1085                                               pMVIA->width,
1086                                               pMVIA->height, viaName));
1087 
1088       if (!flagDefault) {
1089         width  = pMVIA->width;
1090         height = pMVIA->height;
1091       }
1092 
1093       fprintf (DEF_FILE, "\n    + RECT %s ( %ld %ld ) ( %ld %ld )\n",
1094                DEF_layer2a (getBottomVIALayer (pMVIA->type)),
1095                DEF2MBK_length (- width  / 2),
1096                DEF2MBK_length (- height / 2),
1097                DEF2MBK_length (  width  / 2),
1098                DEF2MBK_length (  height / 2));
1099 
1100       fprintVIAMATRIX (pMVIA->type, width, height);
1101 
1102       fprintf (DEF_FILE, "    + RECT %s ( %ld %ld ) ( %ld %ld ) ;\n",
1103                DEF_layer2a (getTopVIALayer (pMVIA->type)),
1104                DEF2MBK_length (- width  / 2),
1105                DEF2MBK_length (- height / 2),
1106                DEF2MBK_length (  width  / 2),
1107                DEF2MBK_length (  height / 2));
1108     }
1109 
1110     fprintf (DEF_FILE, "END VIAS\n\n");
1111   }
1112 }
1113 
1114 
1115 /*  ------------------------------------------------------------------
1116  *  Function  :  "fprintPIN()".
1117  */
1118 
fprintPIN(apLocon,apPhcon,asState)1119 static void  fprintPIN(apLocon, apPhcon, asState)
1120   struct locon *apLocon;
1121   struct phcon *apPhcon;
1122           char *asState;
1123 {
1124   char  sSig[1024];
1125   long  conLength;
1126 
1127 
1128   MBK2DEF_name(sSig, apLocon->NAME);
1129 
1130 
1131   fprintf(DEF_FILE, "    - %s.%ld + NET %s", sSig, apPhcon->INDEX, sSig);
1132 
1133   if (isvdd(apLocon->NAME)) {
1134     /*
1135      * if (LV_Flags & F_FIXED_PINS)
1136      *   fprintf(DEF_FILE, " + SPECIAL");
1137      */
1138 
1139     fprintf(DEF_FILE, " + DIRECTION INPUT + USE POWER");
1140   } else if (isvss(apLocon->NAME)) {
1141     /*
1142      * if (LV_Flags & F_FIXED_PINS)
1143      *   fprintf(DEF_FILE, " + SPECIAL");
1144      */
1145 
1146     fprintf(DEF_FILE, " + DIRECTION INPUT + USE GROUND");
1147   } else if (isck(apLocon->NAME)) {
1148     fprintf(DEF_FILE, " + DIRECTION INPUT + USE CLOCK");
1149   } else
1150     fprintf(DEF_FILE, " + DIRECTION %s",
1151                        DIRtoa(MBK2DEF_locondir(apLocon)));
1152 
1153   if (    /* (LV_Flags & F_FIXED_PINS) */
1154       /*&&*/  (strncmp(apLocon->NAME, "vddv", 4))
1155       &&  (strncmp(apLocon->NAME, "vssv", 4))
1156       &&  !isvdd (apLocon->NAME)
1157       &&  !isvss (apLocon->NAME)) {
1158     conLength = MBK_X_GRID;
1159     if (LV_Flags & F_EXPAND_ROUTE) conLength += FLOOR_XY_EXPAND;
1160 
1161     if (strcmp ("UNPLACED", asState)) {
1162       fprintf(DEF_FILE, "\n        + %s ( %ld %ld ) %s",
1163                         asState,
1164                         apPhcon->XCON,
1165                         apPhcon->YCON,
1166                         DEF_side2a (apPhcon->ORIENT));
1167 
1168       if (LV_Flags & F_EXPAND_PLACE) conLength += FLOOR_XY_EXPAND;
1169     } else {
1170       if (LV_Flags & F_EXPAND_PLACE) conLength += FLOOR_XY_EXPAND / 2;
1171     }
1172 
1173     fprintf(DEF_FILE,   " + LAYER %s ( %ld 0 ) ( %ld %ld )",
1174                            DEF_layer2a (apPhcon->LAYER),
1175                       - MBK2DEF_length (apPhcon->WIDTH / 2),
1176                         MBK2DEF_length (apPhcon->WIDTH / 2),
1177                         MBK2DEF_length (conLength));
1178   }
1179 
1180   fprintf(DEF_FILE, " ;\n");
1181 }
1182 
1183 
1184 /*  ------------------------------------------------------------------
1185  *  Function  :  "fprintPINS()".
1186  */
1187 
fprintPINS()1188 static void  fprintPINS()
1189 {
1190   struct    locon *pLoCon;
1191   struct    phcon  Phcon;
1192   struct eLoseg_s *pLoseg;
1193              long  loconNB, phconNB;
1194 
1195 
1196   loconNB = 0;
1197 
1198   /* First : compute the number of terminals. */
1199   for(pLoCon = LV_lofig->LOCON;
1200       pLoCon != (locon_list*)NULL; pLoCon = pLoCon->NEXT) {
1201     loconNB += 1;
1202     phconNB  = 0;
1203 
1204     if (LV_phfig) {
1205       pLoseg = getloseglist (LV_phfig, getsigname (pLoCon->SIG));
1206 
1207       for (; pLoseg != NULL; pLoseg = pLoseg->next) {
1208         if (pLoseg->type == LOSEG_CON) { phconNB += 1; }
1209       }
1210 
1211       if (phconNB > 1) loconNB += phconNB - 1;
1212     }
1213   }
1214 
1215   fprintf(DEF_FILE, "\n\nPINS %ld ;\n", loconNB);
1216 
1217   for(pLoCon = LV_lofig->LOCON;
1218       pLoCon != (locon_list*)NULL; pLoCon = pLoCon->NEXT) {
1219 
1220     phconNB = 0;
1221 
1222     if (LV_phfig) {
1223       pLoseg = getloseglist (LV_phfig, getsigname (pLoCon->SIG));
1224 
1225       for (; pLoseg != NULL; pLoseg = pLoseg->next) {
1226         __DBG(
1227           fprintf (stderr, "sig %s pLoseg->type := %ld\n",
1228                    getsigname (pLoCon->SIG),
1229                    pLoseg->type);
1230           fflush (stderr);
1231         )
1232         if (pLoseg->type == LOSEG_CON) {
1233           phconNB += 1;
1234 
1235           fprintPIN (pLoCon, (struct phcon*)(pLoseg->MBKobj), "FIXED");
1236         }
1237       }
1238     }
1239 
1240     if (!phconNB) {
1241       Phcon.XCON   = 0;
1242       Phcon.YCON   = 0;
1243       Phcon.INDEX  = 0;
1244       Phcon.WIDTH  = MBKSCALE(2);
1245       Phcon.LAYER  = ALU2;
1246       Phcon.ORIENT = SOUTH;
1247 
1248       fprintPIN (pLoCon, &Phcon, "UNPLACED");
1249     }
1250   }
1251 
1252   fprintf(DEF_FILE, "END PINS\n");
1253 }
1254 
1255 
1256 /*  ------------------------------------------------------------------
1257  *  Function  :  "checkPhins()".
1258  */
1259 
checkPhins(apPhins)1260 static long  checkPhins(apPhins)
1261   struct phins *apPhins;
1262 {
1263   struct row_s *pRow;
1264           char  sameOrient, oppositeOrient, orient;
1265 
1266 
1267   orientPhfig (getphfig (apPhins->FIGNAME, 'A'),
1268                &sameOrient,
1269                &oppositeOrient);
1270 
1271   orient = DEF_N;
1272 
1273   switch (normOrient (MBK2DEF_transf (apPhins->TRANSF))) {
1274     case DEF_W:
1275     case DEF_N:  orient = sameOrient;     break;
1276     case DEF_FE:
1277     case DEF_FS: orient = oppositeOrient; break;
1278   }
1279 
1280   pRow = getBaseRow (apPhins->XINS, apPhins->YINS, orient);
1281 
1282 
1283   if (!pRow) {
1284     warnMBK (NULL);
1285     wprintf ("\n  Instance %s of model %s at (%ld,%ld) is NOT on row grid.\n",
1286              apPhins->INSNAME,
1287              apPhins->FIGNAME,
1288              apPhins->XINS,
1289              apPhins->YINS);
1290     wprintf (  "  Will be removed from the placement file.\n");
1291 
1292     return (FALSE);
1293   }
1294 
1295   return (TRUE);
1296 }
1297 
1298 
1299 /*  ------------------------------------------------------------------
1300  *  Function  :  "fprintCOMPONENTS()".
1301  */
1302 
fprintCOMPONENTS()1303 static void  fprintCOMPONENTS()
1304 {
1305   loins_list *pLoins;
1306   phins_list *pPhins;
1307         long  loInsNB;
1308 
1309 
1310   /* First : compute the number of instances. */
1311   for(pLoins  = LV_lofig->LOINS, loInsNB = 0L;
1312       pLoins != NULL; loInsNB++, pLoins = pLoins->NEXT);
1313 
1314   fprintf(DEF_FILE, "\n\nCOMPONENTS %ld ;\n", loInsNB);
1315 
1316   /* Dump the list of instance/model pairs. */
1317   for(pLoins  = LV_lofig->LOINS;
1318       pLoins != (loins_list*)NULL; pLoins  = pLoins->NEXT) {
1319     fprintf(DEF_FILE, "    - %s %s ", pLoins->INSNAME, pLoins->FIGNAME);
1320 
1321     if (!(pPhins = getphinslink(pLoins)) || !checkPhins (pPhins)) {
1322       fprintf(DEF_FILE, ";\n");
1323     } else {
1324       fprintf(DEF_FILE,
1325               "+ FIXED ( %ld %ld ) %s ;\n",
1326               MBK2DEF_length(pPhins->XINS),
1327               MBK2DEF_length(pPhins->YINS),
1328               DEF_orient2a(MBK2DEF_transf (pPhins->TRANSF)));
1329     }
1330   }
1331 
1332 
1333   fprintf(DEF_FILE, "END COMPONENTS\n");
1334 }
1335 
1336 
1337 /*  ------------------------------------------------------------------
1338  *  Function  :  "fprintWIRESEG()".
1339  */
1340 
fprintWIRESEG(apPhseg,aFlags)1341 static void  fprintWIRESEG(apPhseg, aFlags)
1342   struct phseg *apPhseg;
1343           long  aFlags;
1344 {
1345   fprintf (DEF_FILE, "%s ", DEF_layer2a (apPhseg->LAYER));
1346 
1347   if (aFlags & F_SEG_WIDTH)
1348     fprintf (DEF_FILE, "%ld ", MBK2DEF_length (apPhseg->WIDTH));
1349 
1350   if (aFlags & F_SEG_STRIPE)
1351     fprintf (DEF_FILE, "+ SHAPE STRIPE ");
1352 
1353   fprintf (DEF_FILE, "( %ld %ld ) ( %ld %ld ) ",
1354            MBK2DEF_length (apPhseg->X1),
1355            MBK2DEF_length (apPhseg->Y1),
1356            MBK2DEF_length (apPhseg->X2),
1357            MBK2DEF_length (apPhseg->Y2));
1358 
1359   __DBG(
1360     fprintf (stderr, "MBK X1 := %ld, DEF X1 := %ld\n",
1361                      apPhseg->X1, MBK2DEF_length (apPhseg->X1));
1362   )
1363 }
1364 
1365 
1366 /*  ------------------------------------------------------------------
1367  *  Function  :  "fprintWIREVIA()".
1368  */
1369 
fprintWIREVIA(apPhvia,aFlags)1370 static void  fprintWIREVIA(apPhvia, aFlags)
1371   struct phvia *apPhvia;
1372           long  aFlags;
1373 {
1374   char  viaName[1024];
1375 
1376 
1377   fprintf (DEF_FILE, "%s ", DEF_layer2a (getBottomVIALayer (apPhvia->TYPE)));
1378 
1379   if (aFlags & F_SEG_WIDTH)
1380     fprintf (DEF_FILE, "%ld ", MBK2DEF_length (apPhvia->DX));
1381 
1382   fprintf (DEF_FILE, "( %ld %ld ) %s ",
1383            MBK2DEF_length (apPhvia->XVIA),
1384            MBK2DEF_length (apPhvia->YVIA),
1385            DEF_via2a (apPhvia->TYPE, apPhvia->DX, apPhvia->DY, viaName));
1386 }
1387 
1388 
1389 /*  ------------------------------------------------------------------
1390  *  Function  :  "fprintWIRES()".
1391  */
1392 
fprintWIRES(apLosig)1393 static void  fprintWIRES(apLosig)
1394   struct losig *apLosig;
1395 {
1396   struct eLoseg_s *pLoseg;
1397              long  flagFirst, flagSeg;
1398 
1399 
1400   flagFirst = TRUE;
1401   pLoseg    = getloseglist (LV_phfig, getsigname (apLosig));
1402 
1403   flagSeg = 0L;
1404   if (LV_localFlags & F_SPECIAL_NET) {
1405     flagSeg = F_SEG_STRIPE | F_SEG_WIDTH;
1406   }
1407 
1408 
1409   if (pLoseg) {
1410     for (; pLoseg != NULL; pLoseg = pLoseg->next) {
1411       if (!flagFirst)
1412         fprintf (DEF_FILE, "\n        NEW ");
1413 
1414       switch (pLoseg->type) {
1415         case LOSEG_SEG:
1416           if (flagFirst) fprintf (DEF_FILE, "\n      + ROUTED ");
1417           fprintWIRESEG ((struct phseg*)pLoseg->MBKobj, flagSeg);
1418           flagFirst = FALSE;
1419           break;
1420         case LOSEG_VIA:
1421           if (flagFirst) fprintf (DEF_FILE, "\n      + ROUTED ");
1422           fprintWIREVIA ((struct phvia*)pLoseg->MBKobj, flagSeg);
1423           flagFirst = FALSE;
1424           break;
1425       }
1426 
1427     }
1428   }
1429 }
1430 
1431 
1432 /*  ------------------------------------------------------------------
1433  *  Function  :  "fprintNET()".
1434  */
1435 
fprintNET(apLoSig,aUse)1436 static void  fprintNET(apLoSig, aUse)
1437   losig_list *apLoSig;
1438         char  aUse;
1439 {
1440   struct    ptype *pType;
1441   struct    chain *pChain;
1442   struct    locon *pLoCon;
1443   struct authelem *pElem;
1444              char  sLine[80], sItem[1024];
1445              char *sSig, sSigLEF[1024], sConLEF[1024];
1446              long  lLine;
1447 
1448 
1449   /* Try to guess if this is a VST devectorized internal signal.
1450    * We first seach a loseg with the signal name, if nothing is
1451    * found we try with a vectorized name.
1452    */
1453   sSig  = getsigname (apLoSig);
1454   pElem = searchauthelem (LV_htTerm, sSig);
1455 
1456   /* In case of external signal, override with the terminal name. */
1457   if (pElem != NULL) { sSig = (char*)pElem->VALUE; }
1458 
1459   pType = getptype(apLoSig->USER, (long)LOFIGCHAIN);
1460   if (pType == (ptype_list*)NULL) {
1461     wprinth((char*)NULL);
1462     wprintf(" Signal \"%s\" have no LOFIGCHAIN.\n", sSig);
1463 
1464     pChain = (chain_list*)NULL;
1465   } else {
1466     pChain = (chain_list*)(pType->DATA);
1467   }
1468 
1469 
1470   sSig = MBK2DEF_name(sSigLEF, sSig);
1471 /*snprintf(sItem, 79, "    - %s ", sSig);*/
1472   sprintf(sItem, "    - %s ", sSig);
1473 
1474   sLine[0] = (char)0; lLine = 0L;
1475   if (strlen (sItem) > 79)
1476     fprintf(DEF_FILE, "%s\n", sItem);
1477   else
1478     strLCat(sLine, sItem, &lLine, 79);
1479 
1480 
1481 
1482   for(; pChain != (chain_list*)NULL;
1483         pChain  = pChain->NEXT) {
1484     pLoCon = (locon_list*)(pChain->DATA);
1485 
1486     if (pLoCon->TYPE == INTERNAL) {
1487     /*snprintf(sItem, 79, "( %s %s ) ",
1488      *        ((loins_list*)(pLoCon->ROOT))->INSNAME,
1489      *        MBK2DEF_name(sConLEF, pLoCon->NAME));
1490      */
1491       sprintf(sItem, "( %s %s ) ",
1492              ((loins_list*)(pLoCon->ROOT))->INSNAME,
1493              MBK2DEF_name(sConLEF, pLoCon->NAME));
1494 
1495       if (lLine + strlen(sItem) + 4 > 70) {
1496         fprintf(DEF_FILE, "%s", sLine);
1497         if (strlen (sItem) > 70) {
1498           /* sItem too long anyway... flush it immediatly. */
1499           fprintf(DEF_FILE, " %s\n", sItem);
1500           sItem[0] = (char)0;
1501         } else {
1502           fprintf(DEF_FILE, "\n");
1503         }
1504         lLine = 0L;
1505         strLCat(sLine, "        ", &lLine, 79);
1506       }
1507       strLCat(sLine, sItem, &lLine, 79);
1508     }
1509   }
1510   if (lLine > 0) fprintf(DEF_FILE, "%s", sLine);
1511 
1512   if (LV_phfig) fprintWIRES (apLoSig);
1513 
1514   if (aUse != C_USE_NONE)
1515     fprintf(DEF_FILE, "\n      + USE %s ;\n", USEtoa(aUse));
1516   else
1517     fprintf(DEF_FILE, " ;\n");
1518 }
1519 
1520 
1521 /*  ------------------------------------------------------------------
1522  *  Function  :  "fprintNETS()".
1523  */
1524 
fprintNETS()1525 static void  fprintNETS()
1526 {
1527   losig_list *pLoSig;
1528         long  loSigNB;
1529         char *sSig;
1530 
1531 
1532   LV_localFlags &= ~ F_SPECIAL_NET;
1533   LV_localFlags |=   F_REGULAR_NET;
1534 
1535 
1536   /* First : compute the number of signals. */
1537   for(pLoSig = LV_lofig->LOSIG, loSigNB = 0L;
1538       pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) {
1539     sSig = getsigname(pLoSig);
1540     if (isvdd(sSig) || isvss(sSig) || isck(sSig)) continue;
1541 
1542     loSigNB += 1;
1543   }
1544 
1545   fprintf(DEF_FILE, "\n\nNETS %ld ;\n", loSigNB);
1546 
1547   /* Dump the list of signal connections. */
1548   for(pLoSig  = LV_lofig->LOSIG;
1549       pLoSig != (losig_list*)NULL; pLoSig  = pLoSig->NEXT) {
1550 
1551     sSig = getsigname(pLoSig);
1552     if (     isvdd(sSig)
1553         ||   isvss(sSig)
1554         ||   !strcmp(sSig, "cki")
1555         ||   isck(sSig)) continue;
1556 
1557     fprintNET(pLoSig, C_USE_NONE);
1558   }
1559 
1560   fprintf(DEF_FILE, "END NETS\n");
1561 }
1562 
1563 
1564 /*  ------------------------------------------------------------------
1565  *  Function  :  "fprintSPECIALNETS()".
1566  */
1567 
fprintSPECIALNETS()1568 static void  fprintSPECIALNETS()
1569 {
1570   losig_list *pLoSig;
1571         long  loSigNB;
1572         char *sSig, Use;
1573 
1574 
1575   LV_localFlags &= ~ F_REGULAR_NET;
1576   LV_localFlags |=   F_SPECIAL_NET;
1577 
1578 
1579   /* First : compute the number of signals. */
1580   for(pLoSig = LV_lofig->LOSIG, loSigNB = 0L;
1581       pLoSig != (losig_list*)NULL; pLoSig = pLoSig->NEXT) {
1582     sSig = getsigname(pLoSig);
1583     if (    !isvdd(sSig)
1584         &&  !isvss(sSig)
1585         &&  strcmp(sSig, "cki")
1586         &&  !isck(sSig)) continue;
1587 
1588     loSigNB += 1;
1589   }
1590 
1591   fprintf(DEF_FILE, "\n\nSPECIALNETS %ld ;\n",
1592           loSigNB + ((LV_blockage) ? 1 : 0));
1593 
1594   /* Dump the list of signal connections. */
1595   for(pLoSig  = LV_lofig->LOSIG;
1596       pLoSig != (losig_list*)NULL; pLoSig  = pLoSig->NEXT) {
1597 
1598     sSig = getsigname(pLoSig);
1599 
1600     Use = C_USE_NONE;
1601     if (  isvdd(sSig)       ) Use = C_USE_POWER;
1602     if (  isvss(sSig)       ) Use = C_USE_GROUND;
1603     if (!strcmp(sSig, "cki")) Use = C_USE_CLOCK;
1604     if (  isck(sSig)        ) Use = C_USE_CLOCK;
1605     if (Use == C_USE_NONE) continue;
1606 
1607     fprintNET(pLoSig, Use);
1608   }
1609 
1610   fprintBLOCKAGE ();
1611 
1612   fprintf(DEF_FILE, "END SPECIALNETS\n");
1613 }
1614 
1615 
1616 /*  ------------------------------------------------------------------
1617  *  Function  :  "fprintDEF()".
1618  */
1619 
fprintDEF()1620 static void  fprintDEF()
1621 {
1622   fprintf (DEF_FILE, "VERSION             5.2 ;\n");
1623   fprintf (DEF_FILE, "NAMESCASESENSITIVE  ON ;\n");
1624   fprintf (DEF_FILE, "BUSBITCHARS         \"()\" ;\n");
1625   fprintf (DEF_FILE, "DIVIDERCHAR         \".\" ;\n\n");
1626 
1627   fprintf (DEF_FILE, "DESIGN %s ;\n\n", LV_name);
1628   fprintf (DEF_FILE, "    TECHNOLOGY %s ;\n\n"             , "cmos");
1629   fprintf (DEF_FILE, "    UNITS DISTANCE MICRONS %ld ;\n", DEF_UNITS_MICRONS);
1630 
1631   if (LV_phfig) {
1632     fprintDIEAREA ();
1633 
1634     ref2ROW ();
1635     if (!LV_row) {
1636       wprinth ("fprintfDEF");
1637       wprintf ("\n  Generate default rows and tracks. This may lead to");
1638       wprintf ("\n  incorrect results if the design is expanded.\n");
1639 
1640       buildROWS (LV_phfig);
1641       buildTRACKS (LV_phfig, LV_Flags);
1642     } else {
1643       ref2TRACK ();
1644     }
1645 
1646     fprintROWS ();
1647     fprintTRACKS ();
1648 
1649     ref2BLOCKAGE();
1650 
1651     fprintVIAS ();
1652   }
1653 
1654 
1655   fprintCOMPONENTS ();
1656   fprintPINS ();
1657   fprintNETS ();
1658 
1659   fprintSPECIALNETS ();
1660 
1661   fprintf(DEF_FILE, "\n\nEND DESIGN\n");
1662 }
1663 
1664 
1665 /*  ------------------------------------------------------------------
1666  *  Function  :  "defsavelophfig()".
1667 */
1668 
defsavelophfig(apLofig,apPhfig,aDefName,aFlags)1669 extern void  defsavelophfig(apLofig, apPhfig, aDefName, aFlags)
1670   struct lofig *apLofig;
1671   struct phfig *apPhfig;
1672           char *aDefName;
1673           long  aFlags;
1674 {
1675   LV_Flags    = aFlags;
1676   LV_lofig    = apLofig;
1677   LV_phfig    = apPhfig;
1678   LV_name     = aDefName;
1679   LV_row      = NULL;
1680   LV_track    = NULL;
1681   LV_blockage = NULL;
1682 
1683   if (LV_phfig) {
1684     addfeed (LV_lofig, LV_phfig);
1685     lofigchain (LV_lofig);
1686   }
1687 
1688   buildphinslinks ();
1689   buildtterm ();
1690 
1691   if (!LV_name) LV_name = apLofig->NAME;
1692   DEF_FILE = mbkfopen (LV_name, "def", "w+");
1693 
1694   fprintDEF ();
1695   if (LV_phfig) checklosegaccess (LV_phfig);
1696 
1697   fclose (DEF_FILE);
1698   freerow ();
1699   freetrack ();
1700   freeblockage ();
1701 
1702   freetterm ();
1703   freephinslinks ();
1704 
1705   if (LV_phfig) {
1706     delfeed (LV_lofig);
1707     lofigchain (LV_lofig);
1708   }
1709 }
1710