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