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