1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: sc1electric.c
6 * Modules for the QUISC Silicon Compiler to interface it with Electric
7 * Written by: Andrew R. Kostiuk, Queen's University
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "config.h"
33 #if SCTOOL
34
35 #include "global.h"
36 #include "efunction.h"
37 #include "edialogs.h"
38 #include "sc1.h"
39 #include "usr.h"
40
41 /***********************************************************************
42 Global Variables
43 ------------------------------------------------------------------------
44 */
45
46 TOOL *sc_tool; /* the Silicon Compiler tool object */
47 INTBIG sc_filetypescsim; /* Silicon compiler simulation file descriptor */
48 INTBIG sc_filetypesctab; /* Silicon compiler table file descriptor */
49 static INTBIG sc_simkey; /* key for the ALS info */
50 static INTBIG sc_silkey; /* key for the silos information */
51 static INTBIG sc_bitskey;
52 static INTBIG sc_numskey;
53 static NODEPROTO *sc_layer1proto = NONODEPROTO;
54 static NODEPROTO *sc_layer2proto = NONODEPROTO;
55 static NODEPROTO *sc_viaproto = NONODEPROTO;
56 static NODEPROTO *sc_pwellproto = NONODEPROTO;
57 static NODEPROTO *sc_nwellproto = NONODEPROTO;
58 static ARCPROTO *sc_layer1arc = NOARCPROTO;
59 static ARCPROTO *sc_layer2arc = NOARCPROTO;
60 static LIBRARY *sc_celllibrary = NOLIBRARY;
61
62 extern CHAR *sc_errmsg;
63 extern int sc_sim_format;
64 extern COMCOMP sc_makep;
65
66 /* prototypes for local routines */
67 static void Sc_set_leaf_port_type(PORTPROTO*, int);
68 static void Sc_create_connection(NODEINST **ni, PORTPROTO **pp, INTBIG x, INTBIG y,
69 ARCPROTO *arc);
70 static void sc_optionsdlog(void);
71
72 /***********************************************************************
73 Module: sc_init
74 ------------------------------------------------------------------------
75 Description:
76 Initialize routine for the Silicon Compiler tool.
77 ------------------------------------------------------------------------
78 */
79
sc_init(INTBIG * argc,CHAR1 * argv[],TOOL * thistool)80 void sc_init(INTBIG *argc, CHAR1 *argv[], TOOL *thistool)
81 {
82 Q_UNUSED( argc );
83 Q_UNUSED( argv );
84 /* only initialize during pass 1 */
85 if (thistool == NOTOOL || thistool == 0) return;
86 sc_tool = thistool;
87 Sc_initialize();
88 if ((sc_simkey = makekey(x_("SC_sim"))) == -1)
89 ttyputmsg(x_("ERROR making SIM key in SC Tool"));
90 if ((sc_bitskey = makekey(x_("SC_bits"))) == -1)
91 ttyputmsg(x_("ERROR making BITS key in SC Tool"));
92 if ((sc_numskey = makekey(x_("SC_nums"))) == -1)
93 ttyputmsg(x_("ERROR making NUMS key in SC Tool"));
94 if ((sc_silkey = makekey(x_("SC_silos"))) == -1)
95 ttyputmsg(x_("ERROR making SILOS key in SC Tool."));
96 DiaDeclareHook(x_("silcomp"), &sc_makep, sc_optionsdlog);
97 sc_filetypescsim = setupfiletype(x_(""), x_("*.*"), MACFSTAG('TEXT'), FALSE, x_("scsim"), _("QUISC simulation"));
98 sc_filetypesctab = setupfiletype(x_(""), x_("*.*"), MACFSTAG('TEXT'), FALSE, x_("sctab"), _("QUISC table"));
99 }
100
101 /***********************************************************************
102 Module: sc_slice
103 ------------------------------------------------------------------------
104 Description:
105 Main module of the Silicon Compiler tool. Invoked by the ontool
106 command.
107 ------------------------------------------------------------------------
108 */
109
sc_slice(void)110 void sc_slice(void)
111 {
112 el_pleasestop = 0;
113 Sc_main();
114 toolturnoff(sc_tool, FALSE);
115 }
116
117 /***********************************************************************
118 Module: sc_set
119 ------------------------------------------------------------------------
120 Description:
121 Module invoked by the telltool command.
122 ------------------------------------------------------------------------
123 */
124
sc_set(INTBIG count,CHAR * pars[])125 void sc_set(INTBIG count, CHAR *pars[])
126 {
127 Sc_one_command(count, pars);
128 }
129
130 /***********************************************************************
131 Module: sc_request
132 ------------------------------------------------------------------------
133 Description:
134 Module invoked by the asktool command.
135 ------------------------------------------------------------------------
136 */
137
sc_request(CHAR * command,va_list ap)138 INTBIG sc_request(CHAR *command, va_list ap)
139 {
140 Q_UNUSED( ap );
141
142 if (namesame(command, x_("cell-lib")) == 0)
143 return((INTBIG)sc_celllibrary);
144 return(0);
145 }
146
147 /***********************************************************************
148 Default Silicon Compiler tool routines.
149 ------------------------------------------------------------------------
150 */
151
sc_done(void)152 void sc_done(void) {}
153
154 /***********************************************************************
155 Module: Sc_stop and Sc_clear_stop
156 ------------------------------------------------------------------------
157 Description:
158 Sc_stop returns TRUE if the stopping condition is TRUE. Sc_clear_stop
159 clears the stopping condition.
160 ------------------------------------------------------------------------
161 */
162
Sc_stop(void)163 int Sc_stop(void)
164 {
165 if (stopping(STOPREASONSILCOMP)) return(TRUE);
166 return(FALSE);
167 }
168
Sc_clear_stop(void)169 void Sc_clear_stop(void)
170 {
171 el_pleasestop = 0;
172 }
173
174
ScGetParameter(INTBIG paramnum)175 INTBIG ScGetParameter(INTBIG paramnum)
176 {
177 REGISTER VARIABLE *var;
178
179 var = NOVARIABLE;
180 switch (paramnum)
181 {
182 case SC_PARAM_MAKE_HORIZ_ARC:
183 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_horiz_arc"));
184 if (var == NOVARIABLE) return((INTBIG)DEFAULT_ARC_HORIZONTAL);
185 break;
186 case SC_PARAM_MAKE_VERT_ARC:
187 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_vert_arc"));
188 if (var == NOVARIABLE) return((INTBIG)DEFAULT_ARC_VERTICAL);
189 break;
190 case SC_PARAM_MAKE_L1_WIDTH:
191 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_l1_width"));
192 if (var == NOVARIABLE) return(DEFAULT_L1_TRACK_WIDTH);
193 break;
194 case SC_PARAM_MAKE_L2_WIDTH:
195 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_l2_width"));
196 if (var == NOVARIABLE) return(DEFAULT_L2_TRACK_WIDTH);
197 break;
198 case SC_PARAM_MAKE_PWR_WIDTH:
199 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_pwr_width"));
200 if (var == NOVARIABLE) return(DEFAULT_POWER_TRACK_WIDTH);
201 break;
202 case SC_PARAM_MAKE_MAIN_PWR_WIDTH:
203 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_main_pwr_width"));
204 if (var == NOVARIABLE) return(DEFAULT_MAIN_POWER_WIDTH);
205 break;
206 case SC_PARAM_MAKE_MAIN_PWR_RAIL:
207 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_main_pwr_rail"));
208 if (var == NOVARIABLE) return(DEFAULT_MAIN_POWER_RAIL);
209 break;
210 case SC_PARAM_MAKE_PWELL_SIZE:
211 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_pwell_size"));
212 if (var == NOVARIABLE) return(DEFAULT_PWELL_SIZE);
213 break;
214 case SC_PARAM_MAKE_PWELL_OFFSET:
215 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_pwell_offset"));
216 if (var == NOVARIABLE) return(DEFAULT_PWELL_OFFSET);
217 break;
218 case SC_PARAM_MAKE_NWELL_SIZE:
219 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_nwell_size"));
220 if (var == NOVARIABLE) return(DEFAULT_NWELL_SIZE);
221 break;
222 case SC_PARAM_MAKE_NWELL_OFFSET:
223 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_nwell_offset"));
224 if (var == NOVARIABLE) return(DEFAULT_NWELL_OFFSET);
225 break;
226 case SC_PARAM_MAKE_VIA_SIZE:
227 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_via_size"));
228 if (var == NOVARIABLE) return(DEFAULT_VIA_SIZE);
229 break;
230 case SC_PARAM_MAKE_MIN_SPACING:
231 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_min_spacing"));
232 if (var == NOVARIABLE) return(DEFAULT_MIN_SPACING);
233 break;
234 case SC_PARAM_ROUTE_FEEDTHRU_SIZE:
235 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_feedthru_size"));
236 if (var == NOVARIABLE) return(DEFAULT_FEED_THROUGH_SIZE);
237 break;
238 case SC_PARAM_ROUTE_PORT_X_MIN_DIST:
239 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_port_x_min_dist"));
240 if (var == NOVARIABLE) return(DEFAULT_PORT_X_MIN_DISTANCE);
241 break;
242 case SC_PARAM_ROUTE_ACTIVE_DIST:
243 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_active_dist"));
244 if (var == NOVARIABLE) return(DEFAULT_ACTIVE_DISTANCE);
245 break;
246 case SC_PARAM_PLACE_NUM_ROWS:
247 var = getval((INTBIG)sc_tool, VTOOL, -1, x_("SC_num_rows"));
248 if (var == NOVARIABLE) return(DEFAULT_NUM_OF_ROWS);
249 break;
250 }
251 return(var->addr);
252 }
253
ScSetParameter(INTBIG paramnum,INTBIG addr)254 void ScSetParameter(INTBIG paramnum, INTBIG addr)
255 {
256 switch (paramnum)
257 {
258 case SC_PARAM_MAKE_HORIZ_ARC:
259 setval((INTBIG)sc_tool, VTOOL, x_("SC_horiz_arc"), addr, VARCPROTO);
260 break;
261 case SC_PARAM_MAKE_VERT_ARC:
262 setval((INTBIG)sc_tool, VTOOL, x_("SC_vert_arc"), addr, VARCPROTO);
263 break;
264 case SC_PARAM_MAKE_L1_WIDTH:
265 setval((INTBIG)sc_tool, VTOOL, x_("SC_l1_width"), addr, VINTEGER);
266 break;
267 case SC_PARAM_MAKE_L2_WIDTH:
268 setval((INTBIG)sc_tool, VTOOL, x_("SC_l2_width"), addr, VINTEGER);
269 break;
270 case SC_PARAM_MAKE_PWR_WIDTH:
271 setval((INTBIG)sc_tool, VTOOL, x_("SC_pwr_width"), addr, VINTEGER);
272 break;
273 case SC_PARAM_MAKE_MAIN_PWR_WIDTH:
274 setval((INTBIG)sc_tool, VTOOL, x_("SC_main_pwr_width"), addr, VINTEGER);
275 break;
276 case SC_PARAM_MAKE_MAIN_PWR_RAIL:
277 setval((INTBIG)sc_tool, VTOOL, x_("SC_main_pwr_rail"), addr, VINTEGER);
278 break;
279 case SC_PARAM_MAKE_PWELL_SIZE:
280 setval((INTBIG)sc_tool, VTOOL, x_("SC_pwell_size"), addr, VINTEGER);
281 break;
282 case SC_PARAM_MAKE_PWELL_OFFSET:
283 setval((INTBIG)sc_tool, VTOOL, x_("SC_pwell_offset"), addr, VINTEGER);
284 break;
285 case SC_PARAM_MAKE_NWELL_SIZE:
286 setval((INTBIG)sc_tool, VTOOL, x_("SC_nwell_size"), addr, VINTEGER);
287 break;
288 case SC_PARAM_MAKE_NWELL_OFFSET:
289 setval((INTBIG)sc_tool, VTOOL, x_("SC_nwell_offset"), addr, VINTEGER);
290 break;
291 case SC_PARAM_MAKE_VIA_SIZE:
292 setval((INTBIG)sc_tool, VTOOL, x_("SC_via_size"), addr, VINTEGER);
293 break;
294 case SC_PARAM_MAKE_MIN_SPACING:
295 setval((INTBIG)sc_tool, VTOOL, x_("SC_min_spacing"), addr, VINTEGER);
296 break;
297 case SC_PARAM_ROUTE_FEEDTHRU_SIZE:
298 setval((INTBIG)sc_tool, VTOOL, x_("SC_feedthru_size"), addr, VINTEGER);
299 break;
300 case SC_PARAM_ROUTE_PORT_X_MIN_DIST:
301 setval((INTBIG)sc_tool, VTOOL, x_("SC_port_x_min_dist"), addr, VINTEGER);
302 break;
303 case SC_PARAM_ROUTE_ACTIVE_DIST:
304 setval((INTBIG)sc_tool, VTOOL, x_("SC_active_dist"), addr, VINTEGER);
305 break;
306 case SC_PARAM_PLACE_NUM_ROWS:
307 setval((INTBIG)sc_tool, VTOOL, x_("SC_num_rows"), addr, VINTEGER);
308 break;
309 }
310 }
311
312 /***********************************************************************
313
314 D A T A B A S E I N T E R F A C I N G M O D U L E S
315
316 ------------------------------------------------------------------------
317 */
318
319 /***********************************************************************
320 Module: Sc_find_leaf_cell
321 ------------------------------------------------------------------------
322 Description:
323 Return a pointer to the named leaf cell. If cell is not found,
324 return NULL.
325 ------------------------------------------------------------------------
326 Calling Sequence: leafcell = Sc_find_leaf_cell(name);
327
328 Name Type Description
329 ---- ---- -----------
330 name *char String name of leaf cell.
331 leafcell *char Generic pointer to found cell,
332 NULL if not found.
333 ------------------------------------------------------------------------
334 */
335
Sc_find_leaf_cell(CHAR * name)336 CHAR *Sc_find_leaf_cell(CHAR *name)
337 {
338 NODEPROTO *np, *laynp;
339 REGISTER void *infstr;
340
341 np = getnodeproto(name);
342 if (np == NONODEPROTO)
343 {
344 infstr = initinfstr();
345 if (sc_celllibrary != NOLIBRARY)
346 {
347 formatinfstr(infstr, x_("%s:%s"), sc_celllibrary->libname, name);
348 } else
349 {
350 formatinfstr(infstr, x_("%s"), name);
351 }
352 np = getnodeproto(returninfstr(infstr));
353 if (np == NONODEPROTO) return((CHAR *)NULL);
354 }
355 laynp = layoutview(np);
356 if (laynp != NONODEPROTO) np = laynp;
357 if (np->primindex == 0) return((CHAR *)np);
358 return((CHAR *)NULL);
359 }
360
361 /***********************************************************************
362 Module: Sc_leaf_cell_name
363 ------------------------------------------------------------------------
364 Description:
365 Return a pointer to the name of a leaf cell.
366 ------------------------------------------------------------------------
367 Calling Sequence: leafcellname = Sc_leaf_cell_name(leafcell);
368
369 Name Type Description
370 ---- ---- -----------
371 leafcell *char Pointer to the leaf cell.
372 leafcellname *char String of leaf cell name.
373 ------------------------------------------------------------------------
374 */
375
Sc_leaf_cell_name(CHAR * leafcell)376 CHAR *Sc_leaf_cell_name(CHAR *leafcell)
377 {
378 NODEPROTO *np;
379
380 np = (NODEPROTO *)leafcell;
381 if (np->primindex != 0) return(np->protoname);
382 return(np->protoname);
383 }
384
385 /***********************************************************************
386 Module: Sc_first_leaf_cell
387 ------------------------------------------------------------------------
388 Description:
389 Return a pointer to the first leaf cell in the current library.
390 Return NULL if error, eg. no library, no leaf cells, etc.
391 ------------------------------------------------------------------------
392 Calling Sequence: leafcell = Sc_first_leaf_cell();
393
394 Name Type Description
395 ---- ---- -----------
396 leafcell *char Pointer to the first leaf cell, NULL if
397 no leaf cell found.
398 ------------------------------------------------------------------------
399 */
400
Sc_first_leaf_cell(void)401 CHAR *Sc_first_leaf_cell(void)
402 {
403 if (el_curlib == NOLIBRARY) return((CHAR *)NULL);
404 if (el_curlib->firstnodeproto == NONODEPROTO) return((CHAR *)NULL);
405 return((CHAR *)el_curlib->firstnodeproto);
406 }
407
408 /***********************************************************************
409 Module: Sc_next_leaf_cell
410 ------------------------------------------------------------------------
411 Description:
412 Return a pointer to the next leaf cell in the current library.
413 Return NULL when end of list is reached.
414 ------------------------------------------------------------------------
415 Calling Sequence: nextleafcell = Sc_next_leaf_cell(leafcell);
416
417 Name Type Description
418 ---- ---- -----------
419 leafcell *char Pointer to the current leaf cell.
420 nextleafcell *char Returned pointer to next leaf cell.
421 ------------------------------------------------------------------------
422 */
423
Sc_next_leaf_cell(CHAR * leafcell)424 CHAR *Sc_next_leaf_cell(CHAR *leafcell)
425 {
426 if (((NODEPROTO *)leafcell)->nextnodeproto == NONODEPROTO)
427 return((CHAR *)NULL);
428 return((CHAR *)(((NODEPROTO *)leafcell)->nextnodeproto));
429 }
430
431 /***********************************************************************
432 Module: Sc_leaf_cell_bits
433 ------------------------------------------------------------------------
434 Description:
435 Return the value of the bits field of the leaf cell for the
436 Silicon Compiler.
437 ------------------------------------------------------------------------
438 Calling Sequence: bits = Sc_leaf_cell_bits(leafcell);
439
440 Name Type Description
441 ---- ---- -----------
442 leafcell *char Pointer to the leaf cell.
443 bits int Value of the SC bit field.
444 ------------------------------------------------------------------------
445 */
446
Sc_leaf_cell_bits(CHAR * leafcell)447 int Sc_leaf_cell_bits(CHAR *leafcell)
448 {
449 VARIABLE *var;
450
451 /* check if variable exits */
452 if ((var = getvalkey((INTBIG)leafcell, VNODEPROTO, VINTEGER, sc_bitskey))
453 == NOVARIABLE)
454 {
455 if (setvalkey((INTBIG)leafcell, VNODEPROTO, sc_bitskey, 0, VINTEGER) ==
456 NOVARIABLE) ttyputmsg(_("ERROR creating SCBITS variable."));
457 return(0);
458 }
459 return(var->addr);
460 }
461
462 /***********************************************************************
463 Module: Sc_leaf_cell_bits_address
464 ------------------------------------------------------------------------
465 Description:
466 Return the address of the bits field of the leaf cell for the
467 Silicon Compiler.
468 ------------------------------------------------------------------------
469 Calling Sequence: bits_addr = Sc_leaf_cell_bits_address(leafcell);
470
471 Name Type Description
472 ---- ---- -----------
473 leafcell *char Pointer to the leaf cell.
474 bits_addr *int Address of the SC bits field.
475 ------------------------------------------------------------------------
476 */
477
Sc_leaf_cell_bits_address(CHAR * leafcell)478 int *Sc_leaf_cell_bits_address(CHAR *leafcell)
479 {
480 VARIABLE *var;
481 static int retval;
482
483 /* check if variable exits */
484 if ((var = getvalkey((INTBIG)leafcell, VNODEPROTO, VINTEGER, sc_bitskey))
485 == NOVARIABLE)
486 {
487 if (setvalkey((INTBIG)leafcell, VNODEPROTO, sc_bitskey, 0, VINTEGER) ==
488 NOVARIABLE) ttyputmsg(_("ERROR creating SCBITS variable."));
489 if ((var = getvalkey((INTBIG)leafcell, VNODEPROTO, VINTEGER,
490 sc_bitskey)) == NOVARIABLE)
491 {
492 ttyputmsg(_("ERROR creating SCBITS variable."));
493 return((int *)NULL);
494 }
495 }
496 retval = var->addr;
497 return(&retval);
498 }
499
500 /***********************************************************************
501 Module: Sc_leaf_cell_xsize
502 ------------------------------------------------------------------------
503 Description:
504 Return the size in the x direction for the indicated leaf cell.
505 ------------------------------------------------------------------------
506 Calling Sequence: xsize = Sc_leaf_cell_xsize(leafcell);
507
508 Name Type Description
509 ---- ---- -----------
510 leafcell *char Pointer to the leaf cell.
511 xsize int Returned size in x direction.
512 ------------------------------------------------------------------------
513 */
514
Sc_leaf_cell_xsize(CHAR * leafcell)515 int Sc_leaf_cell_xsize(CHAR *leafcell)
516 {
517 return(((NODEPROTO *)leafcell)->highx - ((NODEPROTO *)leafcell)->lowx);
518 }
519
520 /***********************************************************************
521 Module: Sc_leaf_cell_ysize
522 ------------------------------------------------------------------------
523 Description:
524 Return the size in the y direction for the indicated leaf cell.
525 ------------------------------------------------------------------------
526 Calling Sequence: xsize = Sc_leaf_cell_ysize(leafcell);
527
528 Name Type Description
529 ---- ---- -----------
530 leafcell *char Pointer to the leaf cell.
531 xsize int Returned size in y direction.
532 ------------------------------------------------------------------------
533 */
534
Sc_leaf_cell_ysize(CHAR * leafcell)535 int Sc_leaf_cell_ysize(CHAR *leafcell)
536 {
537 return(((NODEPROTO *)leafcell)->highy - ((NODEPROTO *)leafcell)->lowy);
538 }
539
540 /***********************************************************************
541 Module: Sc_leaf_cell_sim_info
542 ------------------------------------------------------------------------
543 Description:
544 Return an array of pointers to strings for the leaf cell's
545 simulation information. Return NULL on error. Note that the
546 array should be terminated by a NULL.
547 ------------------------------------------------------------------------
548 Calling Sequence: simlist = Sc_leaf_cell_sim_info(leafcell);
549
550 Name Type Description
551 ---- ---- -----------
552 leafcell *char Pointer to the leaf cell.
553 simlist **char Array of pointers to simulation info,
554 NULL on error.
555 ------------------------------------------------------------------------
556 */
557
Sc_leaf_cell_sim_info(CHAR * leafcell)558 CHAR **Sc_leaf_cell_sim_info(CHAR *leafcell)
559 {
560 VARIABLE *simvar;
561 CHAR **simlist, **simlist2;
562 int i, numsim, use_key;
563
564 if (sc_sim_format == SC_ALS_FORMAT)
565 use_key = sc_simkey;
566 else if (sc_sim_format == SC_SILOS_FORMAT)
567 use_key = sc_silkey;
568 if ((simvar = getvalkey((INTBIG)leafcell, VNODEPROTO, VSTRING | VISARRAY,
569 use_key)) == NOVARIABLE) return((CHAR **)NULL);
570 simlist2 = (CHAR **)simvar->addr;
571
572 /* count the number of simulation lines */
573 numsim = 0;
574 for (i = 0; simlist2[i] != NOSTRING; i++) numsim++;
575
576 /* create array of pointers */
577 if ((simlist = (CHAR **)emalloc(sizeof(CHAR *)*(numsim+1),sc_tool->cluster))
578 == 0) return((CHAR **)NULL);
579 for (i = 0; i < numsim; i++) simlist[i] = simlist2[i];
580 simlist[numsim] = NULL;
581 return(simlist);
582 }
583
584 /***********************************************************************
585 Module: Sc_leaf_cell_set_sim
586 ------------------------------------------------------------------------
587 Description:
588 Set the passed simulation information to the indicated leaf cell.
589 ------------------------------------------------------------------------
590 Calling Sequence: err = Sc_leaf_cell_set_sim(simline, leafcell);
591
592 Name Type Description
593 ---- ---- -----------
594 simline *SCSIM Lines of simulation information.
595 leafcell *char Pointer to the leaf cell.
596 err int Returned error code, 0 = no error.
597 ------------------------------------------------------------------------
598 */
599
Sc_leaf_cell_set_sim(SCSIM * simline,CHAR * leafcell)600 int Sc_leaf_cell_set_sim(SCSIM *simline, CHAR *leafcell)
601 {
602 CHAR **simlist;
603 SCSIM *nextsim;
604 int i, numsim, use_key;
605
606 if (sc_sim_format == SC_ALS_FORMAT)
607 use_key = sc_simkey;
608 else if (sc_sim_format == SC_SILOS_FORMAT)
609 use_key = sc_silkey;
610 /* count the number of simulation lines */
611 numsim = 0;
612 for (nextsim = simline; nextsim; nextsim = nextsim->next) numsim++;
613
614 /* create array of pointers */
615 if ((simlist = (CHAR **)emalloc(sizeof(CHAR *)*(numsim+1),sc_tool->cluster)) == 0)
616 return(Sc_seterrmsg(SC_NOMEMORY));
617 for (i = 0; i < numsim; i++)
618 {
619 simlist[i] = simline->model;
620 simline = simline->next;
621 }
622 simlist[numsim] = NOSTRING;
623
624 /* set variable */
625 if (setvalkey((INTBIG)leafcell, VNODEPROTO, use_key, (INTBIG)simlist,
626 VSTRING | VISARRAY) == NOVARIABLE) return(Sc_seterrmsg(SC_SIMXSETVAL));
627 return(0);
628 }
629
630 /***********************************************************************
631 Module: Sc_leaf_cell_get_nums
632 ------------------------------------------------------------------------
633 Description:
634 Fill in the cell_nums structure for the indicated leaf cell.
635 ------------------------------------------------------------------------
636 Calling Sequence: Sc_leaf_cell_get_nums(leafcell, nums);
637
638 Name Type Description
639 ---- ---- -----------
640 leafcell *char Pointer to the leaf cell.
641 nums *SCCELLNUMS Address of structure to fill.
642 ------------------------------------------------------------------------
643 */
644
Sc_leaf_cell_get_nums(CHAR * leafcell,SCCELLNUMS * nums)645 void Sc_leaf_cell_get_nums(CHAR *leafcell, SCCELLNUMS *nums)
646 {
647 VARIABLE *var;
648 int i, j, *iarray, *jarray;
649
650 i = sizeof(SCCELLNUMS) / sizeof(int);
651
652 /* check if variable exits */
653 var = getvalkey((INTBIG)leafcell, VNODEPROTO, VINTEGER|VISARRAY, sc_numskey);
654 if (var == NOVARIABLE)
655 {
656 iarray = (int *)nums;
657 for (j = 0; j < i; j++) iarray[j] = 0;
658 return;
659 }
660
661 iarray = (int *)nums;
662 jarray = (int *)var->addr;
663 for (j = 0; j < i; j++) iarray[j] = jarray[j];
664 }
665
666 /***********************************************************************
667 Module: Sc_leaf_cell_set_nums
668 ------------------------------------------------------------------------
669 Description:
670 Set the cell_nums variable for the indicated leaf cell.
671 ------------------------------------------------------------------------
672 Calling Sequence: err = Sc_leaf_cell_set_nums(leafcell, nums);
673
674 Name Type Description
675 ---- ---- -----------
676 leafcell *char Pointer to the leaf cell.
677 nums *SCCELLNUMS Pointer to cell nums structure.
678 err int Returned error code, 0 = no error.
679 ------------------------------------------------------------------------
680 */
681
Sc_leaf_cell_set_nums(CHAR * leafcell,SCCELLNUMS * nums)682 int Sc_leaf_cell_set_nums(CHAR *leafcell, SCCELLNUMS *nums)
683 {
684 VARIABLE *var;
685 int i, j, *iarray;
686 INTBIG *jarray;
687
688 i = sizeof(SCCELLNUMS) / sizeof(int);
689
690 /* check if variable exits */
691 var = getvalkey((INTBIG)leafcell, VNODEPROTO, VINTEGER|VISARRAY, sc_numskey);
692 if (var == NOVARIABLE)
693 {
694 if ((jarray = emalloc((i + 1) * sizeof(INTBIG), sc_tool->cluster)) == 0)
695 return(Sc_seterrmsg(SC_NOMEMORY));
696 iarray = (int *)nums;
697 for (j = 0; j < i; j++) jarray[j] = iarray[j];
698 jarray[j] = -1;
699 if (setvalkey((INTBIG)leafcell, VNODEPROTO, sc_numskey, (INTBIG)jarray,
700 VINTEGER | VISARRAY) == NOVARIABLE)
701 return(Sc_seterrmsg(SC_NOSET_CELL_NUMS));
702 return(SC_NOERROR);
703 }
704 iarray = (int *)nums;
705 jarray = (INTBIG *)var->addr;
706 for (j = 0; j < i; j++) jarray[j] = iarray[j];
707 return(SC_NOERROR);
708 }
709
710 /***********************************************************************
711 Module: Sc_find_leaf_port
712 ------------------------------------------------------------------------
713 Description:
714 Return a pointer to the named port on the cell. If no port found,
715 return NULL.
716 ------------------------------------------------------------------------
717 Calling Sequence: leafport = Sc_find_leaf_port(leafcell, portname);
718
719 Name Type Description
720 ---- ---- -----------
721 leafcell *char Pointer to leaf cell.
722 portname *char String name of port.
723 leafport *char Generic pointer to first port,
724 NULL if not found.
725 ------------------------------------------------------------------------
726 */
727
Sc_find_leaf_port(CHAR * leafcell,CHAR * portname)728 CHAR *Sc_find_leaf_port(CHAR *leafcell, CHAR *portname)
729 {
730 PORTPROTO *pp;
731
732 for (pp = ((NODEPROTO *)leafcell)->firstportproto; pp != NOPORTPROTO;
733 pp = pp->nextportproto)
734 {
735 if (namesame(pp->protoname, portname) == 0)
736 return((CHAR *)pp);
737 }
738 return((CHAR *)NULL);
739 }
740
741 /***********************************************************************
742 Module: Sc_leaf_port_name
743 ------------------------------------------------------------------------
744 Description:
745 Return a pointer to the name of a leaf port.
746 ------------------------------------------------------------------------
747 Calling Sequence: portname = Sc_leaf_port_name(leafport);
748
749 Name Type Description
750 ---- ---- -----------
751 leafport *char Pointer to port.
752 portname *char String of port name.
753 ------------------------------------------------------------------------
754 */
755
Sc_leaf_port_name(CHAR * leafport)756 CHAR *Sc_leaf_port_name(CHAR *leafport)
757 {
758 return(((PORTPROTO *)leafport)->protoname);
759 }
760
761 /***********************************************************************
762 Module: Sc_first_leaf_port
763 ------------------------------------------------------------------------
764 Description:
765 Return a pointer to the first port of the cell. If no ports,
766 return NULL.
767 ------------------------------------------------------------------------
768 Calling Sequence: leafport = Sc_first_leaf_port(leafcell);
769
770 Name Type Description
771 ---- ---- -----------
772 leafcell *char Pointer to leaf cell.
773 leafport *char Generic pointer to first port,
774 NULL if not found.
775 ------------------------------------------------------------------------
776 */
777
Sc_first_leaf_port(CHAR * leafcell)778 CHAR *Sc_first_leaf_port(CHAR *leafcell)
779 {
780 PORTPROTO *pp;
781
782 pp = ((NODEPROTO *)leafcell)->firstportproto;
783 if (pp == NOPORTPROTO) return((CHAR *)NULL);
784 return((CHAR *)pp);
785 }
786
787 /***********************************************************************
788 Module: Sc_next_leaf_port
789 ------------------------------------------------------------------------
790 Description:
791 Return a pointer to the next port of the cell. If no ports left,
792 return NULL.
793 ------------------------------------------------------------------------
794 Calling Sequence: nextport = Sc_next_leaf_port(curport);
795
796 Name Type Description
797 ---- ---- -----------
798 curport *char Pointer to current port.
799 nextport *char Generic pointer to next port,
800 NULL if not found.
801 ------------------------------------------------------------------------
802 */
803
Sc_next_leaf_port(CHAR * curport)804 CHAR *Sc_next_leaf_port(CHAR *curport)
805 {
806 PORTPROTO *pp;
807
808 pp = ((PORTPROTO *)curport)->nextportproto;
809 if (pp == NOPORTPROTO) return((CHAR *)NULL);
810 return((CHAR *)pp);
811 }
812
813 /***********************************************************************
814 Module: Sc_leaf_port_bits
815 ------------------------------------------------------------------------
816 Description:
817 Return the bits field of a leaf port.
818 ------------------------------------------------------------------------
819 Calling Sequence: bits = Sc_leaf_port_bits(leafport);
820
821 Name Type Description
822 ---- ---- -----------
823 leafport *char Pointer to port.
824 bits int Value of the bits field.
825 ------------------------------------------------------------------------
826 */
827
Sc_leaf_port_bits(CHAR * leafport)828 int Sc_leaf_port_bits(CHAR *leafport)
829 {
830 VARIABLE *var;
831
832 /* check if variable exits */
833 var = getvalkey((INTBIG)leafport, VPORTPROTO, VINTEGER, sc_bitskey);
834 if (var == NOVARIABLE)
835 {
836 if (setvalkey((INTBIG)leafport, VPORTPROTO, sc_bitskey, 0, VINTEGER) ==
837 NOVARIABLE) ttyputmsg(_("ERROR creating SCBITS variable."));
838 return(0);
839 }
840 return(var->addr);
841 }
842
843 /***********************************************************************
844 Module: Sc_leaf_port_bits_address
845 ------------------------------------------------------------------------
846 Description:
847 Return the address of the bits field of a leaf port.
848 ------------------------------------------------------------------------
849 Calling Sequence: bits_a = Sc_leaf_port_bits_address(leafport);
850
851 Name Type Description
852 ---- ---- -----------
853 leafport *char Pointer to port.
854 bits_a *int Address of the bits field.
855 ------------------------------------------------------------------------
856 */
857
Sc_leaf_port_bits_address(CHAR * leafport)858 int *Sc_leaf_port_bits_address(CHAR *leafport)
859 {
860 VARIABLE *var;
861 static int retval;
862
863 /* check if variable exits */
864 var = getvalkey((INTBIG)leafport, VPORTPROTO, VINTEGER, sc_bitskey);
865 if (var == NOVARIABLE)
866 {
867 if (setvalkey((INTBIG)leafport, VPORTPROTO, sc_bitskey, 0, VINTEGER) ==
868 NOVARIABLE) ttyputmsg(_("ERROR creating SCBITS variable."));
869 if ((var = getvalkey((INTBIG)leafport, VPORTPROTO, VINTEGER, sc_bitskey))
870 == NOVARIABLE)
871 {
872 ttyputmsg(_("ERROR creating SCBITS variable."));
873 return((int *)NULL);
874 }
875 }
876 retval = var->addr;
877 return(&retval);
878 }
879
880 /***********************************************************************
881 Module: Sc_leaf_port_type
882 ------------------------------------------------------------------------
883 Description:
884 Return the type of the leaf port.
885 ------------------------------------------------------------------------
886 Calling Sequence: type = Sc_leaf_port_type(leafport);
887
888 Name Type Description
889 ---- ---- -----------
890 leafport *char Pointer to leaf port.
891 type int Returned type.
892 ------------------------------------------------------------------------
893 */
894
Sc_leaf_port_type(CHAR * leafport)895 int Sc_leaf_port_type(CHAR *leafport)
896 {
897 if (portispower((PORTPROTO *)leafport)) return(SCPWRPORT);
898 if (portisground((PORTPROTO *)leafport)) return(SCGNDPORT);
899
900 switch (((PORTPROTO *)leafport)->userbits & STATEBITS)
901 {
902 case BIDIRPORT: return(SCBIDIRPORT);
903 case OUTPORT: return(SCOUTPORT);
904 case INPORT: return(SCINPORT);
905 }
906 return(SCUNPORT);
907 }
908
909 /***********************************************************************
910 Module: Sc_set_leaf_port_type
911 ------------------------------------------------------------------------
912 Description:
913 Set the type of the leaf port.
914 ------------------------------------------------------------------------
915 Calling Sequence: Sc_set_leaf_port_type(leafport, type);
916
917 Name Type Description
918 ---- ---- -----------
919 leafport *PORTPROTO Pointer to leaf port.
920 type int Type to set (eg. input, output, etc.).
921 ------------------------------------------------------------------------
922 */
923
Sc_set_leaf_port_type(PORTPROTO * leafport,int type)924 void Sc_set_leaf_port_type(PORTPROTO *leafport, int type)
925 {
926 leafport->userbits &= ~STATEBITS;
927 switch (type)
928 {
929 case SCGNDPORT:
930 leafport->userbits |= GNDPORT;
931 break;
932 case SCPWRPORT:
933 leafport->userbits |= PWRPORT;
934 break;
935 case SCBIDIRPORT:
936 leafport->userbits |= BIDIRPORT;
937 break;
938 case SCOUTPORT:
939 leafport->userbits |= OUTPORT;
940 break;
941 case SCINPORT:
942 leafport->userbits |= INPORT;
943 break;
944 default:
945 leafport->userbits |= GNDPORT;
946 break;
947 }
948 return;
949 }
950
951 /***********************************************************************
952 Module: Sc_leaf_port_direction
953 ------------------------------------------------------------------------
954 Description:
955 Return the directions that a port can be attached to (i.e. up,
956 down, left, right).
957 ------------------------------------------------------------------------
958 Calling Sequence: direct = Sc_leaf_port_direction(port);
959
960 Name Type Description
961 ---- ---- -----------
962 port *char Pointer to port.
963 direct int Returned direction for attaching.
964 ------------------------------------------------------------------------
965 */
966
Sc_leaf_port_direction(CHAR * port)967 int Sc_leaf_port_direction(CHAR *port)
968 {
969 int direct, bits;
970
971 direct = 0;
972 bits = Sc_leaf_port_bits(port);
973 if (bits & SCPORTDIRMASK) direct = bits & SCPORTDIRMASK;
974 else
975 {
976 /* if no direction specified, assume both up and down */
977 direct |= SCPORTDIRUP;
978 direct |= SCPORTDIRDOWN;
979 }
980
981 return(direct);
982 }
983
984 /***********************************************************************
985 Module: Sc_leaf_port_xpos
986 ------------------------------------------------------------------------
987 Description:
988 Return the xpos of the indicated leaf port from the left side of
989 it's parent leaf cell.
990 ------------------------------------------------------------------------
991 Calling Sequence: xpos = Sc_leaf_port_xpos(port);
992
993 Name Type Description
994 ---- ---- -----------
995 port *char Pointer to leaf port.
996 xpos int Returned position from left side of cell.
997 ------------------------------------------------------------------------
998 */
999
Sc_leaf_port_xpos(CHAR * port)1000 int Sc_leaf_port_xpos(CHAR *port)
1001 {
1002 INTBIG x, y;
1003
1004 if (port != 0)
1005 {
1006 portposition(((PORTPROTO *)port)->subnodeinst,
1007 ((PORTPROTO *)port)->subportproto, &x, &y);
1008 return(x - ((PORTPROTO *)port)->parent->lowx);
1009 }
1010 return(0);
1011 }
1012
1013 /***********************************************************************
1014 Module: Sc_leaf_port_ypos
1015 ------------------------------------------------------------------------
1016 Description:
1017 Return the ypos of the indicated leaf port from the bottom of
1018 it's parent leaf cell.
1019 ------------------------------------------------------------------------
1020 Calling Sequence: ypos = Sc_leaf_port_ypos(port);
1021
1022 Name Type Description
1023 ---- ---- -----------
1024 port *char Pointer to leaf port.
1025 ypos int Returned position from bottom of cell.
1026 ------------------------------------------------------------------------
1027 */
1028
Sc_leaf_port_ypos(CHAR * port)1029 int Sc_leaf_port_ypos(CHAR *port)
1030 {
1031 INTBIG x, y;
1032
1033 if (port != 0)
1034 {
1035 portposition(((PORTPROTO *)port)->subnodeinst,
1036 ((PORTPROTO *)port)->subportproto, &x, &y);
1037 return(y - ((PORTPROTO *)port)->parent->lowy);
1038 }
1039 return(0);
1040 }
1041
1042 /***********************************************************************
1043 Module: Sc_leaf_port_set_first
1044 ------------------------------------------------------------------------
1045 Description:
1046 Set the first port of the indicated leaf cell to the indicated
1047 leaf port.
1048 ------------------------------------------------------------------------
1049 Calling Sequence: Sc_leaf_port_set_first(leafcell, leafport);
1050
1051 Name Type Description
1052 ---- ---- -----------
1053 leafcell *char Pointer to leaf cell.
1054 leafport *char Pointer to leaf port.
1055 ------------------------------------------------------------------------
1056 */
1057
Sc_leaf_port_set_first(CHAR * leafcell,CHAR * leafport)1058 void Sc_leaf_port_set_first(CHAR *leafcell, CHAR *leafport)
1059 {
1060 ((NODEPROTO *)leafcell)->firstportproto = (PORTPROTO *)leafport;
1061 }
1062
1063 /***********************************************************************
1064 Module: Sc_leaf_port_set_next
1065 ------------------------------------------------------------------------
1066 Description:
1067 Set the next port of the indicated leaf port to the indicated
1068 leaf port. If the second leaf port is NULL, set to NOPORTPROTO.
1069 ------------------------------------------------------------------------
1070 Calling Sequence: Sc_leaf_port_set_next(leafport1, leafport2);
1071
1072 Name Type Description
1073 ---- ---- -----------
1074 leafport1 *char Pointer to first leaf port.
1075 leafport2 *char Pointer to second leaf port.
1076 ------------------------------------------------------------------------
1077 */
1078
Sc_leaf_port_set_next(CHAR * leafport1,CHAR * leafport2)1079 void Sc_leaf_port_set_next(CHAR *leafport1, CHAR *leafport2)
1080 {
1081 if (leafport2 != 0)
1082 {
1083 ((PORTPROTO *)leafport1)->nextportproto = (PORTPROTO *)leafport2;
1084 } else
1085 {
1086 ((PORTPROTO *)leafport1)->nextportproto = NOPORTPROTO;
1087 }
1088 }
1089
1090 /***********************************************************************
1091 Module: Sc_library_read
1092 ------------------------------------------------------------------------
1093 Description:
1094 Read the specified library. Set error codes.
1095 ------------------------------------------------------------------------
1096 Calling Sequence: err = Sc_library_read(libname);
1097
1098 Name Type Description
1099 ---- ---- -----------
1100 libname *char String giving name of library.
1101 err int Returned error code, 0 = no error.
1102 ------------------------------------------------------------------------
1103 */
1104
Sc_library_read(CHAR * libname)1105 int Sc_library_read(CHAR *libname)
1106 {
1107 LIBRARY *lib;
1108
1109 /* check to see if library already exists */
1110 for (lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1111 {
1112 if (namesame(libname, lib->libname) == 0)
1113 break;
1114 }
1115 if (lib == NOLIBRARY)
1116 {
1117 if ((lib = newlibrary(libname, libname)) == NOLIBRARY)
1118 return(Sc_seterrmsg(SC_LIBNOMAKE, libname));
1119 } else
1120 {
1121 eraselibrary(lib);
1122 if (reallocstring(&lib->libfile, libname, lib->cluster))
1123 return(Sc_seterrmsg(SC_NOMEMORY));
1124 }
1125 if (asktool(io_tool, x_("read"), (INTBIG)lib, x_("binary")) != 0)
1126 {
1127 eraselibrary(lib);
1128 return(Sc_seterrmsg(SC_LIBNOREAD, libname));
1129 }
1130 selectlibrary(lib, TRUE);
1131 return(0);
1132 }
1133
1134 /***********************************************************************
1135 Module: Sc_library_use
1136 ------------------------------------------------------------------------
1137 Description:
1138 Use the specified library as a cell library. Set error codes.
1139 ------------------------------------------------------------------------
1140 Calling Sequence: err = Sc_library_use(libname);
1141
1142 Name Type Description
1143 ---- ---- -----------
1144 libname *char String giving name of library.
1145 err int Returned error code, 0 = no error.
1146 ------------------------------------------------------------------------
1147 */
1148
Sc_library_use(CHAR * libname)1149 int Sc_library_use(CHAR *libname)
1150 {
1151 LIBRARY *lib;
1152
1153 /* check to see if library already exists */
1154 for (lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1155 if (namesame(libname, lib->libname) == 0) break;
1156 if (lib == NOLIBRARY)
1157 {
1158 return(Sc_seterrmsg(SC_NOLIBRARY, libname));
1159 }
1160 sc_celllibrary = lib;
1161 return(0);
1162 }
1163
1164 /***********************************************************************
1165 Module: Sc_setup_for_maker
1166 ------------------------------------------------------------------------
1167 Description:
1168 Set up the future creation of the maker by setting the appropriate
1169 prototypes.
1170 ------------------------------------------------------------------------
1171 Calling Sequence: err = Sc_setup_for_maker();
1172
1173 Name Type Description
1174 ---- ---- -----------
1175 err int Returned error code, 0 = no error.
1176 ------------------------------------------------------------------------
1177 */
1178
Sc_setup_for_maker(ARCPROTO * layer1,ARCPROTO * layer2)1179 int Sc_setup_for_maker(ARCPROTO *layer1, ARCPROTO *layer2)
1180 {
1181 REGISTER ARCPROTO *ap, *alternatearc, **arclist;
1182 REGISTER int fun, i;
1183 REGISTER TECHNOLOGY *tech;
1184 static POLYGON *poly = NOPOLYGON;
1185
1186 /* make sure there is a polygon */
1187 (void)needstaticpolygon(&poly, 4, sc_tool->cluster);
1188
1189 /* find the horizontal (layer 1) and vertical (layer 2) arcs */
1190 sc_layer1arc = sc_layer2arc = alternatearc = NOARCPROTO;
1191 for(ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
1192 {
1193 switch ((ap->userbits&AFUNCTION)>>AFUNCTIONSH)
1194 {
1195 case APMETAL1:
1196 sc_layer1arc = ap;
1197 break;
1198 case APMETAL2: case APMETAL3: case APMETAL4: case APMETAL5:
1199 case APMETAL6: case APMETAL7: case APMETAL8: case APMETAL9:
1200 case APMETAL10: case APMETAL11: case APMETAL12:
1201 sc_layer2arc = ap;
1202 break;
1203 case APPOLY1: case APPOLY2: case APPOLY3:
1204 alternatearc = ap;
1205 break;
1206 }
1207 }
1208 if (sc_layer1arc == NOARCPROTO) sc_layer1arc = alternatearc;
1209
1210 /* allow overrides */
1211 if (layer1 != NOARCPROTO) sc_layer1arc = layer1;
1212 if (layer2 != NOARCPROTO) sc_layer2arc = layer2;
1213 if (sc_layer1arc == NOARCPROTO) return(Sc_seterrmsg(SC_NO_LAYER1_ARC));
1214 if (sc_layer2arc == NOARCPROTO) return(Sc_seterrmsg(SC_NO_LAYER2_ARC));
1215
1216 /* use technology of the first arc */
1217 tech = sc_layer1arc->tech;
1218
1219 /* find the contact between the two layers */
1220 for(sc_viaproto = tech->firstnodeproto; sc_viaproto != NONODEPROTO;
1221 sc_viaproto = sc_viaproto->nextnodeproto)
1222 {
1223 fun = (sc_viaproto->userbits&NFUNCTION) >> NFUNCTIONSH;
1224 if (fun != NPCONTACT && fun != NPCONNECT) continue;
1225 arclist = sc_viaproto->firstportproto->connects;
1226 for(i=0; arclist[i] != NOARCPROTO; i++)
1227 if (arclist[i] == sc_layer1arc) break;
1228 if (arclist[i] == NOARCPROTO) continue;
1229 for(i=0; arclist[i] != NOARCPROTO; i++)
1230 if (arclist[i] == sc_layer2arc) break;
1231 if (arclist[i] != NOARCPROTO) break;
1232 }
1233 if (sc_viaproto == NONODEPROTO) return(Sc_seterrmsg(SC_NO_VIA));
1234
1235 /* find the pin nodes on the connecting layers */
1236 sc_layer1proto = getpinproto(sc_layer1arc);
1237 if (sc_layer1proto == NONODEPROTO) return(Sc_seterrmsg(SC_NO_LAYER1_NODE));
1238 sc_layer2proto = getpinproto(sc_layer2arc);
1239 if (sc_layer2proto == NONODEPROTO) return(Sc_seterrmsg(SC_NO_LAYER2_NODE));
1240
1241 /*
1242 * find the pure-layer node on the P-well layer
1243 * if the p-well size is zero don't look for the node
1244 * allows technologies without p-wells to be routed (i.e. GaAs)
1245 */
1246 if (ScGetParameter(SC_PARAM_MAKE_PWELL_SIZE) == 0) sc_pwellproto = NONODEPROTO; else
1247 {
1248 sc_pwellproto = getpurelayernode(tech, -1, LFWELL|LFPTYPE);
1249 if (sc_pwellproto == NONODEPROTO) return(Sc_seterrmsg(SC_NO_LAYER_PWELL));
1250 }
1251 if (ScGetParameter(SC_PARAM_MAKE_NWELL_SIZE) == 0) sc_nwellproto = NONODEPROTO; else
1252 {
1253 sc_nwellproto = getpurelayernode(tech, -1, LFWELL|LFNTYPE);
1254 if (sc_nwellproto == NONODEPROTO) return(Sc_seterrmsg(SC_NO_LAYER_PWELL));
1255 }
1256
1257 return(SC_NOERROR);
1258 }
1259
1260 /***********************************************************************
1261 Module: Sc_create_leaf_cell
1262 ------------------------------------------------------------------------
1263 Description:
1264 Create a new leaf cell of the indicated name in the VLSI Layout Tool
1265 Environment. Return NULL on error.
1266 ------------------------------------------------------------------------
1267 Calling Sequence: bcell = Sc_create_leaf_cell(name);
1268
1269 Name Type Description
1270 ---- ---- -----------
1271 name *char Name of new leaf cell.
1272 bcell *char Pointer to created leaf cell.
1273 ------------------------------------------------------------------------
1274 */
1275
Sc_create_leaf_cell(CHAR * name)1276 CHAR *Sc_create_leaf_cell(CHAR *name)
1277 {
1278 NODEPROTO *bcell;
1279 CHAR *view, layoutname[256];
1280
1281 /*
1282 * use layoutname because we don't know how
1283 * long "name" is
1284 */
1285 (void) estrcpy (layoutname, name);
1286
1287 if ((view = estrchr (layoutname, '{')) == NULL)
1288 (void) estrcat (layoutname, x_("{lay}")); else
1289 if (estrncmp (view, x_("{lay}"), 5) != 0)
1290 {
1291 view = '\0';
1292 (void) estrcat (layoutname, x_("{lay}"));
1293 }
1294
1295 bcell = us_newnodeproto(layoutname, el_curlib);
1296 if (bcell == NONODEPROTO) return((CHAR *)NULL);
1297 return((CHAR *)bcell);
1298 }
1299
1300 /***********************************************************************
1301 Module: Sc_create_leaf_instance
1302 ------------------------------------------------------------------------
1303 Description:
1304 Create a new leaf instance of the indicated type in the VLSI Layout
1305 Tool Environment. Return NULL on error.
1306 ------------------------------------------------------------------------
1307 Calling Sequence: binst = Sc_create_leaf_instance(name, type, minx, maxx,
1308 miny, maxy, transpose, rotation, parent);
1309
1310 Name Type Description
1311 ---- ---- -----------
1312 name *char Name of new leaf instance.
1313 type *char Pointer to leaf cell type.
1314 minx, maxx int Bounds in X.
1315 miny, maxy int Bounds in Y.
1316 transpose int Transposition flag (TRUE == transpose).
1317 rotation int Degrees of rotation.
1318 parent *char Cell in which to create instance.
1319 binst *char Pointer to created leaf instance.
1320 ------------------------------------------------------------------------
1321 */
1322
Sc_create_leaf_instance(CHAR * name,CHAR * type,int minx,int maxx,int miny,int maxy,int transpose,int rotation,CHAR * parent)1323 CHAR *Sc_create_leaf_instance(CHAR *name, CHAR *type, int minx, int maxx, int miny,
1324 int maxy, int transpose, int rotation, CHAR *parent)
1325 {
1326 NODEINST *binst;
1327 REGISTER VARIABLE *var;
1328
1329 binst = newnodeinst((NODEPROTO *)type, minx, maxx, miny, maxy, transpose,
1330 rotation, (NODEPROTO *)parent);
1331 if (binst == NONODEINST) return((CHAR *)NULL);
1332
1333 var = setvalkey((INTBIG)binst, VNODEINST, el_node_name_key, (INTBIG)name, VSTRING|VDISPLAY);
1334 if (var == NOVARIABLE)
1335 {
1336 ttyputmsg(_("ERROR creating name of instance '%s'."), name);
1337 } else
1338 {
1339 defaulttextsize(3, var->textdescript);
1340 }
1341 return((CHAR *)binst);
1342 }
1343
1344 /***********************************************************************
1345 Module: Sc_create_layer1_node
1346 ------------------------------------------------------------------------
1347 Description:
1348 Create a node in layer1 in the indicated cell at the given position.
1349 ------------------------------------------------------------------------
1350 Calling Sequence: binst = Sc_create_layer1_node(xpos, ypos, xsize,
1351 ysize, bcell);
1352
1353 Name Type Description
1354 ---- ---- -----------
1355 xpos int Center X position.
1356 ypos int Center Y position.
1357 xsize int Size in X.
1358 ysize int Size in Y.
1359 bcell *char Cell in which to create feed.
1360 binst *char Returned pointer to created instance.
1361 ------------------------------------------------------------------------
1362 */
1363
Sc_create_layer1_node(int xpos,int ypos,int xsize,int ysize,CHAR * bcell)1364 CHAR *Sc_create_layer1_node(int xpos, int ypos, int xsize, int ysize, CHAR *bcell)
1365 {
1366 NODEINST *binst;
1367 int lowx, highx, lowy, highy;
1368
1369 lowx = xpos - (xsize >> 1);
1370 highx = lowx + xsize;
1371 lowy = ypos - (ysize >> 1);
1372 highy = lowy + ysize;
1373 binst = newnodeinst(sc_layer1proto, lowx, highx, lowy, highy, 0, 0,
1374 (NODEPROTO *)bcell);
1375 if (binst == NONODEINST) return((CHAR *)NULL);
1376 return((CHAR *)binst);
1377 }
1378
1379 /***********************************************************************
1380 Module: Sc_create_layer2_node
1381 ------------------------------------------------------------------------
1382 Description:
1383 Create a layer2 node in the indicated cell at the given position.
1384 ------------------------------------------------------------------------
1385 Calling Sequence: binst = Sc_create_layer2_node(xpos, ypos, xsize,
1386 ysize, bcell);
1387
1388 Name Type Description
1389 ---- ---- -----------
1390 xpos int Center X position.
1391 ypos int Center Y position.
1392 xsize int Width in X direction.
1393 ysize int Size in Y direction.
1394 bcell *char Cell in which to create feed.
1395 binst *char Returned pointer to created instance.
1396 ------------------------------------------------------------------------
1397 */
1398
Sc_create_layer2_node(int xpos,int ypos,int xsize,int ysize,CHAR * bcell)1399 CHAR *Sc_create_layer2_node(int xpos, int ypos, int xsize, int ysize, CHAR *bcell)
1400 {
1401 NODEINST *binst;
1402 int lowx, highx, lowy, highy;
1403
1404 lowx = xpos - (xsize >> 1);
1405 highx = lowx + xsize;
1406 lowy = ypos - (ysize >> 1);
1407 highy = lowy + ysize;
1408 binst = newnodeinst(sc_layer2proto, lowx, highx, lowy, highy, 0, 0,
1409 (NODEPROTO *)bcell);
1410 if (binst == NONODEINST) return((CHAR *)NULL);
1411 return((CHAR *)binst);
1412 }
1413
1414 /***********************************************************************
1415 Module: Sc_create_via
1416 ------------------------------------------------------------------------
1417 Description:
1418 Create a via in the indicated cell at the given position.
1419 ------------------------------------------------------------------------
1420 Calling Sequence: binst = Sc_create_via(xpos, ypos, bcell);
1421
1422 Name Type Description
1423 ---- ---- -----------
1424 xpos int Center X position.
1425 ypos int Center Y position.
1426 bcell *char Cell in which to create feed.
1427 binst *char Returned pointer to created instance.
1428 ------------------------------------------------------------------------
1429 */
1430
Sc_create_via(int xpos,int ypos,CHAR * bcell)1431 CHAR *Sc_create_via(int xpos, int ypos, CHAR *bcell)
1432 {
1433 NODEINST *binst;
1434 int lowx, highx, lowy, highy;
1435 INTBIG pxs, pys;
1436
1437 defaultnodesize(sc_viaproto, &pxs, &pys);
1438 lowx = xpos - pxs / 2;
1439 highx = lowx + pxs;
1440 lowy = ypos - pys / 2;
1441 highy = lowy + pys;
1442 binst = newnodeinst(sc_viaproto, lowx, highx, lowy, highy, 0, 0,
1443 (NODEPROTO *)bcell);
1444 if (binst == NONODEINST) return((CHAR *)NULL);
1445 return((CHAR *)binst);
1446 }
1447
1448 /***********************************************************************
1449 Module: Sc_create_pwell
1450 ------------------------------------------------------------------------
1451 Description:
1452 Create a pwell in the indicated cell at the given position.
1453 ------------------------------------------------------------------------
1454 Calling Sequence: binst = Sc_create_pwell(xpos, ypos, xsize, ysize, bcell);
1455
1456 Name Type Description
1457 ---- ---- -----------
1458 xpos int Center X position.
1459 ypos int Center Y position.
1460 xsize int Size in X.
1461 ysize int Size in Y.
1462 bcell *char Cell in which to create feed.
1463 binst *char Returned pointer to created instance.
1464 ------------------------------------------------------------------------
1465 */
1466
Sc_create_pwell(int xpos,int ypos,int xsize,int ysize,CHAR * bcell)1467 CHAR *Sc_create_pwell(int xpos, int ypos, int xsize, int ysize, CHAR *bcell)
1468 {
1469 NODEINST *binst;
1470 int lowx, highx, lowy, highy;
1471
1472 if (sc_pwellproto == NONODEPROTO) return((CHAR *)NULL);
1473
1474 lowx = xpos - (xsize >> 1);
1475 highx = lowx + xsize;
1476 lowy = ypos - (ysize >> 1);
1477 highy = lowy + ysize;
1478 binst = newnodeinst(sc_pwellproto, lowx, highx, lowy, highy, 0, 0,
1479 (NODEPROTO *)bcell);
1480 if (binst == NONODEINST) return((CHAR *)NULL);
1481 return((CHAR *)binst);
1482 }
1483
1484 /***********************************************************************
1485 Module: Sc_create_nwell
1486 ------------------------------------------------------------------------
1487 Description:
1488 Create a nwell in the indicated cell at the given position.
1489 Added 2/11/01 David_Harris@hmc.edu
1490 ------------------------------------------------------------------------
1491 Calling Sequence: binst = Sc_create_nwell(xpos, ypos, xsize, ysize, bcell);
1492
1493 Name Type Description
1494 ---- ---- -----------
1495 xpos int Center X position.
1496 ypos int Center Y position.
1497 xsize int Size in X.
1498 ysize int Size in Y.
1499 bcell *char Cell in which to create feed.
1500 binst *char Returned pointer to created instance.
1501 ------------------------------------------------------------------------
1502 */
1503
Sc_create_nwell(int xpos,int ypos,int xsize,int ysize,CHAR * bcell)1504 CHAR *Sc_create_nwell(int xpos, int ypos, int xsize, int ysize, CHAR *bcell)
1505 {
1506 NODEINST *binst;
1507 int lowx, highx, lowy, highy;
1508
1509 if (sc_nwellproto == NONODEPROTO) return((CHAR *)NULL);
1510
1511 lowx = xpos - (xsize >> 1);
1512 highx = lowx + xsize;
1513 lowy = ypos - (ysize >> 1);
1514 highy = lowy + ysize;
1515 binst = newnodeinst(sc_nwellproto, lowx, highx, lowy, highy, 0, 0,
1516 (NODEPROTO *)bcell);
1517 if (binst == NONODEINST) return((CHAR *)NULL);
1518 return((CHAR *)binst);
1519 }
1520
1521 /***********************************************************************
1522 Module: Sc_create_track_layer1
1523 ------------------------------------------------------------------------
1524 Description:
1525 Create a track between the two given ports on the first routing
1526 layer. Note that ports of primitive instances are passed as NULL
1527 and must be determined.
1528 ------------------------------------------------------------------------
1529 Calling Sequence: inst = Sc_create_track_layer1(instA, portA,
1530 instB, portB, width, bcell);
1531
1532 Name Type Description
1533 ---- ---- -----------
1534 instA *char Pointer to first instance.
1535 portA *char Pointer to first port.
1536 instB *char Pointer to second instance.
1537 portB *char Pointer to second port.
1538 width int Width of track.
1539 bcell *char Pointer to cell in which to create.
1540 inst *char Returned pointer to created track.
1541 ------------------------------------------------------------------------
1542 */
1543
Sc_create_track_layer1(CHAR * instA,CHAR * portA,CHAR * instB,CHAR * portB,int width,CHAR * bcell)1544 CHAR *Sc_create_track_layer1(CHAR *instA, CHAR *portA, CHAR *instB, CHAR *portB,
1545 int width, CHAR *bcell)
1546 {
1547 PORTPROTO *pa, *pb;
1548 NODEINST *na, *nb;
1549 ARCINST *inst;
1550 INTBIG xA, yA, xB, yB, i;
1551
1552 /* copy into internal structures */
1553 na = (NODEINST *)instA;
1554 nb = (NODEINST *)instB;
1555 if (portA != NULL) pa = (PORTPROTO *)portA; else
1556 pa = na->proto->firstportproto;
1557 if (portB != NULL) pb = (PORTPROTO *)portB; else
1558 pb = nb->proto->firstportproto;
1559
1560 /* find center positions */
1561 portposition(na, pa, &xA, &yA);
1562 portposition(nb, pb, &xB, &yB);
1563
1564 /* make sure the arc can connect */
1565 for(i=0; pa->connects[i] != NOARCPROTO; i++)
1566 if (pa->connects[i] == sc_layer1arc) break;
1567 if (pa->connects[i] == NOARCPROTO)
1568 {
1569 /* must place a via */
1570 Sc_create_connection(&na, &pa, xA, yA, sc_layer1arc);
1571 }
1572 for(i=0; pb->connects[i] != NOARCPROTO; i++)
1573 if (pb->connects[i] == sc_layer1arc) break;
1574 if (pb->connects[i] == NOARCPROTO)
1575 {
1576 /* must place a via */
1577 Sc_create_connection(&nb, &pb, xB, yB, sc_layer1arc);
1578 }
1579
1580 inst = newarcinst(sc_layer1arc, width, FIXANG, na, pa, xA, yA,
1581 nb, pb, xB, yB, (NODEPROTO *)bcell);
1582 if (inst == NOARCINST) return((CHAR *)NULL);
1583 return((CHAR *)inst);
1584 }
1585
1586 /***********************************************************************
1587 Module: Sc_create_track_layer2
1588 ------------------------------------------------------------------------
1589 Description:
1590 Create a track between the two given ports on the second routing
1591 layer. Note that ports of primitive instances are passed as NULL
1592 and must be determined.
1593 ------------------------------------------------------------------------
1594 Calling Sequence: inst = Sc_create_track_layer2(instA, portA,
1595 instB, portB, width, bcell);
1596
1597 Name Type Description
1598 ---- ---- -----------
1599 instA *char Pointer to first instance.
1600 portA *char Pointer to first port.
1601 instB *char Pointer to second instance.
1602 portB *char Pointer to second port.
1603 width int Width of track.
1604 bcell *char Pointer to cell in which to create.
1605 inst *char Returned pointer to created track.
1606 ------------------------------------------------------------------------
1607 */
1608
Sc_create_track_layer2(CHAR * instA,CHAR * portA,CHAR * instB,CHAR * portB,int width,CHAR * bcell)1609 CHAR *Sc_create_track_layer2(CHAR *instA, CHAR *portA, CHAR *instB, CHAR *portB,
1610 int width, CHAR *bcell)
1611 {
1612 PORTPROTO *pa, *pb;
1613 NODEINST *na, *nb;
1614 ARCINST *inst;
1615 INTBIG xA, yA, xB, yB, i;
1616
1617 /* copy into internal structures */
1618 na = (NODEINST *)instA;
1619 nb = (NODEINST *)instB;
1620 if (portA != NULL) pa = (PORTPROTO *)portA; else
1621 pa = na->proto->firstportproto;
1622 if (portB != NULL) pb = (PORTPROTO *)portB; else
1623 pb = nb->proto->firstportproto;
1624
1625 /* find center positions */
1626 portposition(na, pa, &xA, &yA);
1627 portposition(nb, pb, &xB, &yB);
1628
1629 /* make sure the arc can connect */
1630 for(i=0; pa->connects[i] != NOARCPROTO; i++)
1631 if (pa->connects[i] == sc_layer2arc) break;
1632 if (pa->connects[i] == NOARCPROTO)
1633 {
1634 /* must place a via */
1635 Sc_create_connection(&na, &pa, xA, yA, sc_layer2arc);
1636 }
1637 for(i=0; pb->connects[i] != NOARCPROTO; i++)
1638 if (pb->connects[i] == sc_layer2arc) break;
1639 if (pb->connects[i] == NOARCPROTO)
1640 {
1641 /* must place a via */
1642 Sc_create_connection(&nb, &pb, xB, yB, sc_layer2arc);
1643 }
1644
1645 inst = newarcinst(sc_layer2arc, width, FIXANG, na, pa, xA, yA,
1646 nb, pb, xB, yB, (NODEPROTO *)bcell);
1647 if (inst == NOARCINST) return((CHAR *)NULL);
1648 return((CHAR *)inst);
1649 }
1650
Sc_create_connection(NODEINST ** ni,PORTPROTO ** pp,INTBIG x,INTBIG y,ARCPROTO * arc)1651 void Sc_create_connection(NODEINST **ni, PORTPROTO **pp, INTBIG x, INTBIG y,
1652 ARCPROTO *arc)
1653 {
1654 REGISTER NODEPROTO *via;
1655 REGISTER NODEINST *vianode;
1656 REGISTER INTBIG fun, i, j, lx, hx, ly, hy, wid;
1657 INTBIG sx, sy;
1658 REGISTER ARCPROTO **arclist, **niarclist;
1659 REGISTER ARCINST *zeroarc;
1660
1661 niarclist = (*pp)->connects;
1662
1663 /* always use the standard via (David Harris) */
1664 via = sc_viaproto;
1665 if (via == NONODEPROTO) return;
1666 fun = (via->userbits&NFUNCTION) >> NFUNCTIONSH;
1667 if (fun != NPCONTACT && fun != NPCONNECT) return;
1668 arclist = via->firstportproto->connects;
1669
1670 /* make sure that this contact connects to the desired arc */
1671 for(i=0; arclist[i] != NOARCPROTO; i++)
1672 if (arclist[i] == arc) break;
1673 if (arclist[i] == NOARCPROTO) return;
1674
1675 /* make sure that this contact connects to the initial node */
1676 for(i=0; arclist[i] != NOARCPROTO; i++)
1677 {
1678 for(j=0; niarclist[j] != NOARCPROTO; j++)
1679 {
1680 if (arclist[i] == niarclist[j]) break;
1681 }
1682 if (niarclist[j] != NOARCPROTO) break;
1683 }
1684
1685 /* use this via to make the connection */
1686 defaultnodesize(via, &sx, &sy);
1687 lx = x - sx/2; hx = lx + sx;
1688 ly = y - sy/2; hy = ly + sy;
1689 vianode = newnodeinst(via, lx, hx, ly, hy, 0, 0, (*ni)->parent);
1690 if (vianode == NONODEINST) return;
1691 wid = defaultarcwidth(arclist[i]);
1692 zeroarc = newarcinst(arclist[i], wid, FIXED, *ni, *pp, x, y,
1693 vianode, via->firstportproto, x, y, (*ni)->parent);
1694 if (zeroarc == NOARCINST) return;
1695 *ni = vianode;
1696 *pp = via->firstportproto;
1697 }
1698
1699 /***********************************************************************
1700 Module: Sc_create_export_port
1701 ------------------------------------------------------------------------
1702 Description:
1703 Create an export at the given instance at the given port.
1704 Note that ports of primitive instances are passed as NULL and must
1705 be determined.
1706 ------------------------------------------------------------------------
1707 Calling Sequence: xport = Sc_create_export_port(inst, port, name,
1708 type, bcell);
1709
1710 Name Type Description
1711 ---- ---- -----------
1712 instA *char Pointer to instance.
1713 port *char Pointer to port.
1714 name *char Pointer to name.
1715 type int Type of port (eg. input, output, etc.)
1716 bcell *char Pointer to cell in which to create.
1717 xport *char Returned pointer to created port.
1718 ------------------------------------------------------------------------
1719 */
1720
Sc_create_export_port(CHAR * inst,CHAR * port,CHAR * name,int type,CHAR * bcell)1721 CHAR *Sc_create_export_port(CHAR *inst, CHAR *port, CHAR *name, int type, CHAR *bcell)
1722 {
1723 PORTPROTO *xport;
1724
1725 /* check if primative */
1726 if ((PORTPROTO *)port == NULL)
1727 port = (CHAR *)(((NODEINST *)inst)->proto->firstportproto);
1728
1729 xport = newportproto((NODEPROTO *)bcell, (NODEINST *)inst,
1730 (PORTPROTO *)port, name);
1731 if (xport == NOPORTPROTO) return((CHAR *)NULL);
1732 Sc_set_leaf_port_type(xport, type);
1733 return((CHAR *)xport);
1734 }
1735
1736 /*
1737 * routine to examine a schematic from the current cell
1738 */
Sc_schematic(void)1739 void Sc_schematic(void)
1740 {
1741 ttyputmsg(_("Sorry, cannot handle schematics yet"));
1742 }
1743
1744 /****************************** DIALOG ******************************/
1745
1746 /* Silicon Compiler Options */
1747 static DIALOGITEM sc_optionsdialogitems[] =
1748 {
1749 /* 1 */ {0, {500,268,524,326}, BUTTON, N_("OK")},
1750 /* 2 */ {0, {500,36,524,94}, BUTTON, N_("Cancel")},
1751 /* 3 */ {0, {8,204,24,384}, POPUP, x_("")},
1752 /* 4 */ {0, {32,204,48,276}, EDITTEXT, x_("")},
1753 /* 5 */ {0, {8,8,24,180}, MESSAGE, N_("Horizontal routing arc:")},
1754 /* 6 */ {0, {60,8,76,180}, MESSAGE, N_("Vertical routing arc:")},
1755 /* 7 */ {0, {32,8,48,174}, MESSAGE, N_("Horizontal wire width:")},
1756 /* 8 */ {0, {60,204,76,384}, POPUP, x_("")},
1757 /* 9 */ {0, {84,8,100,174}, MESSAGE, N_("Vertical wire width:")},
1758 /* 10 */ {0, {84,204,100,276}, EDITTEXT, x_("")},
1759 /* 11 */ {0, {120,8,136,174}, MESSAGE, N_("Power wire width:")},
1760 /* 12 */ {0, {120,204,136,276}, EDITTEXT, x_("")},
1761 /* 13 */ {0, {144,8,160,174}, MESSAGE, N_("Main power wire width:")},
1762 /* 14 */ {0, {144,204,160,276}, EDITTEXT, x_("")},
1763 /* 15 */ {0, {204,8,220,199}, MESSAGE, N_("P-Well height (0 for none):")},
1764 /* 16 */ {0, {168,204,184,352}, POPUP, x_("")},
1765 /* 17 */ {0, {228,8,244,199}, MESSAGE, N_("P-Well offset from bottom:")},
1766 /* 18 */ {0, {204,204,220,276}, EDITTEXT, x_("")},
1767 /* 19 */ {0, {320,8,336,199}, MESSAGE, N_("Via size:")},
1768 /* 20 */ {0, {232,204,248,276}, EDITTEXT, x_("")},
1769 /* 21 */ {0, {344,8,360,199}, MESSAGE, N_("Minimum metal spacing:")},
1770 /* 22 */ {0, {256,204,272,276}, EDITTEXT, x_("")},
1771 /* 23 */ {0, {384,8,400,199}, MESSAGE, N_("Routing: feed-through size:")},
1772 /* 24 */ {0, {280,204,296,276}, EDITTEXT, x_("")},
1773 /* 25 */ {0, {408,8,424,199}, MESSAGE, N_("Routing: min. port distance:")},
1774 /* 26 */ {0, {320,204,336,276}, EDITTEXT, x_("")},
1775 /* 27 */ {0, {432,8,448,199}, MESSAGE, N_("Routing: min. active dist.:")},
1776 /* 28 */ {0, {344,204,360,276}, EDITTEXT, x_("")},
1777 /* 29 */ {0, {472,8,488,199}, MESSAGE, N_("Number of rows of cells:")},
1778 /* 30 */ {0, {384,204,400,276}, EDITTEXT, x_("")},
1779 /* 31 */ {0, {408,204,424,276}, EDITTEXT, x_("")},
1780 /* 32 */ {0, {168,8,184,180}, MESSAGE, N_("Main power arc:")},
1781 /* 33 */ {0, {256,8,272,199}, MESSAGE, N_("N-Well height (0 for none):")},
1782 /* 34 */ {0, {432,204,448,276}, EDITTEXT, x_("")},
1783 /* 35 */ {0, {280,8,296,199}, MESSAGE, N_("N-Well offset from top:")},
1784 /* 36 */ {0, {472,204,488,276}, EDITTEXT, x_("")}
1785 };
1786 static DIALOG sc_optionsdialog = {{50,75,583,473}, N_("Silicon Compiler Options"), 0, 36, sc_optionsdialogitems, 0, 0};
1787
1788 /* special items for the "Silicon Compiler Options" dialog: */
1789 #define DSCO_HORIZARCS 3 /* Horizontal arc list (popup) */
1790 #define DSCO_HORIZWIDTH 4 /* Horizontal arc width (edit text) */
1791 #define DSCO_VERTARCS 8 /* Vertical arc list (popup) */
1792 #define DSCO_VERTWIDTH 10 /* Vertical arc width (edit text) */
1793 #define DSCO_POWERWIDTH 12 /* Power arc width (edit text) */
1794 #define DSCO_MPOWERWIDTH 14 /* Main power arc width (edit text) */
1795 #define DSCO_MPOWERARC 16 /* Main power arc (popup) */
1796 #define DSCO_PWELLHEIGHT 18 /* P-Well height (edit text) */
1797 #define DSCO_PWELLOFFSET 20 /* P-Well offset (edit text) */
1798 #define DSCO_NWELLHEIGHT 22 /* N-Well height (edit text) */
1799 #define DSCO_NWELLOFFSET 24 /* N-Well offset (edit text) */
1800 #define DSCO_VIASIZE 26 /* Via size (edit text) */
1801 #define DSCO_MINSPACING 28 /* Minimum spacing (edit text) */
1802 #define DSCO_FEEDTHRU 30 /* Routing feed-through size (edit text) */
1803 #define DSCO_PORTDIST 31 /* Routing minimum port dist (edit text) */
1804 #define DSCO_ACTIVEDIST 34 /* Routing minimum active dist (edit text) */
1805 #define DSCO_NUMROWS 36 /* Number of rows of cells (edit text) */
1806
sc_optionsdlog(void)1807 void sc_optionsdlog(void)
1808 {
1809 INTBIG itemHit, numarcnames, horizindex, vertindex, i, l1width, l2width,
1810 pwrwidth, mainpwrwidth, pwellsize, pwelloffset, nwellsize, nwelloffset,
1811 viasize, minspacing, feedthrusize, portxmindist, activedist, numrows,
1812 mainpwrrail;
1813 REGISTER ARCPROTO *ap, *aphoriz, *apvert;
1814 CHAR **arcnames, numstring[20], *transnames[2];
1815 REGISTER void *dia;
1816 static CHAR *powerarcnames[2] = {N_("Horizontal Arc"), N_("Vertical Arc")};
1817
1818 /* get parameters */
1819 aphoriz = (ARCPROTO *)ScGetParameter(SC_PARAM_MAKE_HORIZ_ARC);
1820 apvert = (ARCPROTO *)ScGetParameter(SC_PARAM_MAKE_VERT_ARC);
1821 l1width = ScGetParameter(SC_PARAM_MAKE_L1_WIDTH);
1822 l2width = ScGetParameter(SC_PARAM_MAKE_L2_WIDTH);
1823 pwrwidth = ScGetParameter(SC_PARAM_MAKE_PWR_WIDTH);
1824 mainpwrwidth = ScGetParameter(SC_PARAM_MAKE_MAIN_PWR_WIDTH);
1825 mainpwrrail = ScGetParameter(SC_PARAM_MAKE_MAIN_PWR_RAIL);
1826 pwellsize = ScGetParameter(SC_PARAM_MAKE_PWELL_SIZE);
1827 pwelloffset = ScGetParameter(SC_PARAM_MAKE_PWELL_OFFSET);
1828 nwellsize = ScGetParameter(SC_PARAM_MAKE_NWELL_SIZE);
1829 nwelloffset = ScGetParameter(SC_PARAM_MAKE_NWELL_OFFSET);
1830 viasize = ScGetParameter(SC_PARAM_MAKE_VIA_SIZE);
1831 minspacing = ScGetParameter(SC_PARAM_MAKE_MIN_SPACING);
1832 feedthrusize = ScGetParameter(SC_PARAM_ROUTE_FEEDTHRU_SIZE);
1833 portxmindist = ScGetParameter(SC_PARAM_ROUTE_PORT_X_MIN_DIST);
1834 activedist = ScGetParameter(SC_PARAM_ROUTE_ACTIVE_DIST);
1835 numrows = ScGetParameter(SC_PARAM_PLACE_NUM_ROWS);
1836
1837 /* gather list of arcs */
1838 numarcnames = 0;
1839 for(ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
1840 numarcnames++;
1841 numarcnames++;
1842 arcnames = (CHAR **)emalloc(numarcnames * (sizeof (CHAR *)), el_tempcluster);
1843 if (arcnames == 0) return;
1844 numarcnames = 0;
1845 arcnames[numarcnames++] = _("NOT SELECTED");
1846 horizindex = vertindex = 0;
1847 for(ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
1848 {
1849 arcnames[numarcnames] = ap->protoname;
1850 if (aphoriz == ap) horizindex = numarcnames;
1851 if (apvert == ap) vertindex = numarcnames;
1852 numarcnames++;
1853 }
1854
1855 /* display the silicon compiler options dialog box */
1856 dia = DiaInitDialog(&sc_optionsdialog);
1857 if (dia == 0) return;
1858 for(i=0; i<2; i++) transnames[i] = TRANSLATE(powerarcnames[i]);
1859 DiaSetPopup(dia, DSCO_MPOWERARC, 2, transnames);
1860 DiaSetPopup(dia, DSCO_VERTARCS, numarcnames, arcnames);
1861 DiaSetPopup(dia, DSCO_HORIZARCS, numarcnames, arcnames);
1862 DiaSetPopupEntry(dia, DSCO_VERTARCS, vertindex);
1863 DiaSetPopupEntry(dia, DSCO_HORIZARCS, horizindex);
1864 DiaSetText(dia, DSCO_HORIZWIDTH, latoa(l1width, 0));
1865 DiaSetText(dia, DSCO_VERTWIDTH, latoa(l2width, 0));
1866 DiaSetText(dia, DSCO_POWERWIDTH, latoa(pwrwidth, 0));
1867 DiaSetText(dia, DSCO_MPOWERWIDTH, latoa(mainpwrwidth, 0));
1868 DiaSetText(dia, DSCO_PWELLHEIGHT, latoa(pwellsize, 0));
1869 DiaSetText(dia, DSCO_PWELLOFFSET, latoa(pwelloffset, 0));
1870 DiaSetText(dia, DSCO_VIASIZE, latoa(viasize, 0));
1871 DiaSetText(dia, DSCO_MINSPACING, latoa(minspacing, 0));
1872 DiaSetText(dia, DSCO_FEEDTHRU, latoa(feedthrusize, 0));
1873 DiaSetText(dia, DSCO_PORTDIST, latoa(portxmindist, 0));
1874 DiaSetText(dia, DSCO_ACTIVEDIST, latoa(activedist, 0));
1875 esnprintf(numstring, 20, x_("%ld"), numrows);
1876 DiaSetText(dia, DSCO_NUMROWS, numstring);
1877 DiaSetPopupEntry(dia, DSCO_MPOWERARC, mainpwrrail);
1878 DiaSetText(dia, DSCO_NWELLHEIGHT, latoa(nwellsize, 0));
1879 DiaSetText(dia, DSCO_NWELLOFFSET, latoa(nwelloffset, 0));
1880
1881 /* loop until done */
1882 for(;;)
1883 {
1884 itemHit = DiaNextHit(dia);
1885 if (itemHit == OK || itemHit == CANCEL) break;
1886 }
1887
1888 if (itemHit != CANCEL)
1889 {
1890 i = DiaGetPopupEntry(dia, DSCO_VERTARCS);
1891 if (i == 0) ap = NOARCPROTO; else
1892 ap = getarcproto(arcnames[i]);
1893 if (ap != apvert) ScSetParameter(SC_PARAM_MAKE_VERT_ARC, (INTBIG)ap);
1894 i = DiaGetPopupEntry(dia, DSCO_HORIZARCS);
1895 if (i == 0) ap = NOARCPROTO; else
1896 ap = getarcproto(arcnames[i]);
1897 if (ap != aphoriz) ScSetParameter(SC_PARAM_MAKE_HORIZ_ARC, (INTBIG)ap);
1898
1899 i = atola(DiaGetText(dia, DSCO_HORIZWIDTH), 0);
1900 if (i != l1width) ScSetParameter(SC_PARAM_MAKE_L1_WIDTH, i);
1901 i = atola(DiaGetText(dia, DSCO_VERTWIDTH), 0);
1902 if (i != l2width) ScSetParameter(SC_PARAM_MAKE_L2_WIDTH, i);
1903 i = atola(DiaGetText(dia, DSCO_POWERWIDTH), 0);
1904 if (i != pwrwidth) ScSetParameter(SC_PARAM_MAKE_PWR_WIDTH, i);
1905 i = atola(DiaGetText(dia, DSCO_MPOWERWIDTH), 0);
1906 if (i != mainpwrwidth) ScSetParameter(SC_PARAM_MAKE_MAIN_PWR_WIDTH, i);
1907 i = atola(DiaGetText(dia, DSCO_PWELLHEIGHT), 0);
1908 if (i != pwellsize) ScSetParameter(SC_PARAM_MAKE_PWELL_SIZE, i);
1909 i = atola(DiaGetText(dia, DSCO_PWELLOFFSET), 0);
1910 if (i != pwelloffset) ScSetParameter(SC_PARAM_MAKE_PWELL_OFFSET, i);
1911 i = atola(DiaGetText(dia, DSCO_VIASIZE), 0);
1912 if (i != viasize) ScSetParameter(SC_PARAM_MAKE_VIA_SIZE, i);
1913 i = atola(DiaGetText(dia, DSCO_MINSPACING), 0);
1914 if (i != minspacing) ScSetParameter(SC_PARAM_MAKE_MIN_SPACING, i);
1915 i = atola(DiaGetText(dia, DSCO_FEEDTHRU), 0);
1916 if (i != feedthrusize) ScSetParameter(SC_PARAM_ROUTE_FEEDTHRU_SIZE, i);
1917 i = atola(DiaGetText(dia, DSCO_PORTDIST), 0);
1918 if (i != portxmindist) ScSetParameter(SC_PARAM_ROUTE_PORT_X_MIN_DIST, i);
1919 i = atola(DiaGetText(dia, DSCO_ACTIVEDIST), 0);
1920 if (i != activedist) ScSetParameter(SC_PARAM_ROUTE_ACTIVE_DIST, i);
1921 i = eatoi(DiaGetText(dia, DSCO_NUMROWS));
1922 if (i != numrows) ScSetParameter(SC_PARAM_PLACE_NUM_ROWS, i);
1923 i = DiaGetPopupEntry(dia, DSCO_MPOWERARC);
1924 if (i != mainpwrrail) ScSetParameter(SC_PARAM_MAKE_MAIN_PWR_RAIL, i);
1925 i = atola(DiaGetText(dia, DSCO_NWELLHEIGHT), 0);
1926 if (i != nwellsize) ScSetParameter(SC_PARAM_MAKE_NWELL_SIZE, i);
1927 i = atola(DiaGetText(dia, DSCO_NWELLOFFSET), 0);
1928 if (i != nwelloffset) ScSetParameter(SC_PARAM_MAKE_NWELL_OFFSET, i);
1929 }
1930 efree((CHAR *)arcnames);
1931 DiaDoneDialog(dia);
1932 }
1933
1934 #endif /* SCTOOL - at top */
1935