1 /* -*- tab-width: 4 -*-
2  *
3  * Electric(tm) VLSI Design System
4  *
5  * File: sc1sim.c
6  * Modules concerned with simulation output for the QUISC Silicon Compiler
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 "sc1.h"
37 
38 extern SCCELL	*sc_cells, *sc_curcell;
39 
40 int sc_sim_format = SC_SILOS_FORMAT;
41 
42 /* prototypes for local routines */
43 static int   Sc_simformat(int, CHAR*[]);
44 static int   Sc_simset(int, CHAR*[]);
45 static int   Sc_simshow(int, CHAR*[]);
46 static int   Sc_simwrite(int, CHAR*[]);
47 static void  Sc_simwrite_clear_flags(void);
48 static int   Sc_simwrite_model(SCCELL*, CHAR*, FILE*);
49 static int   Sc_simwrite_subelements(SCNITREE*, FILE*);
50 static int   Sc_simwrite_cell_instances(SCCELL*, FILE*);
51 static CHAR *Sc_sim_isaport(SCCELL*, CHAR*);
52 static int   Sc_simwrite_gate(CHAR*, FILE*);
53 static void  Sc_fprintf_80(FILE *fp, CHAR *fstring, ...);
54 
55 /***********************************************************************
56 Module:  Sc_simulation
57 ------------------------------------------------------------------------
58 Description:
59 	Interprete and execute the simulation command.  Valid options are:
60 		1.  set - set a cell's model
61 		2.  show - show a cell's model
62 		3.  write - output the simulation file
63 		4.  format - select the output format (silos or als (default)
64 ------------------------------------------------------------------------
65 */
66 
Sc_simulation(int count,CHAR * pars[])67 int Sc_simulation(int count, CHAR *pars[])
68 {
69 	int		l;
70 
71 	if (!count)
72 		return(Sc_seterrmsg(SC_SIMNPARS));
73 	l = estrlen(pars[0]);
74 
75 	if (namesamen(pars[0], x_("set"), l) == 0)
76 		return(Sc_simset(count-1, &pars[1]));
77 	if (namesamen(pars[0], x_("show"), l) == 0)
78 		return(Sc_simshow(count-1, &pars[1]));
79 	if (namesamen(pars[0], x_("write"), l) == 0)
80 		return(Sc_simwrite(count-1, &pars[1]));
81 	if (namesamen(pars[0], x_("format"), l) == 0)
82 		return(Sc_simformat(count-1, &pars[1]));
83 	return(Sc_seterrmsg(SC_SIMXCMD, pars[0]));
84 }
85 
86 /*************************************************************
87 Module:  Sc_simformat
88 -------------------------------------------------------------
89 Description: Set the simulator format to be used
90 ------------------------------------------------------------------
91 */
92 
Sc_simformat(int count,CHAR * pars[])93 int Sc_simformat(int count, CHAR *pars[])
94 {
95 	if (!count)
96 		return(Sc_seterrmsg(SC_SIMNPARS));
97 	if (namesamen(pars[0], x_("als"), 3) == 0)
98 	{
99 		sc_sim_format = SC_ALS_FORMAT;
100 		return(SC_NOERROR);
101 	}
102 	if (namesamen(pars[0], x_("silos"), 5) == 0)
103 	{
104 		sc_sim_format = SC_SILOS_FORMAT;
105 		return(SC_NOERROR);
106 	}
107 	return(Sc_seterrmsg(SC_UNKNOWN, pars[0]));
108 }
109 
110 /***********************************************************************
111 Module:  Sc_simset
112 ------------------------------------------------------------------------
113 Description:
114 	Handle the setting of the simulation model for a node and/or cell.
115 ------------------------------------------------------------------------
116 */
117 
Sc_simset(int count,CHAR * pars[])118 int Sc_simset(int count, CHAR *pars[])
119 {
120 	SCCELL	*cell;
121 	CHAR	**simlist, buffer[MAXLINE];
122 	CHAR	*leafcell, *filename;
123 	SCSIM	*simline, *oldline, *startline;
124 	int		type, i;
125 	FILE	*fp;
126 
127 	if (!count)
128 		return(Sc_seterrmsg(SC_SIMSETNPARS));
129 
130 	/* check for a complex cell */
131 	for (cell = sc_cells; cell; cell = cell->next)
132 	{
133 		if (namesame(pars[0], cell->name) == 0) break;
134 	}
135 	if (cell == NULL)
136 	{
137 		/* try to find leaf cell in current library */
138 		if ((leafcell = Sc_find_leaf_cell(pars[0])) == NULL)
139 			return(Sc_seterrmsg(SC_CELLNOFIND, pars[0]));
140 		type = SCLEAFCELL;
141 	} else
142 	{
143 		type = SCCOMPLEXCELL;
144 	}
145 
146 	/* check if simulation information already exits */
147 	if (type == SCCOMPLEXCELL)
148 	{
149 		if (cell->siminfo)
150 		{
151 			if ((fp = xcreate(SCSIMFILE, sc_filetypescsim, _("Simulation File"), 0)) == NULL)
152 				return(Sc_seterrmsg(SC_SIMSETFERROR));
153 			for (simline = (SCSIM *)cell->siminfo; simline; simline = simline->next)
154 				xprintf(fp, x_("%s\n"), simline->model);
155 			xclose(fp);
156 		}
157 	} else
158 	{
159 		/* write out simulation information for leafcell if it exists */
160 		if ((simlist = Sc_leaf_cell_sim_info(leafcell)))
161 		{
162 			if ((fp = xcreate(SCSIMFILE, sc_filetypescsim, _("Simulation File"), 0)) == NULL)
163 				return(Sc_seterrmsg(SC_SIMSETFERROR));
164 			for (i = 0; simlist[i]; i++)
165 				xprintf(fp, x_("%s\n"), simlist[i]);
166 			xclose(fp);
167 		}
168 	}
169 
170 	/* get lines */
171 	if ((fp = xopen(SCSIMFILE, sc_filetypescsim, x_(""), &filename)) == NULL)
172 		return(Sc_seterrmsg(SC_SIMSETFERROR));
173 	oldline = NULL;
174 	startline = NULL;
175 	for(;;)
176 	{
177 		if (xfgets(buffer, MAXLINE, fp)) break;
178 		/*
179 		 * BUG ALERT:
180 		 *    xfgets has a bug, and strips of the '\n'.
181 		 *    Fixing the bug causes problems elsewhere.
182 		 *    Therefore, check for '\n' before stripping it off.
183 		 * LWS 12/11/89
184 		 */
185 		i = estrlen(buffer);
186 		if (buffer[i-1] == '\n') buffer[i-1] = '\0';
187 		/* buffer[strlen(buffer) - 1] = NULL; */	/* strip off newline */
188 		simline = (SCSIM *)emalloc(sizeof(SCSIM), sc_tool->cluster);
189 		if (simline == 0)
190 			return(Sc_seterrmsg(SC_NOMEMORY));
191 		if (oldline)
192 		{
193 			oldline->next = simline;
194 		} else
195 		{
196 			startline = simline;
197 		}
198 		if (allocstring(&simline->model, buffer, sc_tool->cluster))
199 			return(Sc_seterrmsg(SC_NOMEMORY));
200 		simline->next = NULL;
201 		oldline = simline;
202 	}
203 	xclose(fp);
204 
205 	/* set similation information based on object type */
206 	if (type == SCCOMPLEXCELL)
207 	{
208 		if (cell->siminfo)
209 		{
210 			for (simline = (SCSIM *)cell->siminfo; simline; )
211 			{
212 				if (simline->model)
213 					efree((CHAR *)simline->model);
214 				oldline = simline;
215 				simline = simline->next;
216 				efree((CHAR *)oldline);
217 			}
218 			cell->siminfo = NULL;
219 		}
220 		cell->siminfo = startline;
221 	} else
222 	{
223 		(void)Sc_leaf_cell_set_sim(startline, leafcell);
224 	}
225 	return(0);
226 }
227 
228 /***********************************************************************
229 Module:  Sc_simshow
230 ------------------------------------------------------------------------
231 Description:
232 	Handle the showing of the simulation model for a complex or leaf cell.
233 ------------------------------------------------------------------------
234 */
235 
Sc_simshow(int count,CHAR * pars[])236 int Sc_simshow(int count, CHAR *pars[])
237 {
238 	SCCELL		*cell;
239 	SCSIM		*simline;
240 	CHAR		**simlist, *leafcell, simhdr[10];
241 	int			i;
242 
243 	if (!count)
244 		return(Sc_seterrmsg(SC_SIMSHOWNPARS));
245 
246 	if (sc_sim_format == SC_ALS_FORMAT)
247 	{
248 		estrcpy(simhdr, x_("ALS"));
249 	} else if (sc_sim_format == SC_SILOS_FORMAT)
250 	{
251 		estrcpy(simhdr, x_("SILOS"));
252 	}
253 	for (cell = sc_cells; cell; cell = cell->next)
254 	{
255 		if (namesame(pars[0], cell->name) == 0)
256 			break;
257 	}
258 	if (cell == NULL)
259 	{
260 		if ((leafcell = Sc_find_leaf_cell(pars[0])) == NULL)
261 			return(Sc_seterrmsg(SC_CELLNOFIND, pars[0]));
262 		ttyputmsg(_("%s SIMULATION Model for leaf cell %s:"), simhdr, pars[0]);
263 		if ((simlist = Sc_leaf_cell_sim_info(leafcell)))
264 		{
265 			for (i = 0; simlist[i]; i++)
266 			{
267 				if (*(simlist[i]))
268 				{
269 					ttyputmsg(simlist[i]);
270 				} else
271 				{
272 					ttyputmsg(x_(" "));
273 				}
274 			}
275 		}
276 	} else
277 	{
278 		ttyputmsg(_("%s SIMULATION Model for cell %s:"), simhdr, pars[0]);
279 		for (simline = cell->siminfo; simline; simline = simline->next)
280 		{
281 			if (*(simline->model))
282 			{
283 				ttyputmsg(simline->model);
284 			} else
285 			{
286 				ttyputmsg(x_(" "));
287 			}
288 		}
289 	}
290 	return(0);
291 }
292 
293 /***********************************************************************
294 Module:  Sc_simwrite
295 ------------------------------------------------------------------------
296 Description:
297 	Handle the writing of the simulation file for a cell.
298 ------------------------------------------------------------------------
299 */
300 
Sc_simwrite(int count,CHAR * pars[])301 int Sc_simwrite(int count, CHAR *pars[])
302 {
303 	CHAR	*strtime, outfile[60];
304 	FILE	*fp;
305 	SCCELL	*cell;
306 	time_t	tsec;
307 	int		err;
308 	SCPORT	*port;
309 
310 	if (count < 1)
311 		return(Sc_seterrmsg(SC_SIMWRITENPARS));
312 
313 	/* search for cell in current complex cell list */
314 	for (cell = sc_cells; cell; cell = cell->next)
315 	{
316 		if (namesame(pars[0], cell->name) == 0)
317 			break;
318 	}
319 	if (cell == NULL)
320 		return(Sc_seterrmsg(SC_CELLNOFIND, pars[0]));
321 
322 	/* open output file */
323 	if (count > 1)
324 	{
325 		(void)estrcpy(outfile, pars[1]);
326 	} else
327 	{
328 		(void)estrcpy(outfile, cell->name);
329 		if (sc_sim_format == SC_ALS_FORMAT)
330 		{
331 			(void)estrcat(outfile, x_(".net"));
332 		} else if (sc_sim_format == SC_SILOS_FORMAT)
333 		{
334 			(void)estrcat(outfile, x_(".sil"));
335 		}
336 	}
337 
338 	if ((fp = xcreate(outfile, sc_filetypescsim, _("Simulation File"), 0)) == NULL)
339 		return(Sc_seterrmsg(SC_SIMWRITEFOPEN, outfile));
340 	tsec = getcurrenttime();
341 	strtime = timetostring(tsec);
342 	Sc_simwrite_clear_flags();
343 
344 	if (sc_sim_format == SC_ALS_FORMAT)
345 	{
346 		Sc_fprintf_80(fp, x_("#*************************************************\n"));
347 		Sc_fprintf_80(fp, x_("#  ALS Design System netlist file\n"));
348 		Sc_fprintf_80(fp, x_("#  File Created by Electric (vhdl-compiler) on:\n"));
349 		Sc_fprintf_80(fp, x_("#  %s\n"), strtime);
350 		Sc_fprintf_80(fp, x_("#  For main cell:    %s\n"), pars[0]);
351 		Sc_fprintf_80(fp, x_("#-------------------------------------------------\n\n"));
352 		err = Sc_simwrite_model(cell, x_("main"), fp);
353 		Sc_fprintf_80(fp, x_("\n#********* End of netlist file *******************\n"));
354 	} else if (sc_sim_format == SC_SILOS_FORMAT)
355 	{
356 		Sc_fprintf_80(fp, x_("$*************************************************\n"));
357 		Sc_fprintf_80(fp, x_("$  SILOS netlist file\n"));
358 		Sc_fprintf_80(fp, x_("$  File Created by Electric (vhdl-compiler) on:\n"));
359 		Sc_fprintf_80(fp, x_("$  %s\n"), strtime);
360 		Sc_fprintf_80(fp, x_("$  For main cell:    %s\n"), pars[0]);
361 		Sc_fprintf_80(fp, x_("$-------------------------------------------------\n\n"));
362 		Sc_fprintf_80(fp, x_(".GLOBAL power\npower .CLK 0 S1\n"));
363 		Sc_fprintf_80(fp, x_(".GLOBAL ground\nground .CLK 0 S0\n\n"));
364 		err = Sc_simwrite_model(cell, cell->name, fp);
365 		Sc_fprintf_80(fp, x_("(%s %s "),cell->name, cell->name);	/* top level call*/
366 		for (port = cell->ports; port; port = port->next)
367 		{
368 			switch (port->bits & SCPORTTYPE)
369 			{
370 				/* ports are actual */
371 				case SCPWRPORT:
372 				case SCGNDPORT:
373 					break;
374 				default:
375 					Sc_fprintf_80(fp, x_(" %s"), port->name);
376 					break;
377 			}
378 		}
379 		Sc_fprintf_80(fp, x_("\n"));
380 		Sc_fprintf_80(fp, x_("\n$********* End of netlist file *******************\n"));
381 	}
382 	xclose(fp);
383 	return(err);
384 }
385 
386 /***********************************************************************
387 Module:  Sc_simwrite_clear_flags
388 ------------------------------------------------------------------------
389 Description:
390 	Clear the simwrite required and written flags on all complex cells
391 	and leaf cells.
392 ------------------------------------------------------------------------
393 */
394 
Sc_simwrite_clear_flags(void)395 void Sc_simwrite_clear_flags(void)
396 {
397 	SCCELL	*cell;
398 	CHAR	*leafcell;
399 	int		*bits;
400 
401 	/* clear flags on all complex cells */
402 	for (cell = sc_cells; cell; cell = cell->next)
403 		cell->bits &= ~SCSIMWRITEBITS;
404 
405 	/* clear flags on all leafcells */
406 	for (leafcell = Sc_first_leaf_cell(); leafcell != NULL;
407 		leafcell = Sc_next_leaf_cell(leafcell))
408 	{
409 		bits = Sc_leaf_cell_bits_address(leafcell);
410 		*bits &= ~SCSIMWRITEBITS;
411 	}
412 }
413 
414 /***********************************************************************
415 Module:  Sc_simwrite_model
416 ------------------------------------------------------------------------
417 Description:
418 	Procedure to write a model netlist file.
419 ------------------------------------------------------------------------
420 */
421 
Sc_simwrite_model(SCCELL * cell,CHAR * name,FILE * fp)422 int Sc_simwrite_model(SCCELL *cell, CHAR *name, FILE *fp)
423 {
424 	SCPORT	*port;
425 	int		err, first;
426 	SCSIM	*simline;
427 
428 	cell->bits |= SCSIMWRITESEEN;
429 	if (cell->siminfo)
430 	{
431 		for (simline = cell->siminfo; simline; simline = simline->next)
432 		{
433 			if (*(simline->model))
434 			{
435 				ttyputmsg(simline->model);
436 			} else
437 			{
438 				ttyputmsg(x_(" "));
439 			}
440 		}
441 	} else
442 	{
443 		/* first print submodels */
444 		if ((err = Sc_simwrite_subelements(cell->nilist, fp)))
445 			return(err);
446 	}
447 
448 	if (sc_sim_format == SC_ALS_FORMAT)
449 	{
450 		Sc_fprintf_80(fp, x_("model %s("), name);
451 	} else if (sc_sim_format == SC_SILOS_FORMAT)
452 	{
453 		Sc_fprintf_80(fp, x_(".MACRO %s"), name);
454 	}
455 	first = TRUE;
456 	for (port = cell->ports; port; port = port->next)
457 	{
458 		switch (port->bits & SCPORTTYPE)
459 		{
460 			case SCPWRPORT:
461 			case SCGNDPORT:
462 				break;
463 			default:
464 				if (sc_sim_format == SC_ALS_FORMAT)
465 				{
466 					if (first)
467 					{
468 						Sc_fprintf_80(fp, x_("%s"), port->name);
469 						first = FALSE;
470 					} else
471 					{
472 						Sc_fprintf_80(fp, x_(", %s"), port->name);
473 					}
474 				} else if (sc_sim_format == SC_SILOS_FORMAT)
475 				{
476 					Sc_fprintf_80(fp, x_(" %s"),
477 					Sc_sim_isaport(cell, port->name));
478 				}
479 				break;
480 		}
481 	}
482 	if (sc_sim_format == SC_ALS_FORMAT)
483 	{
484 		Sc_fprintf_80(fp, x_(")\n"));
485 	} else if (sc_sim_format == SC_SILOS_FORMAT)
486 	{
487 		Sc_fprintf_80(fp, x_("\n"));
488 	}
489 
490 	/* print instances of cells */
491 	if (!(cell->siminfo))
492 	{
493 		if ((err = Sc_simwrite_cell_instances(cell, fp)))
494 			return(err);
495 	}
496 
497 	if (sc_sim_format == SC_SILOS_FORMAT)
498 	{
499 		Sc_fprintf_80(fp, x_(".EOM\n\n"));
500 	} else
501 	{
502 		Sc_fprintf_80(fp, x_("\n"));
503 	}
504 	return(SC_NOERROR);
505 }
506 
507 /***********************************************************************
508 Module:  Sc_simwrite_subelements
509 ------------------------------------------------------------------------
510 Description:
511 	Recursively write any subelements of the node instance tree.
512 ------------------------------------------------------------------------
513 */
514 
Sc_simwrite_subelements(SCNITREE * nptr,FILE * fp)515 int Sc_simwrite_subelements(SCNITREE *nptr, FILE *fp)
516 {
517 	int		err;
518 
519 	for (; nptr; nptr = nptr->next)
520 	{
521 		switch (nptr->type)
522 		{
523 			case SCCOMPLEXCELL:
524 				if (!(((SCCELL *)(nptr->np))->bits & SCSIMWRITESEEN))
525 				{
526 					if ((err = Sc_simwrite_model(((SCCELL *)(nptr->np)),
527 						((SCCELL *)(nptr->np))->name, fp)))
528 							return(err);
529 				}
530 				break;
531 			case SCLEAFCELL:
532 				if (!(Sc_leaf_cell_bits(nptr->np) & SCSIMWRITESEEN))
533 				{
534 					if ((err = Sc_simwrite_gate(nptr->np, fp)))
535 						return(err);
536 				}
537 				break;
538 			default:
539 				break;
540 		}
541 	}
542 	return(0);
543 }
544 
545 /***********************************************************************
546 Module:  Sc_simwrite_cell_instances
547 ------------------------------------------------------------------------
548 Description:
549 	Print instances of complex or leaf cells within a cell
550 ------------------------------------------------------------------------
551 */
552 
Sc_simwrite_cell_instances(SCCELL * cell,FILE * fp)553 int Sc_simwrite_cell_instances(SCCELL *cell, FILE *fp)
554 {
555 	int		first, power, ground;
556 	SCNIPORT	*port;
557 	SCNITREE    *nptr;
558 
559 	nptr = cell->nilist;
560 	if (nptr == NULL)
561 		return(0);
562 	power = ground = FALSE;
563 	for ( ; nptr; nptr = nptr->next)
564 	{
565 		switch (nptr->type)
566 		{
567 			case SCCOMPLEXCELL:
568 				if (sc_sim_format == SC_ALS_FORMAT)
569 				{
570 					Sc_fprintf_80(fp, x_("%s: "), nptr->name);
571 					Sc_fprintf_80(fp, x_("%s("), ((SCCELL *)(nptr->np))->name);
572 				} else if (sc_sim_format == SC_SILOS_FORMAT)
573 				{
574 					Sc_fprintf_80(fp, x_("(%s %s"), nptr->name,
575 						((SCCELL *)(nptr->np))->name);
576 				}
577 				first = TRUE;
578 				for (port = nptr->ports; port; port = port->next)
579 				{
580 					if (sc_sim_format == SC_ALS_FORMAT)
581 					{
582 						if (first)
583 						{
584 							Sc_fprintf_80(fp, x_("%s"), port->ext_node->name);
585 							first = FALSE;
586 						} else
587 						{
588 							Sc_fprintf_80(fp, x_(", %s"), port->ext_node->name);
589 						}
590 					} else if (sc_sim_format == SC_SILOS_FORMAT)
591 					{
592 						if (port->ext_node->firstport->next == NULL)
593 						{
594 							Sc_fprintf_80(fp, x_(" .SKIP"));
595 						} else
596 						{
597 							Sc_fprintf_80(fp, x_(" %s"),
598 							Sc_sim_isaport(cell,port->ext_node->name));
599 						}
600 					}
601 					if (namesame(port->ext_node->name, x_("ground")) == 0)
602 					{
603 						ground = TRUE;
604 					} else if (namesame(port->ext_node->name, x_("power")) == 0)
605 					{
606 						power = TRUE;
607 					}
608 				}
609 				if (sc_sim_format == SC_ALS_FORMAT)
610 				{
611 					Sc_fprintf_80(fp, x_(")\n"));
612 				} else
613 				{
614 					Sc_fprintf_80(fp, x_("\n"));
615 				}
616 				break;
617 			case SCLEAFCELL:
618 				if (sc_sim_format == SC_ALS_FORMAT)
619 				{
620 					Sc_fprintf_80(fp, x_("%s: "), nptr->name);
621 					Sc_fprintf_80(fp, x_("%s("), Sc_leaf_cell_name(nptr->np));
622 				} else if (sc_sim_format == SC_SILOS_FORMAT)
623 				{
624 					Sc_fprintf_80(fp, x_("(%s %s "), nptr->name,
625 						Sc_leaf_cell_name(nptr->np));
626 				}
627 				first = TRUE;
628 				for (port = nptr->ports; port; port = port->next)
629 				{
630 					if (sc_sim_format == SC_ALS_FORMAT)
631 					{
632 						if (first)
633 						{
634 							Sc_fprintf_80(fp, x_("%s"), port->ext_node->name);
635 							first = FALSE;
636 						} else
637 						{
638 							Sc_fprintf_80(fp, x_(", %s"), port->ext_node->name);
639 						}
640 					} else if (sc_sim_format == SC_SILOS_FORMAT)
641 					{
642 						if (port->ext_node->firstport->next == NULL)
643 						{
644 							Sc_fprintf_80(fp, x_(" .SKIP"));
645 						} else
646 						{
647 							Sc_fprintf_80(fp, x_(" %s"),
648 							Sc_sim_isaport(cell, port->ext_node->name));
649 						}
650 					}
651 					if (namesame(port->ext_node->name, x_("ground")) == 0)
652 					{
653 						ground = TRUE;
654 					} else if (namesame(port->ext_node->name, x_("power")) == 0)
655 					{
656 						power = TRUE;
657 					}
658 				}
659 				if (sc_sim_format == SC_ALS_FORMAT)
660 				{
661 					Sc_fprintf_80(fp, x_(")\n"));
662 				} else
663 				{
664 					Sc_fprintf_80(fp, x_("\n"));
665 				}
666 				break;
667 			case SCSPECIALCELL:
668 			default:
669 				break;
670 		}
671 	}
672 	if (sc_sim_format == SC_ALS_FORMAT)
673 	{
674 		if (ground)
675 			Sc_fprintf_80(fp, x_("set ground=L@3\n"));
676 		if (power)
677 			Sc_fprintf_80(fp, x_("set power=H@3\n"));
678 	}
679 	return(0);
680 }
681 
682 /**********************************************************************
683 Module: Sc_sim_isaport
684 -----------------------------------------------------------------------
685 Description:
686 	Determine if this instance port is also one of the ports on the
687 		model, and if it subscripted;
688 ----------------------------------------------------------------------
689 Calling sequence:
690 	 Sc_sim_isaport(cell, portname)
691 Where: cell is the model (macro) in which the instance exists
692 	   portname is the name of this port
693 
694 Returns: the original string, or one which is modified to replace
695 the '[' with '_'
696 ----------------------------------------------------------------------
697 */
698 
Sc_sim_isaport(SCCELL * cell,CHAR * portname)699 CHAR *Sc_sim_isaport(SCCELL *cell, CHAR *portname)
700 {
701 	SCPORT *test;
702 	CHAR *ptr;
703 	static CHAR newname[100];
704 
705 	if (estrchr(portname, '[') == 0) return(portname);
706 
707 	for (test = cell->ports; test != NULL; test = test->next)
708 	{
709 		if (namesame(portname, test->name) == 0)
710 		{
711 			for(ptr = newname; *portname;  ptr++, portname ++)
712 			{
713 				if (*portname == '[')
714 				{
715 					estrcpy(ptr, x_("__"));
716 					ptr++;
717 				} else if (*ptr == ']')
718 				{
719 					continue;
720 				} else
721 				{
722 					*ptr = *portname;
723 				}
724 			}
725 			*ptr = 0;
726 			return(newname);
727 		}
728 	}
729 	return(portname);
730 }
731 
732 /***********************************************************************
733 Module:  Sc_simwrite_gate
734 ------------------------------------------------------------------------
735 Description:
736 	Write a gate description for the indicated leaf cell.
737 ------------------------------------------------------------------------
738 */
739 
Sc_simwrite_gate(CHAR * leafcell,FILE * fp)740 int Sc_simwrite_gate(CHAR *leafcell, FILE *fp)
741 {
742 	CHAR	**simlist;
743 	int		i, *bits;
744 
745 	bits = Sc_leaf_cell_bits_address(leafcell);
746 	*bits |= SCSIMWRITESEEN;
747 	if ((simlist = Sc_leaf_cell_sim_info(leafcell)))
748 	{
749 		for (i = 0; simlist[i]; i++)
750 		{
751 			Sc_fprintf_80(fp, simlist[i]);
752 			Sc_fprintf_80(fp, x_("\n"));
753 		}
754 		Sc_fprintf_80(fp, x_("\n"));
755 		return(0);
756 	} else
757 	{
758 		return(Sc_seterrmsg(SC_SCVARNOFIND,Sc_leaf_cell_name(leafcell)));
759 	}
760 }
761 
762 /***********************************************************************
763 Module:  Sc_fprintf_80
764 ------------------------------------------------------------------------
765 Description:
766 	Print the passed format string and elements to the indicated file
767 	while keeping the maximum line length to less than 80.  It does this
768 	by inserting new lines where necessary.  Note that the number of
769 	elements is limited to eight.
770 	Modified Aug. 1989 (SRP) for SILOS continuation character.
771 ------------------------------------------------------------------------
772 Calling Sequence:  Sc_fprintf_80(fp, fstring, arg1, arg2, arg3, ...);
773 
774 Name			Type		Description
775 ----			----		-----------
776 fp				*FILE		Pointer to output file.
777 fstring			*char		Pointer to formating string.
778 arg1,arg2,...	int			Generic values (pointers) to items.
779 ------------------------------------------------------------------------
780 */
781 
Sc_fprintf_80(FILE * fp,CHAR * fstring,...)782 void Sc_fprintf_80(FILE *fp, CHAR *fstring, ...)
783 {
784 	static int	lline = 0;
785 	int			length;
786 	CHAR		buff[256], *sptr, save[10];
787 	va_list		ap;
788 
789 	var_start(ap, fstring);
790 	evsnprintf(buff, 256, fstring, ap);
791 	va_end(ap);
792 	length = estrlen(buff);
793 	sptr = buff;
794 	if ((lline + length) > 70)
795 	{
796 		/* insert newline at first white space */
797 		while (*sptr)
798 		{
799 			if (isspace(*sptr))
800 			{
801 				estrncpy(save, sptr, 3);
802 				estrcpy(sptr, x_("\n"));
803 				if (sc_sim_format == SC_SILOS_FORMAT)
804 				{
805 					estrcat(sptr, x_("+"));
806 					lline = 1;
807 				} else
808 				{
809 					lline = 0;
810 				}
811 				xprintf(fp, buff);
812 				estrncpy(sptr, save, 3);
813 				break;
814 			}
815 			sptr++;
816 		}
817 		if (*sptr == 0)
818 		{
819 			sptr = buff;
820 		}
821 	}
822 	xprintf(fp, sptr);
823 	for ( ; *sptr != 0; sptr++)
824 	{
825 		if (*sptr == '\n')
826 		{
827 			lline = 0;
828 		} else
829 		{
830 			lline++;
831 		}
832 	}
833 }
834 
835 #endif  /* SCTOOL - at top */
836