1 /*
2  *  $Id: util_Floorplan.c,v 1.3 2006/06/28 13:25:07 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    :         "./util_Floorplan.c"                    |
13  *  | ************************************************************** |
14  *  |  U p d a t e s                                                 |
15  *  |                                                                |
16  *  \----------------------------------------------------------------/
17  */
18 
19 
20 # include  "util_Defs.h"
21 # include  "debugoff.h"
22 
23 
24 /*  ------------------------------------------------------------------
25  *  Local constants.
26  */
27 
28 # define        F_NO_OVERLAP        ((long)(1<<0))
29 # define        F_OVERLAP           ((long)(1<<1))
30 # define        F_I1_IN_I2          ((long)(1<<2))
31 # define        F_I2_IN_I1          ((long)(1<<3))
32 # define        F_SEG_EXCLUS        ((long)(1<<0))
33 # define        F_SEG_INCLUS        ((long)(1<<1))
34 # define        F_SEG_HALFOVER      ((long)(1<<2))
35 # define        F_SEG_OVER          ((long)(1<<3))
36 # define        F_TERM_XY           ((long)(1<<0))
37 # define        F_TERM_LAYER        ((long)(1<<1))
38 # define        F_TERM_SIDE         ((long)(1<<2))
39 # define        F_TERM_USER         ((long)(1<<3))
40 
41 # define        F_SIDE_FULL         ((long)(1<<1))
42 
43 # define        SIDE_NORTH          0
44 # define        SIDE_SOUTH          1
45 # define        SIDE_EAST           2
46 # define        SIDE_WEST           3
47 # define        SIDE_ALL            4
48 
49 
50 /*  ------------------------------------------------------------------
51  *  Local structures.
52  */
53 
54   typedef struct ulocon_s {
55     long  flags;
56   } ulocon_t;
57 
58   typedef struct term_s {
59              long  flags;
60              char *name;
61              char  layer;
62              long  XY;
63     struct term_s *next;
64   } term_t;
65 
66 
67   typedef struct side_s {
68            char    orient;
69            char    layer;
70            long    flags;
71            long    x;
72            long    y;
73            long    length;
74            long    nbTerm;
75            long    maxTerm;
76     struct term_s *lTerm;
77   } side_t;
78 
79 
80 /*  ------------------------------------------------------------------
81  *  Local variables.
82  */
83 
84   static         char  routingLayers3[256] = "alu1.alu2.alu3.";
85   static         char  routingLayers4[256] =
86                         "alu1.alu2.alu3.alu4.";
87   static         char  routingLayers6[256] =
88                         "alu1.alu2.alu3.alu4.alu5.alu6.";
89   static         long  LV_dupTerm;
90   static         long  LV_loTerm;
91 
92 
93 /*  ------------------------------------------------------------------
94  *  Local macros.
95  */
96 
97 # define    SNAPGRID(x)  ((x) - ((x) % MBK_X_GRID))
98 
99 
100 /*  ----------------------------------------------------------------------
101  *  Local functions declarations.
102  */
103 
104   static struct term_s   *newTerm         __FP((struct term_s *apHead,
105                                                          long  aFlags,
106                                                          char *aName,
107                                                          char  aLayer,
108                                                          long  aXY));
109   static struct term_s   *freeTerm        __FP((struct term_s *apTerm));
110   static struct ulocon_s *getUlocon       __FP((struct locon *apLocon));
111   static struct ulocon_s *newUlocon       __FP((struct locon *apLocon));
112   static void             freeUlocon      __FP((struct locon *apLocon));
113   static void             linkTerm        __FP((struct locon *apLocon,
114                                                         long  aFlags));
115   static void             unlinkTerm      __FP((struct locon *apLocon));
116   static struct side_s   *newSide         __FP((char aOrient,
117                                                 char aLayer,
118                                                 long aX,
119                                                 long aY,
120                                                 long aLength));
121   static void             freeSide        __FP((struct side_s *apSide));
122   static struct side_s   *buildSide       __FP((struct phfig *apPhfig,
123                                                 struct lofig *apLofig,
124                                                         char  aOrient,
125                                                         char  aLayer));
126   static            long  countDupTerms   __FP((struct phfig *apPhfig));
127   static            long  addLoconUinfo   __FP((struct lofig *apLofig));
128   static            void  freeLoconUinfo  __FP((struct lofig *apLofig));
129   static            long  computeArea     __FP((struct lofig *apLofig));
130 # if 0
131   static            long  intervalRel     __FP((long  aI1_min,
132                                                 long  aI1_max,
133                                                 long  aI2_min,
134                                                 long  aI2_max));
135   static            long  segInArea       __FP((struct phseg *aPhseg,
136                                                         long  aX1,
137                                                         long  aY1,
138                                                         long  aX2,
139                                                         long  aY2));
140 # endif
141 
142 
143 /*
144  *  /--------------------------------------------------------------------\
145  *  |                     Functions Definitions                          |
146  *  \--------------------------------------------------------------------/
147  */
148 
149 /*  ----------------------------------------------------------------------
150  *  Function  :  "newTerm()".
151  */
152 
newTerm(apHead,aFlags,aName,aLayer,aXY)153 static struct term_s *newTerm (apHead, aFlags, aName, aLayer, aXY)
154   struct term_s *apHead;
155            long  aFlags;
156            char *aName;
157            char  aLayer;
158            long  aXY;
159 {
160   struct term_s *pTerm;
161 
162 
163   pTerm = (struct term_s*)mbkalloc (sizeof (struct term_s));
164 
165   pTerm->flags = aFlags;
166   pTerm->name  = aName;
167   pTerm->layer = aLayer;
168   pTerm->XY    = aXY;
169   pTerm->next  = apHead;
170 
171   return (pTerm);
172 }
173 
174 
175 /*  ----------------------------------------------------------------------
176  *  Function  :  "freeTerm()".
177  */
178 
freeTerm(apTerm)179 static struct term_s *freeTerm (apTerm)
180   struct term_s *apTerm;
181 {
182   struct term_s *pNext;
183 
184 
185   pNext = apTerm->next;
186 
187   mbkfree (apTerm);
188 
189   return (pNext);
190 }
191 
192 
193 /*  ----------------------------------------------------------------------
194  *  Function  :  "getUlocon()".
195  */
196 
getUlocon(apLocon)197 static struct ulocon_s *getUlocon (apLocon)
198   struct locon *apLocon;
199 {
200   struct ptype    *pType;
201 
202 
203   if (!(pType = getptype (apLocon->USER, PTYPE_ULOCON))) return (NULL);
204 
205   return ((struct ulocon_s*)pType->DATA);
206 }
207 
208 
209 /*  ----------------------------------------------------------------------
210  *  Function  :  "newUlocon()".
211  */
212 
newUlocon(apLocon)213 static struct ulocon_s *newUlocon (apLocon)
214   struct locon *apLocon;
215 {
216   struct ulocon_s *pUlocon;
217 
218 
219   if (!(pUlocon = getUlocon (apLocon))) {
220     pUlocon = (struct ulocon_s*)mbkalloc (sizeof (struct ulocon_s));
221 
222     pUlocon->flags = 0L;
223 
224     apLocon->USER = addptype (apLocon->USER, PTYPE_ULOCON, (void*)pUlocon);
225   }
226 
227 
228   return (pUlocon);
229 }
230 
231 
232 /*  ----------------------------------------------------------------------
233  *  Function  :  "freeUlocon()".
234  */
235 
freeUlocon(apLocon)236 static void  freeUlocon (apLocon)
237   struct locon *apLocon;
238 {
239   struct ptype *pType;
240 
241 
242   if ((pType = getptype (apLocon->USER, PTYPE_ULOCON))) {
243     mbkfree (pType->DATA);
244 
245     apLocon->USER = delptype (apLocon->USER, PTYPE_ULOCON);
246   }
247 }
248 
249 
250 /*  ----------------------------------------------------------------------
251  *  Function  :  "linkTerm()".
252  */
253 
linkTerm(apLocon,aFlags)254 static void  linkTerm (apLocon, aFlags)
255   struct locon  *apLocon;
256           long   aFlags;
257 {
258   struct ulocon_s *pUlocon;
259 
260 
261   if (!(pUlocon = getUlocon (apLocon)))
262     pUlocon = newUlocon (apLocon);
263 
264   pUlocon->flags = aFlags;
265 }
266 
267 
268 /*  ----------------------------------------------------------------------
269  *  Function  :  "unlinkTerm()".
270  */
271 
unlinkTerm(apLocon)272 static void  unlinkTerm (apLocon)
273   struct locon *apLocon;
274 {
275   freeUlocon (apLocon);
276 }
277 
278 
279 /*  ----------------------------------------------------------------------
280  *  Function  :  "newSide()".
281  */
282 
newSide(aOrient,aLayer,aX,aY,aLength)283 static struct side_s *newSide (aOrient, aLayer, aX, aY, aLength)
284   char  aOrient;
285   char  aLayer;
286   long  aX;
287   long  aY;
288   long  aLength;
289 {
290   struct side_s *pSide;
291 
292 
293   pSide = (struct side_s*)mbkalloc (sizeof (struct side_s));
294 
295   pSide->nbTerm   = 0;
296   pSide->maxTerm  = 0;
297   pSide->flags    = 0;
298   pSide->lTerm    = NULL;
299   pSide->orient   = aOrient;
300   pSide->layer    = aLayer;
301   pSide->x        = aX;
302   pSide->y        = aY;
303   pSide->length   = aLength;
304 
305   return (pSide);
306 }
307 
308 
309 /*  ----------------------------------------------------------------------
310  *  Function  :  "freeSide()".
311  */
312 
freeSide(apSide)313 static void  freeSide (apSide)
314   struct side_s *apSide;
315 {
316   struct term_s *pTerm;
317 
318 
319   for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = freeTerm (pTerm));
320 
321   mbkfree (apSide);
322 }
323 
324 
325 /*  ----------------------------------------------------------------------
326  *  Function  :  "buildSide()".
327  */
328 
buildSide(apPhfig,apLofig,aOrient,aLayer)329 static struct side_s *buildSide (apPhfig, apLofig, aOrient, aLayer)
330   struct phfig *apPhfig;
331   struct lofig *apLofig;
332           char  aOrient;
333           char  aLayer;
334 {
335   struct side_s *pSide;
336   struct  phcon *pPhcon;
337            long  XSIDE, YSIDE, sideLength;
338 
339 
340   switch (aOrient) {
341     case WEST:
342       XSIDE      = apPhfig->XAB1;
343       YSIDE      = apPhfig->YAB1;
344       sideLength = apPhfig->YAB2 - apPhfig->YAB1;
345       break;
346     case EAST:
347       XSIDE      = apPhfig->XAB2;
348       YSIDE      = apPhfig->YAB1;
349       sideLength = apPhfig->YAB2 - apPhfig->YAB1;
350       break;
351     case NORTH:
352       XSIDE      = apPhfig->XAB1;
353       YSIDE      = apPhfig->YAB2;
354       sideLength = apPhfig->XAB2 - apPhfig->XAB1;
355       break;
356     default:
357     case SOUTH:
358       XSIDE      = apPhfig->XAB1;
359       YSIDE      = apPhfig->YAB1;
360       sideLength = apPhfig->XAB2 - apPhfig->XAB1;
361       break;
362   }
363 
364 
365   pSide = newSide (aOrient, aLayer, XSIDE, YSIDE, sideLength);
366 
367   for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
368     /* Checking terminal orientation. */
369     if (pPhcon->ORIENT == aOrient) {
370       switch (aOrient) {
371         case EAST:
372         case WEST:
373           if (XSIDE != pPhcon->XCON) {
374             eprinth ("buildSide");
375             eprintf ("\n  East/west terminal %s at (%ld,%ld) is not on",
376                      pPhcon->NAME,
377                      pPhcon->XCON,
378                      pPhcon->YCON);
379             eprintf ("\n  the abutment-box.\n");
380             EXIT (1);
381           }
382 
383           /* Adding the terminal to the side's list. */
384           pSide->nbTerm++;
385           pSide->lTerm = newTerm (pSide->lTerm,
386                                   F_TERM_XY|F_TERM_LAYER|F_TERM_USER,
387                                   pPhcon->NAME,
388                                   pPhcon->LAYER,
389                                   pPhcon->YCON);
390           break;
391         case NORTH:
392         default:
393         case SOUTH:
394           if (YSIDE != pPhcon->YCON) {
395             eprinth ("buildSide");
396             eprintf ("\n  North/south terminal %s at (%ld,%ld) is not on",
397                      pPhcon->NAME,
398                      pPhcon->XCON,
399                      pPhcon->YCON);
400             eprintf ("\n  the abutment-box.\n");
401             EXIT (1);
402           }
403 
404           /* Adding the terminal to the side's list. */
405           pSide->nbTerm++;
406           pSide->lTerm = newTerm (pSide->lTerm,
407                                   F_TERM_XY|F_TERM_LAYER|F_TERM_USER,
408                                   pPhcon->NAME,
409                                   pPhcon->LAYER,
410                                   pPhcon->XCON);
411           break;
412       }
413 
414       linkTerm (getlocon (apLofig, pPhcon->NAME),
415                 F_TERM_XY|F_TERM_LAYER|F_TERM_SIDE);
416     }
417   }
418 
419   return (pSide);
420 }
421 
422 
423 /*  ----------------------------------------------------------------------
424  *  Function  :  "sortSide()".
425  */
426 
sortSide(apSide)427 static void  sortSide(apSide)
428   struct side_s *apSide;
429 {
430   struct term_s *pTerm;
431            char *tFilled;
432            long  i, spacing, sideOrig;
433 
434 
435   tFilled = (char*)mbkalloc (sizeof (char) * apSide->nbTerm);
436 
437   switch (apSide->orient) {
438     case EAST:
439     case WEST:
440       sideOrig = apSide->y; break;
441     case NORTH:
442     case SOUTH:
443     default:
444       sideOrig = apSide->x; break;
445   }
446 
447   spacing = apSide->length / apSide->nbTerm;
448   for (i = 0; i < apSide->nbTerm; i++) tFilled[i] = '\0';
449 
450   for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = pTerm->next) {
451     if (pTerm->flags & F_TERM_XY) {
452       tFilled[(pTerm->XY - sideOrig) / spacing ] = '\1';
453     }
454   }
455 
456   __DBG( fprintf (stderr, "spacing := %ld\n", spacing); )
457 
458   i = 0;
459   for (pTerm = apSide->lTerm; pTerm != NULL; pTerm = pTerm->next) {
460     __DBG( fprintf (stderr, "i := %ld\n", i); )
461 
462     if (!(pTerm->flags & F_TERM_XY)) {
463       pTerm->XY    = sideOrig + SNAPGRID((spacing * i) + (spacing >> 1));
464       pTerm->layer = apSide->layer;
465 
466       __DBG( fprintf (stderr, "pTerm->XY := %ld\n", pTerm->XY); )
467     }
468 
469     i++;
470   }
471 }
472 
473 
474 /*  ----------------------------------------------------------------------
475  *  Function  :  "countDupTerms()".
476  */
477 
countDupTerms(apPhfig)478 static long  countDupTerms (apPhfig)
479   struct phfig *apPhfig;
480 {
481   struct     phcon *pPhcon;
482   struct authtable *htCon;
483   struct  authelem *pElem;
484 
485 
486   htCon = createauthtable (1024);
487 
488   /* Find the number of duplicated terminals. */
489   for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
490     pElem = searchauthelem (htCon, pPhcon->NAME);
491 
492     if (!pElem) {
493       pElem = addauthelem (htCon, pPhcon->NAME, -1);
494     }
495 
496     pElem->VALUE++;
497   }
498 
499 
500   LV_dupTerm = 0;
501 
502   /* Make the sum. */
503   for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
504     pElem = searchauthelem (htCon, pPhcon->NAME);
505 
506     LV_dupTerm += pElem->VALUE;
507 
508     /* Do not count twice duplicated terminals... */
509     pElem->VALUE = 0;
510   }
511 
512   destroyauthtable (htCon);
513 
514 
515   return (LV_dupTerm);
516 }
517 
518 
519 /*  ----------------------------------------------------------------------
520  *  Function  :  "addLoconUinfo()".
521  */
522 
addLoconUinfo(apLofig)523 static long  addLoconUinfo (apLofig)
524   struct lofig *apLofig;
525 {
526   struct     locon *pLocon;
527 
528 
529   LV_loTerm = 0;
530 
531 
532   for (pLocon = apLofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) {
533     LV_loTerm++;
534 
535     linkTerm (pLocon, 0);
536   }
537 
538   return (LV_loTerm);
539 }
540 
541 
542 /*  ----------------------------------------------------------------------
543  *  Function  :  "freeLoconUinfo()".
544  */
545 
freeLoconUinfo(apLofig)546 static void  freeLoconUinfo (apLofig)
547   struct lofig *apLofig;
548 {
549   struct     locon *pLocon;
550 
551 
552   for (pLocon = apLofig->LOCON; pLocon != NULL; pLocon = pLocon->NEXT) {
553     unlinkTerm (pLocon);
554   }
555 }
556 
557 
558 /*  ----------------------------------------------------------------------
559  *  Function  :  "nextFreeLocon()".
560  */
561 
nextFreeLocon(apLocon)562 static struct locon *nextFreeLocon (apLocon)
563   struct locon *apLocon;
564 {
565   struct ulocon_s *pUlocon;
566   struct locon    *pLocon;
567 
568 
569   for (pLocon = apLocon; pLocon != NULL; pLocon = pLocon->NEXT) {
570     pUlocon = getUlocon (pLocon);
571 
572     if (!(pUlocon->flags & F_TERM_SIDE)) return (pLocon);
573   }
574 
575   return (NULL);
576 }
577 
578 
579 /*  ----------------------------------------------------------------------
580  *  Function  :  "placeTerms()".
581  */
582 
placeTerms(apLofig,apPhfig)583 extern void  placeTerms (apLofig, apPhfig)
584   struct lofig *apLofig;
585   struct phfig *apPhfig;
586 {
587   struct side_s *tSide[4];
588   struct term_s *pTerm;
589   struct locon  *pLocon;
590            long  iSide;
591            long  spaceTerm, newSpaceTerm, sideSpaceTerm;
592            long  nbPhterm , newNbPhterm;
593            long  nbPlacedTerm;
594            long  flagLoop;
595            long  XCON, YCON;
596 
597 
598   addLoconUinfo (apLofig);
599   countDupTerms (apPhfig);
600 
601   tSide[SIDE_NORTH] = buildSide (apPhfig, apLofig, NORTH, ALU3);
602   tSide[SIDE_SOUTH] = buildSide (apPhfig, apLofig, SOUTH, ALU3);
603   tSide[SIDE_EAST]  = buildSide (apPhfig, apLofig, EAST , ALU2);
604   tSide[SIDE_WEST]  = buildSide (apPhfig, apLofig, WEST , ALU2);
605 
606 
607   /* Side allocation for free terminals. */
608 
609   nbPhterm     = LV_loTerm + LV_dupTerm;
610   spaceTerm    = 0;
611   nbPlacedTerm = 0;
612 
613   for (iSide = 0; iSide < SIDE_ALL; iSide++) {
614     spaceTerm    += tSide[iSide]->length;
615     nbPlacedTerm += tSide[iSide]->nbTerm;
616   }
617 
618   spaceTerm /= (nbPhterm + 1);
619 
620   __DBG( fprintf (stderr, "spaceTerm := %ld\n", spaceTerm); )
621   __DBG( fprintf (stderr, "nbPhterm  := %ld\n", nbPhterm ); )
622 
623 
624   if (nbPlacedTerm < nbPhterm) {
625     /* Find sides with free space for terminals. */
626     for (flagLoop = TRUE; flagLoop; ) {
627       flagLoop = FALSE;
628 
629       newSpaceTerm = 0;
630       newNbPhterm  = LV_loTerm + LV_dupTerm;
631 
632       for (iSide = 0; iSide < SIDE_ALL; iSide++) {
633         if (tSide[iSide]->flags & F_SIDE_FULL) {
634           newNbPhterm -= tSide[iSide]->nbTerm;
635         } else {
636 
637           sideSpaceTerm  = tSide[iSide]->length / (tSide[iSide]->nbTerm + 1);
638           __DBG( fprintf (stderr, "sideSpaceTerm := %ld\n", sideSpaceTerm); )
639 
640           if (sideSpaceTerm <= spaceTerm) {
641             __DBG( fprintf (stderr, "side %ld overloaded\n", iSide); )
642             /* This side is overloaded : skip it. */
643             flagLoop = TRUE;
644 
645             tSide[iSide]->flags   |= F_SIDE_FULL;
646             tSide[iSide]->maxTerm  = tSide[iSide]->nbTerm;
647             newNbPhterm -= tSide[iSide]->nbTerm;
648           } else {
649             newSpaceTerm  += sideSpaceTerm;
650             tSide[iSide]->maxTerm  = tSide[iSide]->length / spaceTerm;
651             __DBG( fprintf (stderr,
652                             "tSide[%ld]->maxTerm := %ld\n",
653                             iSide,
654                             tSide[iSide]->maxTerm); )
655           }
656         }
657       }  /* End of 'for(iSide ...)'. */
658 
659       spaceTerm = newSpaceTerm / (newNbPhterm + 1);
660 
661       __DBG( fprintf (stderr, "spaceTerm := %ld\n", spaceTerm); )
662     }  /* End of 'for(flagLoop... )'. */
663   }
664 
665 
666   /* Dispatch remaining terminals on non-overloaded sides. */
667   iSide = 0;
668 
669   for (pLocon = nextFreeLocon (apLofig->LOCON);
670        pLocon != NULL; pLocon = nextFreeLocon (pLocon->NEXT)) {
671     while (tSide[iSide]->nbTerm >= tSide[iSide]->maxTerm) {
672       if (iSide >= SIDE_ALL) {
673         eprinth ("placeTerms");
674         eprintf ("\n  No more sides to place terminals");
675         eprintf (" (this is a bug)\n\n");
676         EXIT (1);
677       }
678 
679       iSide++;
680     }
681 
682     tSide[iSide]->nbTerm++;
683     tSide[iSide]->lTerm = newTerm (tSide[iSide]->lTerm,
684                                    0,
685                                    pLocon->NAME,
686                                    0,
687                                    0);
688 
689     linkTerm (pLocon, F_TERM_SIDE);
690   }
691 
692 
693   /* Sets the positions on all sides. */
694   for (iSide = 0; iSide < SIDE_ALL; iSide++) {
695     __DBG (fprintf (stderr, "sortSide(%ld)\n", iSide); )
696     sortSide (tSide[iSide]);
697   }
698 
699 
700   /* Add the physical terminals. */
701   for (iSide = 0; iSide < SIDE_ALL; iSide++) {
702     for (pTerm = tSide[iSide]->lTerm; pTerm != NULL; pTerm = pTerm->next) {
703       switch (tSide[iSide]->orient) {
704         case NORTH:
705         case SOUTH:
706         default:
707           XCON = pTerm->XY;
708           YCON = tSide[iSide]->y;
709           break;
710         case EAST:
711         case WEST:
712           XCON = tSide[iSide]->x;
713           YCON = pTerm->XY;
714           break;
715       }
716 
717       addphcon (apPhfig,
718                 tSide[iSide]->orient,
719                 pTerm->name,
720                 XCON,
721                 YCON,
722                 pTerm->layer,
723                 MBKSCALE(2));
724     }
725   }
726 
727 
728 
729   /* Free all the sides structures. */
730   for (iSide = 0; iSide < SIDE_ALL; iSide++) freeSide (tSide[iSide]);
731 
732   freeLoconUinfo (apLofig);
733 }
734 
735 
736 /*  ----------------------------------------------------------------------
737  *  Function  :  "computeArea()".
738  */
739 
computeArea(apLofig)740 static long  computeArea(apLofig)
741   struct lofig *apLofig;
742 {
743   struct loins* pLoins;
744   struct phfig* pModel;
745           long  area;
746           long  AB_width, AB_height;
747 
748 
749   area = 0L;
750 
751   for (pLoins = apLofig->LOINS; pLoins != NULL; pLoins = pLoins->NEXT) {
752     pModel = getphfig (pLoins->FIGNAME, 'P');
753 
754     AB_width  = pModel->XAB2 - pModel->XAB1;
755     AB_height = pModel->YAB2 - pModel->YAB1;
756 
757 
758     if (AB_width <= 0) {
759       eprinth (NULL);
760       eprintf (
761         "Negative or null width (%ld) for abutment box of \"%s\".\n",
762         AB_width, pModel->NAME);
763       EXIT (1);
764     }
765 
766     if (AB_height <= 0) {
767       eprinth (NULL);
768       eprintf (
769         "Negative or null height (%ld) for abutment box of \"%s\".\n",
770         AB_height, pModel->NAME);
771       EXIT (1);
772     }
773 
774     if (AB_width % MBK_X_GRID) {
775       eprinth (NULL);
776       eprintf (
777         "Unpitched width (%ld) for abutment box of \"%s\".\n",
778         AB_width, pModel->NAME);
779       EXIT (1);
780     }
781 
782     if (AB_height % MBK_Y_SLICE) {
783       eprinth (NULL);
784       eprintf (
785         "Unpitched height (%ld) for abutment box of \"%s\".\n",
786         AB_height, pModel->NAME);
787       EXIT (1);
788     }
789 
790 
791     AB_width  = AB_width  / MBK_X_GRID;
792     AB_height = AB_height / MBK_Y_SLICE;
793 
794     area += AB_width * AB_height;
795   }
796 
797 
798   return (area);
799 }
800 
801 
802 /*  ----------------------------------------------------------------------
803  *  Function  :  "makeFloorplan()".
804  */
805 
makeFloorplan(apLofig,aMargin,aXSize,aYSize,aAspectRatio,aPower,aFlags)806 extern struct phfig *makeFloorplan(apLofig,
807                                    aMargin,
808                                    aXSize,
809                                    aYSize,
810                                    aAspectRatio,
811                                    aPower,
812                                    aFlags)
813   struct lofig *apLofig;
814           long  aMargin;
815           long  aXSize;
816           long  aYSize;
817         double  aAspectRatio;
818           long  aPower;
819           long  aFlags;
820 {
821   struct phfig *pPhfig;
822           long  specCount, i;
823           long  area;
824           long  xSize, ySize;
825           long  XAB1, YAB1, XAB2, YAB2;
826           char  row_name[1024], row_type[1024];
827           char *routingLayers;
828 
829 
830   specCount  = (aFlags & F_FLOOR_X_SIZE) ? 1 : 0;
831   specCount += (aFlags & F_FLOOR_Y_SIZE) ? 1 : 0;
832   specCount += (aFlags & F_FLOOR_ASPECT_RATIO) ? 1 : 0;
833 
834   if (specCount != 1) {
835     errMBK  ("makeFloorplan");
836     eprintf ("\n  One, and only one argument among aXSize, aYSize and");
837     eprintf (   " aAspectRatio must\n   be non zero.\n");
838     EXIT (1);
839   }
840 
841   pPhfig = addphfig (apLofig->NAME);
842 
843   area = computeArea (apLofig);
844   area = (long)((1.0 + (double)aMargin / 100.0) * (double)area);
845 
846   /* Shut up GCC. */
847   xSize = 0;
848   ySize = 0;
849 
850   if (aFlags & F_FLOOR_X_SIZE) {
851     xSize = aXSize;
852     ySize =    area / (xSize - 7 * aPower)
853            + ((area % (xSize - 7 * aPower)) ? 1 : 0);
854   }
855 
856   if (aFlags & F_FLOOR_Y_SIZE) {
857     ySize = aYSize;
858     xSize = (7 * aPower) + (area / aYSize) + ((area / aYSize) ? 1 : 0);
859   }
860 
861   if (aFlags & F_FLOOR_ASPECT_RATIO) {
862     double  x, r, b, xy;
863 
864     xy = (double)(Y_SLICE / X_GRID);
865 
866     b = ((double)(7 * aPower)) / xy;
867     x = (b + sqrt (pow (b, 2.0) + 4 * xy * (double)(area) * aAspectRatio))
868       / (2 * xy * aAspectRatio);
869 
870     ySize = (long)floor (x * aAspectRatio);
871 
872     /* Compute missing area (as ySize is rounded down).
873      * The unit the number of horizontal sites.
874      */
875     r = ((double)(area + 7 * aPower * ySize) - pow ((double)ySize, 2.0) * xy)
876       /  (double)(ySize);
877 
878     xSize = ((long)ceil ((double)ySize * xy + r));
879   }
880 
881 
882   XAB1 = 0L;
883   YAB1 = 0L;
884   XAB2 = xSize * MBK_X_GRID;
885   YAB2 = ySize * MBK_Y_SLICE;
886 
887 
888   /* Build the floorplan. */
889 
890   /* The Abutment-box. */
891   defab (pPhfig, XAB1, YAB1, XAB2, YAB2);
892 
893   /* The row matrix. */
894   strcpy (row_type, "core");
895   for (i = 0; i < ySize; i++) {
896     sprintf (row_name, "row_%ld", i);
897 
898     DEF2MBK_row (pPhfig,
899                  row_name,
900                  row_type,
901                  (i % 2) ? DEF_FS : DEF_N,
902                  xSize,
903                  1L,
904                  DEF_X_GRID,
905                  DEF_Y_SLICE,
906                  XAB1,
907                  YAB1 + i * MBK_Y_SLICE);
908   }
909 
910   /* The tracks matrix. */
911   routingLayers = routingLayers6;
912 
913   if (aFlags & F_FLOOR_LAYERS_3) {
914     routingLayers = routingLayers3;
915   }
916 
917   if (aFlags & F_FLOOR_LAYERS_4) {
918     routingLayers = routingLayers4;
919   }
920 
921   /* Horizontal tracks. */
922   DEF2MBK_track (pPhfig,
923                  "Y",
924                  MBK2DEF_length (YAB1 + MBK_X_GRID),
925                  ySize * (Y_SLICE / X_GRID) - 1,
926                  DEF_X_GRID,
927                  routingLayers,
928                  XAB1,
929                  YAB1 + MBK_X_GRID);
930 
931   /* Vertical tracks. */
932   DEF2MBK_track (pPhfig,
933                  "X",
934                  MBK2DEF_length (XAB1 + MBK_X_GRID),
935                  xSize - 1,
936                  DEF_X_GRID,
937                  routingLayers,
938                  XAB1 + MBK_X_GRID,
939                  YAB1);
940 
941 
942   return (pPhfig);
943 }
944 
945 
946 /*  ----------------------------------------------------------------------
947  *  Function  :  "expandFloorplan()".
948  */
949 
expandFloorplan(apPhfig)950 extern void  expandFloorplan(apPhfig)
951   struct phfig *apPhfig;
952 {
953   struct phseg *pPhseg;
954   struct phcon *pPhcon;
955           long  XAB1, YAB1, XAB2, YAB2;
956 
957 
958   XAB1 = apPhfig->XAB1;
959   YAB1 = apPhfig->YAB1;
960   XAB2 = apPhfig->XAB2;
961   YAB2 = apPhfig->YAB2;
962 
963 
964   apPhfig->XAB1 -= FLOOR_XY_EXPAND;
965   apPhfig->YAB1 -= FLOOR_XY_EXPAND;
966   apPhfig->XAB2 += FLOOR_XY_EXPAND;
967   apPhfig->YAB2 += FLOOR_XY_EXPAND;
968 
969 
970   /* Move terminals to the new AB. */
971   for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
972     if (pPhcon->XCON == XAB1) pPhcon->XCON = apPhfig->XAB1;
973     if (pPhcon->XCON == XAB2) pPhcon->XCON = apPhfig->XAB2;
974     if (pPhcon->YCON == YAB1) pPhcon->YCON = apPhfig->YAB1;
975     if (pPhcon->YCON == YAB2) pPhcon->YCON = apPhfig->YAB2;
976   }
977 
978 
979   /* Shrink segments to fit in the new AB. */
980   for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) {
981     if (pPhseg->X1 == XAB1) pPhseg->X1 = apPhfig->XAB1;
982     if (pPhseg->X2 == XAB2) pPhseg->X2 = apPhfig->XAB2;
983     if (pPhseg->Y1 == YAB1) pPhseg->Y1 = apPhfig->YAB1;
984     if (pPhseg->Y2 == YAB2) pPhseg->Y2 = apPhfig->YAB2;
985   }
986 
987 
988 # if 0
989   DEF2MBK_blockage (apPhfig,
990                     MBK2DEF_length (apPhfig->XAB1),
991                     MBK2DEF_length (apPhfig->YAB1),
992                     MBK2DEF_length (FLOOR_XY_EXPAND),
993                     MBK2DEF_length (FLOOR_XY_EXPAND)
994                     );
995 
996   DEF2MBK_blockage (apPhfig,
997                     MBK2DEF_length (apPhfig->XAB1),
998                     MBK2DEF_length (apPhfig->YAB2 - FLOOR_XY_EXPAND),
999                     MBK2DEF_length (FLOOR_XY_EXPAND),
1000                     MBK2DEF_length (FLOOR_XY_EXPAND)
1001                     );
1002 
1003   DEF2MBK_blockage (apPhfig,
1004                     MBK2DEF_length (apPhfig->XAB2 - FLOOR_XY_EXPAND),
1005                     MBK2DEF_length (apPhfig->YAB1),
1006                     MBK2DEF_length (FLOOR_XY_EXPAND),
1007                     MBK2DEF_length (FLOOR_XY_EXPAND)
1008                     );
1009 
1010   DEF2MBK_blockage (apPhfig,
1011                     MBK2DEF_length (apPhfig->XAB2 - FLOOR_XY_EXPAND),
1012                     MBK2DEF_length (apPhfig->YAB2 - FLOOR_XY_EXPAND),
1013                     MBK2DEF_length (FLOOR_XY_EXPAND),
1014                     MBK2DEF_length (FLOOR_XY_EXPAND)
1015                     );
1016 # endif
1017 }
1018 
1019 
1020 # if 0
1021 /*  ----------------------------------------------------------------------
1022  *  Function  :  "intervalRel()".
1023  */
1024 
1025 static long  intervalRel(aI1_min, aI1_max, aI2_min, aI2_max)
1026   long  aI1_min, aI1_max, aI2_min, aI2_max;
1027 {
1028   long  flag;
1029 
1030 
1031   if (aI1_min > aI1_max) {
1032     errMBK  ("intervalRel");
1033     eprintf (" I1_min(%ld) > I1_max(%ld) !\n", aI1_min, aI1_max);
1034     EXIT (1);
1035   }
1036   if (aI2_min > aI2_max) {
1037     errMBK  ("intervalRel");
1038     eprintf (" I2_min(%ld) > I2_max(%ld) !\n", aI2_min, aI2_max);
1039     EXIT (1);
1040   }
1041 
1042 
1043   flag = 2;
1044 
1045   if ((aI1_min < aI2_min) || (aI1_min > aI2_max)) flag--;
1046   if ((aI1_max < aI2_min) || (aI1_max > aI2_max)) flag--;
1047   if ((aI1_min < aI2_min) && (aI1_max > aI2_max)) flag = 3;
1048 
1049 
1050   switch (flag) {
1051     default:
1052     case 3: flag = F_I2_IN_I1;   break;
1053     case 2: flag = F_I1_IN_I2;   break;
1054     case 1: flag = F_OVERLAP;    break;
1055     case 0: flag = F_NO_OVERLAP; break;
1056   }
1057 
1058   return (flag);
1059 }
1060 
1061 
1062 /*  ----------------------------------------------------------------------
1063  *  Function  :  "segInArea()".
1064  */
1065 
1066 static long  segInArea(aPhseg, aX1, aY1, aX2, aY2)
1067   struct phseg *aPhseg;
1068           long  aX1, aY1, aX2, aY2;
1069 {
1070   long  flagX, flagY;
1071 
1072 
1073   if (aX1 > aX2) {
1074     errMBK  ("segInArea");
1075     eprintf ("Bad area X1(%ld) > X2(%ld) !\n", aX1, aX2);
1076     EXIT (1);
1077   }
1078   if (aY1 > aY2) {
1079     errMBK  ("segInArea");
1080     eprintf ("Bad area Y1(%ld) > Y2(%ld) !\n", aY1, aY2);
1081     EXIT (1);
1082   }
1083 
1084 
1085   flagX = intervalRel (aPhseg->X1, aPhseg->X2, aX1, aX2);
1086   flagY = intervalRel (aPhseg->Y1, aPhseg->Y2, aY1, aY2);
1087 
1088 
1089   if ((flagX == F_NO_OVERLAP) || (flagY == F_NO_OVERLAP))
1090     return (F_SEG_EXCLUS);
1091 
1092   if ((flagX == F_I1_IN_I2) && (flagY == F_I1_IN_I2))
1093     return (F_SEG_INCLUS);
1094 
1095   if ((flagX == F_I2_IN_I1) && (flagY == F_I2_IN_I1))
1096     return (F_SEG_HALFOVER);
1097 
1098   return (F_SEG_OVER);
1099 }
1100 # endif
1101 
1102 
1103 /*  ----------------------------------------------------------------------
1104  *  Function  :  "shrinkFloorplan()".
1105  */
1106 
shrinkFloorplan(apPhfig)1107 extern void  shrinkFloorplan(apPhfig)
1108   struct phfig *apPhfig;
1109 {
1110   struct phseg *pPhseg;
1111   struct phcon *pPhcon;
1112   struct phref *pPhref;
1113           long  XAB1, YAB1, XAB2, YAB2;
1114 
1115 
1116   XAB1 = apPhfig->XAB1;
1117   YAB1 = apPhfig->YAB1;
1118   XAB2 = apPhfig->XAB2;
1119   YAB2 = apPhfig->YAB2;
1120 
1121   /* Shrink the abutment-box. */
1122   apPhfig->XAB1 += FLOOR_XY_EXPAND;
1123   apPhfig->YAB1 += FLOOR_XY_EXPAND;
1124   apPhfig->XAB2 -= FLOOR_XY_EXPAND;
1125   apPhfig->YAB2 -= FLOOR_XY_EXPAND;
1126 
1127 
1128   /* Move terminals to the new AB. */
1129   for (pPhcon = apPhfig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
1130     if (pPhcon->XCON == XAB1) pPhcon->XCON = apPhfig->XAB1;
1131     if (pPhcon->XCON == XAB2) pPhcon->XCON = apPhfig->XAB2;
1132     if (pPhcon->YCON == YAB1) pPhcon->YCON = apPhfig->YAB1;
1133     if (pPhcon->YCON == YAB2) pPhcon->YCON = apPhfig->YAB2;
1134   }
1135 
1136 
1137   /* Shrink segments to fit in the new AB. */
1138   for (pPhseg = apPhfig->PHSEG; pPhseg != NULL; pPhseg = pPhseg->NEXT) {
1139     if (pPhseg->X1 == XAB1) pPhseg->X1 = apPhfig->XAB1;
1140     if (pPhseg->X2 == XAB2) pPhseg->X2 = apPhfig->XAB2;
1141     if (pPhseg->Y1 == YAB1) pPhseg->Y1 = apPhfig->YAB1;
1142     if (pPhseg->Y2 == YAB2) pPhseg->Y2 = apPhfig->YAB2;
1143   }
1144 
1145 
1146   /* Move references to the new AB. */
1147   for (pPhref = apPhfig->PHREF; pPhref != NULL; pPhref = pPhref->NEXT) {
1148     if (pPhref->XREF == XAB1) pPhref->XREF = apPhfig->XAB1;
1149     if (pPhref->XREF == XAB2) pPhref->XREF = apPhfig->XAB2;
1150     if (pPhref->YREF == YAB1) pPhref->YREF = apPhfig->YAB1;
1151     if (pPhref->YREF == YAB2) pPhref->YREF = apPhfig->YAB2;
1152   }
1153 }
1154 
1155 
1156 /*  ----------------------------------------------------------------------
1157  *  Function  :  "protectPowmid()".
1158  */
1159 
protectPowmid(apPhfig)1160 extern void  protectPowmid(apPhfig)
1161   struct phfig *apPhfig;
1162 {
1163 # if 0
1164   struct phins *pIns;
1165   struct phfig *pModel;
1166           char *powmidName;
1167           long  width, height, expand;
1168 
1169 
1170   expand = FLOOR_XY_EXPAND;
1171 
1172   powmidName = namealloc ("powmid_x0");
1173   pModel = getphfig ("powmid_x0", 'A');
1174   width  = pModel->XAB2 - pModel->XAB1;
1175   height = pModel->YAB2 - pModel->YAB1;
1176 
1177   for (pIns = apPhfig->PHINS; pIns != NULL; pIns = pIns->NEXT) {
1178     if (pIns->FIGNAME == powmidName) {
1179       if (pIns->YINS == apPhfig->YAB1 + expand) {
1180         DEF2MBK_blockage (apPhfig,
1181                           MBK2DEF_length (pIns->XINS),
1182                           MBK2DEF_length (apPhfig->YAB1),
1183                           MBK2DEF_length (width),
1184                           MBK2DEF_length ((MBK_X_GRID << 1) + expand)
1185                           );
1186       }
1187 
1188       if (pIns->YINS + height == apPhfig->YAB2 - expand) {
1189         DEF2MBK_blockage (apPhfig,
1190                           MBK2DEF_length (pIns->XINS),
1191                           MBK2DEF_length (apPhfig->YAB2
1192                                           - (MBK_X_GRID << 1) - expand),
1193                           MBK2DEF_length (width),
1194                           MBK2DEF_length ((MBK_X_GRID << 1) + expand)
1195                           );
1196       }
1197     }
1198   }
1199 # endif
1200 }
1201