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