1 /* Copyright (c) 1991-2007 Pragmatic C Software Corp. */
2 
3 /*
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2 of the License, or (at your
7    option) any later version.
8 
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17 
18    We are selling our new Verilog compiler that compiles to X86 Linux
19    assembly language.  It is at least two times faster for accurate gate
20    level designs and much faster for procedural designs.  The new
21    commercial compiled Verilog product is called CVC.  For more information
22    on CVC visit our website at www.pragmatic-c.com/cvc.htm or contact
23    Andrew at avanvick@pragmatic-c.com
24 
25  */
26 
27 
28 /*
29  * main module - command option and license manager code
30  */
31 
32 /*
33  * main module
34  */
35 #include <stdio.h>
36 #include <time.h>
37 
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <sys/time.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <stdlib.h>
46 
47 #include <ctype.h>
48 
49 #include <signal.h>
50 
51 #include <setjmp.h>
52 
53 #ifdef __DBMALLOC__
54 #include "../malloc.h"
55 #endif
56 
57 #include "v.h"
58 #include "cvmacros.h"
59 
60 static char copyright[]
61  = "Copyright (c) 1991-2007 Pragmatic C Software Corp.";
62 
63 /* declares from v.h */
64 /* various simulation counting variables */
65 char *__vers;          /* actual product info */
66 char *__vers2;
67 char *__ofdt;
68 char *__platform;
69 char *__start_sp, *__end_sp;/* pointer for "big" memory allocator */
70 char *__pvdate;        /* date in unix form */
71 char *__pv_timestamp;  /* timestamp for design */
72 time_t __start_time;   /* start wall clock times in secs. */
73 time_t __start_mstime; /* start millisecond part */
74 time_t __end_comp_time;/* end of compilation time */
75 time_t __end_comp_mstime;
76 time_t __end_prep_time;/* end of preparation time */
77 time_t __end_prep_mstime;
78 time_t __end_time;     /* start and end wall clock times */
79 time_t __end_mstime;   /* start and end wall clock times */
80 
81 /* various file variables and global data base flags (i/o vars) */
82 char **__in_fils;      /* malloced input file list from args */
83 int32 __siz_in_fils;   /* current size of input files */
84 int32 __last_inf;      /* last input file in list */
85 int32 __last_optf;     /* last option file */
86 int32 __last_lbf;      /* last lib/inc file (starts last_inf + 1) */
87 int32 __last_srcf;     /* last src containing file for debugger */
88 struct incloc_t *__inclst_hdr; /* header of included files list */
89 struct incloc_t *__inclst_end; /* end of included files list */
90 struct filpos_t *__filpostab; /* in fils size tab of file line pos. */
91 FILE *__save_log_s;    /* if $nolog executed, value to use if log */
92 int32 __echo_iactcmds_tolog; /* T => echo interactive cmds to log file */
93 FILE *__save_key_s;    /* if $nolog executed, value to use if log */
94 int32 __nokey_seen;    /* $nokey executed and no key */
95 FILE *__in_s;
96 FILE *__log_s;
97 FILE *__cmd_s;         /* command file source or null for tty */
98 FILE *__key_s;         /* if key_s nil but key_fnam not, must open */
99 struct optlst_t *__opt_hdr;   /* header of expanded option list */
100 struct optlst_t *__opt_end;   /* wrk end of expanded option list */
101 word32 *__wsupptab;    /* tab (1 bit/msg) for warn and iact suppress */
102 char *__blnkline;      /* work blank line */
103 char __pv_homedir[RECLEN]; /* home dir - . if HOME env. not set */
104 struct mcchan_t __mulchan_tab[32];/* mc desc. tab (32 built in Ver) */
105 struct fiofd_t **__fio_fdtab; /* array of ptrs to file io stream */
106 char *__fiolp;         /* fio file input work string ptr */
107 char *__fiofp;         /* fio file input work fmt string ptr */
108 long __scanf_pos;      /* byte offset position of scanf in file */
109 sighandler *__old_int_sig;  /* value of quit (^c) signal on entry */
110 int32 __force_base;    /* for output force base if not BASENONE */
111 struct vinstk_t **__vinstk;/* open file/macro list in stack form */
112 struct vinstk_t *__visp;/* pointer to top of open input stack */
113 int32 __vin_top;       /* index of top of current file stack */
114 char *__log_fnam;      /* log file for all terminal output */
115 char *__sdf_opt_log_fnam; /* sdf log file if set by cmd arg */
116 FILE *__sdf_opt_log_s; /* and open file ptr */
117 int32 __sdf_no_warns;  /* T => don't print any SDF warning msgs */
118 int32 __sdf_no_errs;   /* T => don't print any SDF error msgs */
119 int32 __sdf_from_cmdarg; /* T => SDF annotation call from cmd option */
120 char *__cmd_fnam;      /* command interact. input file name */
121 char *__cmd_start_fnam;/* -i startup interactive input file name */
122 char *__key_fnam;      /* key file name and stream */
123 FILE *__tr_s;          /* trace output file - can be stdout */
124 char *__tr_fnam;
125 int32 __cmd_ifi;       /* constant command in_fils index */
126 char *__lic_path;      /* +licpath [path] if option used */
127 FILE *__sdf_s;         /* current SDF back annotate file/stream */
128 struct sdfnamlst_t *__sdflst; /* list of sdf annotate option files */
129 int32 __sdf_sav_enum;  /* saved error num. for annotate inhibit */
130 int32 __sdf_sav_maxerrs; /* saved max errors so won't stop */
131 int32 __has_sdfann_calls;/* T => no sdf annotate systsk calls in src */
132 int32 __sdf_active;    /* T => annotating SDF - for PLI erro code  */
133 struct mod_t *__sdf_mdp; /* special sdf context mod */
134 
135 /* cfg variables */
136 char *__cmdl_library;  /* library name to file off the command line */
137 struct mapfiles_t *__map_files_hd; /* hdr of map files from cmd args */
138 struct mapfiles_t *__map_files_tail; /* end of map file list */
139 struct cfglib_t *__cfglib_hd; /* head of list of libs for cfg */
140 struct cfglib_t *__cfglib_tail; /* and tail */
141 struct cfg_t *__cfg_hd;/* head of list of cfgs */
142 struct cfg_t *__cur_cfg;/* current cfg */
143 struct mod_t *__cfg_mdp;/* SJM - remove me - why global */
144 char **__bind_inam_comptab;/* during cfg binding, comp descent comps */
145 int32 __siz_bind_comps;/* current malloc size of table */
146 int32 __last_bind_comp_ndx;/* last currently used comp end index */
147 int32 __cfg_verbose;   /* T => emit cfg reading verbose messages */
148 
149 /* file variables */
150 int32 __cur_infi;      /* index in in_fils of current file */
151 struct optlst_t *__new_opt_hdr;/* header of expanded option list */
152 struct optlst_t *__new_opt_end;/* wrk end of expanded option list */
153 struct optlst_t *__log_olp;   /* log option, nil if none */
154 struct optlst_t *__help_olp;  /* help option, nil if none */
155 struct optlst_t *__quiet_olp; /* quiet option, nil if none */
156 struct optlst_t *__verb_olp;  /* verbose option, nil if none */
157 int32 __vpi_argc;      /* global arg count for vpi */
158 char **__vpi_argv;     /* global arg array for vpi */
159 char *__vpi_argv0;     /* argv execed program name */
160 char *__cur_fnam;      /* being read file name for errors */
161 int32 __cur_fnam_ind;  /* index in in_fils of cur_fnam */
162 int32 __sfnam_ind;     /* global file index for current stmt. */
163 int32 __slin_cnt;      /* global line no. for currently check stmt */
164 int32 __vpifnam_ind;   /* vpi_ global current file index */
165 int32 __vpilin_cnt;    /* vpi_ global current line no. */
166 struct expr_t *__srm_xp; /* current string 'file' for sreadmem */
167 char *__srm_strp;      /* char. pos. in sreadmem string */
168 char *__srm_strp_beg;  /* work alloced location for sreadmem string */
169 int32 __srm_strp_len;  /* alloced length */
170 int32 __srm_stargi;    /* current string position number */
171 int32 __in_ifdef_level;/* current processing `ifdef level */
172 int32 __ifdef_skipping;/* T = skipping not included ifdef section */
173 char *__langstr;       /* work string for `language */
174 int32 __doing_langdir; /* T => processing `language directive */
175 int32 __rding_top_level; /* T => reading outside top level construct */
176 
177 /* variables for batch tracing */
178 word64 __last_trtime;  /* last trace statement time */
179 word64 __last_evtrtime;/* last event trace time */
180 struct itree_t *__last_tritp;/* last event traced inst. itree loc. */
181 
182 /* command processing variables and temps */
183 int32 __pv_err_cnt, __pv_warn_cnt; /* error counts */
184 int32 __inform_cnt;    /* number of informs */
185 int32 __outlinpos;     /* current trunc. output line pos. */
186 long __mem_use;        /* counts allocated mem for debugging */
187 long __mem_allocated;  /* bytes allocated */
188 long __mem_freed;      /* bytes freed */
189 long __memstr_use;     /* counts allocated string mem for debugging */
190 long __arrvmem_use;    /* allocated bytes for Verilog arrays */
191 long __mem_udpuse;     /* number of bytes used by udp tables */
192 word64 __tim_zero;     /* place for time of constant 0 */
193 int32 __num_glbs;      /* total no. of globals in design */
194 int32 __num_inmodglbs; /* glbs thar resolve to intra module refs. */
195 int32 __num_uprel_glbs;/* number of upward relative globals */
196 int32 __nets_removable;/* flat no. of deletable nets */
197 int32 __flnets_removable;/* removable static nets */
198 int32 __gates_removable; /* removable static gates */
199 int32 __flgates_removable; /* flat no. of deletable gates */
200 int32 __contas_removable; /* removabale static cont. assigns */
201 int32 __flcontas_removable; /* flat no. of deletable cont. assigns */
202 
203 /* special allocate free variables */
204 struct ncablk_t *__hdr_ncablks; /* blocks used for ncomp recs */
205 int32 __ncablk_nxti;   /* index of next free pos. */
206 struct cpblk_t *__hdr_cpblks; /* blocks used for cell recs*/
207 int32 __cpblk_nxti;    /* index of next free pos. */
208 struct cppblk_t *__hdr_cppblks; /* blocks used for cell pin recs*/
209 int32 __cppblk_nxti;   /* index of next free pos. */
210 struct tnblk_t *__hdr_tnblks;  /* blocks of symb table tree nodes */
211 int32 __tnblk_nxti;    /* index of next free pos. */
212 struct cpnblk_t *__hdr_cpnblks;  /* blocks of explicit cell pnames */
213 
214 /* source processing variables */
215 int32 __lin_cnt;       /* line number while reading a file */
216 int32 __saverr_cnt;    /* counter to inhibit more than a err in xpr */
217 int32 __max_errors;    /* maximum errors before stopping */
218 int32 __rding_comment; /* flag so comment non printable chars ok */
219 int32 __total_rd_lines;/* total number of lines read */
220 int32 __total_lang_dirs; /* total num `language directives read */
221 
222 /* booleans for program options (flags) */
223 int32 __verbose;       /* T => emit various extra messages */
224 int32 __quiet_msgs;    /* T => do not emit msgs just errors */
225 int32 __no_warns;      /* T => don't print warning msgs */
226 int32 __no_errs;       /* T => don't print error msgs */
227 int32 __no_informs;    /* T => don't print inform msgs (dflt) */
228 int32 __debug_flg;     /* T => turn on debugging output */
229 int32 __opt_debug_flg; /* T => turn on vm compiler debugging output */
230 int32 __st_tracing;    /* T => trace statement execution */
231 int32 __ev_tracing;    /* T => trace event schedules and processes */
232 int32 __pth_tracing;   /* T => trace path delays in detail */
233 int32 __prt_stats;     /* T => print design statics tables */
234 int32 __prt_allstats;  /* T => print design and mod content tabs */
235 int32 __show_cancel_e; /* T => chg val to x on pulse cancelled event */
236 int32 __showe_onevent; /* T => if showing cancel e, drive x on event */
237 int32 __warn_cancel_e; /* T => emit warn cancel_e (indep. of cancel) */
238 int32 __rm_gate_pnd0s; /* T => remove #0 from all gates */
239 int32 __rm_path_pnd0s; /* T => (default) remove all 0 delay paths */
240 int32 __dmpvars_all;   /* T => dumpvars all variables */
241 
242 /* command option booleans */
243 int32 __lib_verbose;   /* T => emit src.file/lib source messages */
244 int32 __sdf_verbose;   /* T => emit msgs for SDF annotated delays */
245 int32 __switch_verbose;/* T => emit msgs for switch/tran chan build */
246 int32 __chg_portdir;   /* T => chg port dir to bid. for XL compat */
247 int32 __nb_sep_queue;  /* F => old un-seperated nb in pnd0 queue */
248 int32 __decompile;     /* T => decompile and print Verilog source */
249 int32 __compile_only;  /* T => check syntax (inc. lib.) no quads */
250 int32 __parse_only;    /* T => first pass parse only to chk sep mod */
251 int32 __dflt_ntyp;     /* Verilog wire type for normal nets */
252 int32 __mintypmax_sel; /* for (e:e:e) expressions value to use */
253 int32 __sdf_mintypmax_sel; /* min:nom_max over-ride for $sdf_annotate */
254 int32 __gateeater_on;  /* T => attempt to remove (disconnect) gates */
255 int32 __no_expand;     /* T => make all wire vectors vectored */
256 int32 __in_cell_region;/* T => turn on cell bit for every module */
257 int32 __unconn_drive;  /* if none TOK_NONE else PULL 0 or PULL 1 */
258 int32 __no_specify;    /* T => check but no simulate with specify */
259 int32 __no_tchks;      /* T => check but no simulate with tim chks */
260 int32 __lib_are_cells; /* T => if in lib, the mark as cell (dflt.) */
261 int32 __design_has_cells;/* T => cells somewhere in design */
262 int32 __accelerate;    /* T => use short circuits g/prt code if can */
263 int32 __pli_keep_src;  /* T => keep more source stmt info for pli */
264 int32 __use_impthdels; /* T => use src-dst im path dels */
265 
266 /* source input variables and temps */
267 char __lasttoken[IDLEN];/* current last pushed back symbol name */
268 char __token[IDLEN];   /* current symbol (in canonical (lc) form) */
269 int32 __toktyp;        /* place for current toktyp value */
270 int32 __lasttoktyp;    /* push back token type (= UNDEF if none) */
271 int32 __last_attr_prefix;/* push back pending attr prefix state */
272 int32 __itoklen;       /* current number token bit length */
273 int32 __itoksized;     /* T => token is sized */
274 int32 __itokbase;      /* base constant for number token */
275 int32 __itoksizdflt;   /* '[base] form with width (uses dflt.) */
276 int32 __itok_signed;   /* T => token is signed number */
277 double __itok_realval; /* actual scannoer double val */
278 char *__strtoken;      /* growable token to hold string */
279 int32 __strtok_wid;    /* current size of string token */
280 char *__numtoken;      /* growable token to hold numbers */
281 int32 __numtok_wid;    /* current size of number token */
282 int32 __letendnum_state; /* T => letter can end unsized num. */
283 int32 __macro_sep_width; /* T => possible beginning of macro 2 tok num */
284 int32 __maybe_2tok_sized_num; /* T => seeing number after macro num */
285 int32 __macro_sav_nwid;/* value of saved first tok width */
286 int32 __first_linetok; /* T => token first on line */
287 int32 __file_just_op;  /* T => new file and no token yet returned */
288 int32 __first_num_eol; /* T => first tok because number ended line */
289 char *__macwrkstr;     /* work string for macros */
290 int32 __mac_line_len;  /* actual length of macro line in wrk str */
291 int32 __macwrklen;     /* allocated len of mac. work string */
292 struct macarg_t *__macarg_hdr; /* hdr of list of format mac. args */
293 int32 __macbs_flag;    /* T=> 8'h`DEFINE catch multiple bases errors */
294 char *__attrwrkstr;    /* work string for attributes */
295 int32 __attr_line_len; /* actual length of attribute string */
296 int32 __attrwrklen;    /* alloced len of attr work string - grows */
297 char *__attrparsestr;  /* string to parse attr out of */
298 int32 __attrparsestrlen; /* string to parse attr out of */
299 int32 __attr_prefix;   /* T => token has attribute prefix */
300 int32 __attr_fnam_ind; /* location of attr inst. */
301 int32 __attr_lin_cnt;  /* location of attr inst. */
302 struct attr_t __wrk_attr; /* latest read attribute */
303 char *__xs, *__xs2;    /* places to put expr to str trunc messages */
304 int32 __pv_ctv;        /* tmp for white space skipping macros */
305 int32 __syncto_class;  /* token class sync skipping halted at */
306 char *__exprline;      /* expr. output line work string */
307 int32 __exprlinelen;   /* expr. line length */
308 int32 __cur_sofs;      /* ndx of next ofs (position) in expr line */
309 word32 *__acwrk;       /* a value work string for scanning number */
310 word32 *__bcwrk;       /* b value work string for scanning number */
311 word32 __addrtmp[2];   /* up to 32 bit temp with addr. */
312 int32 __abwrkwlen;     /* current acwrk a half length in words */
313 char __portnam[IDLEN];
314 char __pv_varnam[IDLEN]; /* variable name */
315 int32 __expr_is_lval;  /* T => parsing proc. assign lhs */
316 int32 __allow_scope_var; /* T => process systask arg can be scope */
317 
318 /* vars needed for pushing back numbers (see var. comment) */
319 int32 __lastitokbase;
320 int32 __lastitoksized;
321 int32 __lastitoksizdflt;
322 int32 __lastitok_signed;
323 int32 __lastitoklen;
324 word32 *__lastacwrk;   /* special malloced push back num value */
325 word32 *__lastbcwrk;
326 double __lastitok_realval;
327 
328 /* the module and module subtask specific work variables */
329 struct mod_t *__oinst_mod;/* ptr. to old current module for copying */
330 struct mod_t *__end_mdp; /* end of module def. list */
331 struct cell_t *__end_cp; /* end of module inst. list */
332 int32 __cp_num;          /* counter for unnamed gate/inst pos. */
333 struct conta_t *__end_ca; /* end of module conta list */
334 int32 __conta_num;     /* counter for building symbol for conta */
335 struct varinitlst_t *__end_mod_varinitlst; /* end of mod var inits */
336 struct symtab_t *__tfcall_wrksytp;/* wrk tf tab for undecl xmr uprel */
337 
338 struct dfparam_t *__end_dfp;/* module current end of defparam list */
339 struct task_pin_t *__end_tpp; /* end of task port list */
340 struct task_t *__end_tbp;/* end of top level task/functions/blocks */
341 struct task_t *__cur_tsk;/* ptr. to current task */
342 struct net_t *__end_paramnp; /* end of ordered parm decl. list */
343 struct net_t *__end_loc_paramnp; /* end of ordered parm loc decl. list */
344 struct net_t *__end_impparamnp; /* end of ordered imprt parm decl lst */
345 struct net_t *__end_glbparamnp; /* end of ordered glb parm decl. lst */
346 struct net_t *__end_tskparamnp; /* end of task param decl. list */
347 struct net_t *__end_tsk_loc_paramnp; /* end of task param decl. list */
348 struct ialst_t *__end_ialst; /* end of module initial/always list */
349 struct gref_t *__grwrktab;  /* work table for building mod glbs */
350 int32 __grwrktabsiz;        /* its size */
351 int32 __grwrknum;      /* current number of glbs in work table */
352 int32 __cur_declobj;   /* token type of declared mod or task */
353 int32 __pv_stlevel;    /* tmp. for current stmt nesting level */
354 int32 __design_no_strens;/* T => no strengths used in design */
355 int32 __strenprop_chg; /* during propagate pass at least one chged */
356 int32 __splitting;     /* T => in process of splitting module */
357 int32 __processing_pnd0s;/* T => in time unit, in end #0 region */
358 struct dce_expr_t *__cur_dce_expr; /* glb for edge events eval expr */
359 int32 __lofp_port_decls; /* T => exclusive hdr port decls appeared */
360 struct exprlst_t *__impl_evlst_hd; /* hdr of impl @(*) ev expr list */
361 struct exprlst_t *__impl_evlst_tail; /* and its tail */
362 int32 __canbe_impl_evctrl; /* glb switch to allow @(*) as ev ctrl */
363 
364 /* variables for dumpvars */
365 int32 __dv_seen;       /* dumpvars seen but not yet setup */
366 int32 __dv_state;      /* processing state of dumpvars */
367 word64 __dv_calltime;  /* time dump var. first (and only) called */
368 int32 __dv_dumplimit_size; /* user set limit of dv file size (0 none) */
369 int32 __dv_file_size;  /* current size of dumpvars file */
370 int32 __dv_time_emitted; /* flag to stop repeated same #[time] */
371 char *__dv_fnam;       /* name of dumpvars output file */
372 int32 __dv_func;       /* global set with type of dumpvar dumping */
373 struct mdvmast_t *__dv_hdr; /* hdr of mast dumpvar rec. list */
374 struct mdvmast_t *__dv_end; /* end of dumpvar rec. list */
375 struct dvchgnets_t *__dv_netfreelst; /* free list of time var chges */
376 int32 __dv_fd;         /* file number of dmpvars fd */
377 char *__dv_buffer;     /* buffer to speed up dumpvars output */
378 int32 __dv_nxti;       /* next free location */
379 int32 __dv_outlinpos;  /* line postion in dump vars file */
380 int32 __next_dvnum;    /* highest so far used dumpvars number */
381 struct dvchgnets_t *__dv_chgnethdr;  /* curr. time var chg list hdr */
382 int32 __dv_isall_form; /* T doing all of design dumpvar setup */
383 int32 __dv_allform_insrc;/* T dumpvars all form in source */
384 
385 /* time scale - precision variables */
386 word32 __cur_units;    /* current units (0 (1s) - 15 (1ft) */
387 word32 __cur_prec;     /* current digits of precision (0-15) */
388 word32 __des_timeprec; /* assume -, 0-15 design sim. tick prec. */
389 word32 __tfmt_units;   /* %t output units (also interact. units) */
390 word32 __tfmt_precunits;/* %t number of prec. digits */
391 int32 __des_has_timescales;/* T => design has at least one timescale */
392 char *__tfmt_suf;      /* suffix for %t */
393 int32 __tfmt_minfwid;  /* minimum field width for %t */
394 word64 __itoticks_tab[16];/* table of scales amount from prec. */
395 char __timstr_unitsuf[4];/* to_timstr units suffix if needed */
396 word64 __timstr_mult;  /* multiplier if needed */
397 int32  __nd_timstr_suf;/* T => need to_timstr units */
398 
399 /* veriusertfs pli user function and task work variables */
400 /* SJM 07/16/02 - need internal veriuser tfs for new +loadpli1 option */
401 struct t_tfcell *__shadow_veriusertfs; /* internal copy of table */
402 int32 __last_veriusertf; /* last user veriusertfs tf number */
403 struct tfinst_t *__tfinst;/* current tf_ inst loc. */
404 struct tfrec_t *__tfrec;/* current tf_ record */
405 struct dceauxlst_t *__pvc_dcehdr; /* header of current pvc dces */
406 struct tfrec_t *__tfrec_hdr; /* header of design wide tfrec list */
407 struct tfrec_t *__tfrec_end; /* last el of design wide tfrec list */
408 i_tev_ndx __tehdr_rosynci; /* hdr ndx of slot end ro sync ev lst */
409 i_tev_ndx __teend_rosynci; /* end of slot end ro sync ev lst */
410 int32 __now_resetting; /* reset in progress - for cbs and misctf */
411 int32 __rosync_slot;   /* T => processing tf or vpi  ro synch events */
412 struct loadpli_t *__pli1_dynlib_hd; /* hd of ld pli1 dynamic lb list */
413 struct loadpli_t *__pli1_dynlib_end; /* and its end */
414 
415 /* vpi_ work variables */
416 int32 __last_systf;    /* last vpi_ registered sytfs number */
417 int32 __num_vpi_force_cbs; /* number of registered vpi force cbs */
418 int32 __vpi_force_cb_always; /* T => always call back on force */
419 int32 __num_vpi_rel_cbs; /* number of registered vpi rel cbs */
420 int32 __vpi_rel_cb_always; /* T => always call back on release */
421 int32 __allforce_cbs_off; /* T => can't reenter any of all force cbs */
422 int32 __allrel_cbs_off;/* T => can't reenter any of all release cbs */
423 char *__wrks1;         /* work string - can not use xs if func */
424 char *__wrks2;
425 char __wrk_vpiemsg[IDLEN];/* error msg. work string */
426 char __wrk_vpiget_str[IDLEN];/* standard required vpi get str string */
427 char __wrk_vpi_product[256];/* product version */
428 char __wrk_vpi_errcode[256];/* error codes are Cver err num as str */
429 double __wrk_vpi_timedbl;/* time double for vpi error rec */
430 char *__wrkvalbufp;    /* buf for vpi get value value_p contents */
431 int32 __wrkval_buflen; /* and current length */
432 int32 __vpi_vlog_start_done;/* T => startup done, no systf registering */
433 struct systftab_t *__systftab; /* table of vpi_ systf records */
434 int32 __size_systftab; /* current size of systf data rec. table */
435 struct xstk_t *__cur_sysf_xsp; /* tmp stk_t for vpi sysf ret val */
436 struct expr_t *__cur_sysf_expr;/* tmp calling expr. for vpi sysf*/
437 struct st_t *__cur_syst_stp; /* tmp stmt for vpi syst*/
438 struct dceauxlst_t *__cbvc_dcehdr; /* header of current vc cb dces */
439 struct rfcblst_t *__rel_allcb_hdr;
440 struct rfcblst_t *__rel_allcb_end;
441 struct rfcblst_t *__force_allcb_hdr;
442 struct rfcblst_t *__force_allcb_end;
443 i_tev_ndx *__vpicb_tehdri; /* hdr of fixed cb tev list - 1 per class */
444 i_tev_ndx *__vpicb_teendi; /* end of fixed cb tev list - 1 per class */
445 int32 __have_vpi_actions;/* some use of __vpi actions */
446 int32 __have_vpi_gateout_cbs;/* some use of gate out term cbs */
447 struct h_t *__vpi_hfree_hdr;  /* handle free list hdr */
448 struct hrec_t *__vpi_hrecfree_hdr;  /* handle record free list hdr */
449 struct cbrec_t *__vpi_cbrec_hdr; /* all cbs list header */
450 int32 __ithtsiz;       /* size of global work ld/drv handle table */
451 struct h_t *__ithtab;  /* and the work ld/drv handle table */
452 struct hrec_t *__ithrectab; /* and hrec contents of it */
453 int32 __ithtsiz2;      /* size of global work ld/drv handle table */
454 struct h_t *__ithtab2; /* 2nd work for in subtree handles */
455 struct hrec_t *__ithrectab2; /* and hrec contents of it */
456 struct vpisystf_t *__vpi_sysf_hdr; /* hdr sys func call src locs */
457 struct vpisystf_t *__vpi_syst_hdr; /* hdr sys task enable src locs */
458 int32 __in_vpi_errorcb;/* T => if sim ctrl, suppress error msg error */
459 int32 __vpierr_cb_active; /* T => at least one cbError reged */
460 int32 __acc_vpi_erroff;/* acc_ flag to stop internal acc_ error cbs */
461 int32 __errorcb_suppress_msg; /* T => sim control suppress error msg */
462 struct h_t *__cur_vpi_inst;
463 struct hrec_t *__cur_vpi_obj;
464 struct loadpli_t *__vpi_dynlib_hd; /* hd of ld vpi dynamic lib list */
465 struct loadpli_t *__vpi_dynlib_end; /* and its end */
466 struct dcevnt_t *__cbvc_causing_dcep; /* glb for vc cb if it is remed */
467 
468 /* specify work variables */
469 struct spfy_t *__cur_spfy;/* current specify block */
470 struct spcpth_t *__end_spcpths; /* end of specify path st. list */
471 int32 __path_num;      /* counter for unnamed paths */
472 struct tchk_t *__end_tchks;/* end of specify time check st. list */
473 struct net_t *__end_msprms;/* end of specify specparam net list */
474 struct tchk_t *__cur_tchk;
475 int32 __tchk_num;      /* counter for unnamed paths */
476 struct symtab_t *__sav_spsytp;/* save loc. of sym tab in spfy sect. */
477 
478 /* work compile global variables accessed by routines */
479 int32 __v1stren;       /* wire/inst. Ver. 1 strength */
480 int32 __v0stren;       /* wire/inst. Ver. 0 strength */
481 word32 __pr_iodir;     /* glb. for port ref. expr. I/O direction */
482 int32 __pr_wid;        /* global for total port ref. expr. width */
483 int32 __mpref_explicit;/* T => mod def header port ref explicit */
484 int32 __sym_is_new;    /* set when new symbol added */
485 struct sy_t **__wrkstab;/* malloced work symbol table area */
486 int32 __last_sy;       /* last symbol in work area */
487 int32 __mod_specparams;/* number of declared specparams in mod */
488 int32 __name_assigned_to;/* glb set if func. def. name assigned to */
489 struct sy_t *__locfnamsyp; /* place for func. def. chk func. symbol */
490 int32 __processing_func; /* T => prep or exec of function occuring */
491 struct st_t **__nbstk; /* func. nest nblock stack (nxt for exec) */
492 int32 __nbsti;
493 struct sy_t *__ca1bit_syp; /* gmsym for 1 bit conta converted gate */
494 int32 __chking_conta;  /* T => checking a continuous assignment */
495 int32 __rhs_isgetpat;  /* T => flag for checking stylized getpat */
496 int32 __lhs_changed;   /* T => assignment changed lhs */
497 word32 __badind_a;     /* place for a part of in error index value */
498 word32 __badind_b;     /* and for b part */
499 int32 __badind_wid;    /* width for bad ind (<32 expr can eval to x) */
500 int32 __expr_has_real; /* T => know some real in expr. */
501 int32 __isform_bi_xvi; /* glbl for IS net pin bit index in contab */
502 int32 __lhsxpr_has_ndel; /* T => component wire of lhs has wire del */
503 int32 __checking_only; /* T => no error msg, looking for something */
504 int32 __task_has_tskcall;/* T => task calls other task (not name blk) */
505 int32 __task_has_delay;/* T => task call has del. needs thread */
506 int32 __func_has_fcall;/* T => func contains has non sys fcall */
507 int32 __iact_must_sched; /* T => iact stmt(s) have $stop or loop */
508 int32 __expr_rhs_decl; /* T current expr. is decl. not proc. rhs */
509 int32 __chg_rng_direct;/* T => change rng dir. for implicitly decl */
510 int32 __has_top_mtm;   /* T => for parameter rhs non () m:t:m */
511 int32 __nd_0width_catel_remove; /* fx3 file 0 width concat glb */
512 
513 /* current Verilog module/task/block symbol environment */
514 struct symtab_t **__venviron;
515 int32 __top_sti;
516 struct symtab_t *__modsyms;/* separate symbol table for type names */
517 struct symtab_t *__pv_defsyms;/* global table for `defines */
518 struct symtab_t *__syssyms;/* global tab for system tasks and funcs */
519 struct sy_t **__glbsycmps; /* work global name symbols */
520 struct expr_t **__glbxcmps;/* work glbal exprs */
521 int32 __last_gsc;
522 
523 /* n.l. access headers and tables */
524 struct mod_t *__modhdr;/* header of top level module list */
525 struct udp_t *__udphead; /* header udps */
526 struct udp_t *__udp_last;/* end udp list */
527 struct inst_t **__top_itab; /* tab of virt inst ptrs of top mods */
528 int32 *__top_ipind;    /* binary searchable top insts index */
529 int32 __numtopm;       /* number of uninstanciated top modules */
530 struct itree_t **__it_roots; /* table of root itree entries */
531 int32 __ualtrepipnum;  /* udp rep. change threshold */
532 struct thread_t *__initalw_thrd_hdr; /* list hd of per inst in/al thds */
533 struct tev_t *__tevtab;/* reallocable tab of events and free evs */
534 int32 __numused_tevtab;/* num used at least once in tev tab */
535 int32 __size_tevtab;   /* num tev's allocated in tev tab */
536 word32 *__contab;      /* design wide constant table */
537 int32 __contabwsiz;    /* currrent size of const tab in words */
538 int32 __contabwi;      /* next free word32 slot in const tab */
539 int32 __opempty_contabi; /* special contab ndx for opempty expr leaf */
540 struct contab_info_t **__contab_hash; /* contab hash information */
541 
542 /* n.l. access routines */
543 struct dfparam_t *__dfphdr; /* design wide defparam list header */
544 int32 __num_dfps;      /* number of defparams in source */
545 int32 __num_glbdfps;   /* number of defparams in design */
546 int32 __num_locdfps;   /* number of local defparams */
547 int32 __num_inst_pndparams;/* static number of inst. pound params */
548 int32 __design_gia_pndparams;/* T => at least one gia range pnd params */
549 int32 __design_gi_arrays;  /* T => design has arrays of g/i */
550 int32 __pndparam_splits; /* T => at least one split from pound params */
551 int32 __defparam_splits; /* T => at least one split from def params */
552 int32 __dagmaxdist;    /* max. nested mod. inst. level */
553 struct mod_t **__mdlevhdr; /* array of ptrs to ith lev linked mods */
554 struct cell_pin_t *__cphdr;   /* header of temp. cell pin list */
555 struct cell_pin_t *__cpp_last;/* current last cell pin*/
556 struct tnode_t *__tmp_head;
557 
558 struct xldlnpp_t *__xldl_hdr; /* other side unproc. xl drv/ld npps */
559 struct xldlnpp_t *__last_xldl;/* end of list - place to add after */
560 struct xldlvtx_t **__xldlvtxind; /* table of xl drv/ld net/bit vtx */
561 int32 __num_xldlvtxs;  /* number of lements in table */
562 int32 __siz_xldlvtxtab;/* current size of table */
563 
564 /* udp table building variables */
565 struct wcard_t *__wcardtab; /* level wildcard table */
566 int32 __last_wci;      /* last wild card index for line */
567 word32 *__cur_utab;    /* current udp table */
568 struct utline_t *__cur_utlp; /* current line info struct */
569 word32 __cur_uoval;    /* current udp line output value */
570 int32 __cur_unochange; /* T => cur line has '-' no change output */
571 struct udp_t *__cur_udp; /* current udp struct */
572 word32 __cur_upstate;  /* current last input (state) for wide */
573 int32 __cur_ueipnum;   /* cur. input pos. num of edge (NO_VAL none) */
574 int32 __cur_utabsel;   /* current edge 1st char - 2nd in state line */
575 
576 /* expression and function processing variables */
577 int32 __xndi;          /* next place in collected expression list */
578 struct expr_t **__exprtab;/* table to collect expressions into */
579 struct expridtab_t **__expr_idtab; /* expr parse id name info */
580 int32 __exprtabsiz;    /* current operator precedence expr tab siz */
581 int32 __last_xtk;
582 struct expr_t *__root_ndp;/* root of built and alloced expression */
583 struct xstk_t **__xstk;/* expr work vals */
584 int32 __xspi;          /* expr. pointer */
585 int32 __maxxnest;      /* current size of expr. stack - must grow */
586 int32 __maxfcnest;     /* size of func. call task stk - must grow */
587 struct task_t **__fcstk; /* function call nesting stack */
588 int32 __fcspi;           /* fcall tos index */
589 
590 /* -y and -v library variables */
591 struct vylib_t *__vyhdr; /* header of lib. file list */
592 struct vylib_t *__end_vy;/* last entry on vy lib. list */
593 int32 __num_ylibs;     /* number of ylibs in options */
594 int32 __num_vlibs;     /* number of vlibs in options */
595 
596 struct undef_t *__undefhd;/* head of undefined mod/udp list */
597 struct undef_t *__undeftail; /* tail of undefined mod/udp list */
598 int32 __undef_mods;    /* count of undefined modules */
599 
600 int32 __lib_rescan;    /* T => rescan from start after each */
601 int32 __cur_passres;   /* num mods resolved in current pass */
602 int32 __rescanning_lib;/* T => for `language exclude after 1st pass */
603 int32 __num_ys;        /* number of -y options in lib. */
604 char **__lbexts;       /* tab of -y library extension suffixes */
605 int32 __last_lbx;
606 char **__incdirs;      /* tab of +incdir paths (always / end) */
607 int32 __last_incdir;
608 
609 /* simulation preparation variables */
610 int32 __cur_npii;      /* current index of inst. in cur. mod */
611 struct gate_t *__cur_npgp;/* current net-pin processing gate */
612 struct mod_t *__cur_npmdp;/* current net-pin processing module */
613 struct conta_t *__cur_npcap; /* current net pin proc. conta */
614 struct tfrec_t *__cur_nptfrp; /* current net pin tf arg drvr rec */
615 struct net_t *__cur_npnp; /* current net pin net for vpi putv driver */
616 int32 __cur_npnum;     /* current port number (from 0) */
617 int32 __cur_pbi;       /* current bit number for PB ICONN npp */
618 int32 num_optim_cats;  /* number of optimized concats */
619 int32 num_optim_catels;/* number of all elements in optim concats */
620 int32 __cur_lhscati1;  /* if lhs concat, high rhs psel index */
621 int32 __cur_lhscati2;  /* if lhs concat, low rhs psel index */
622 struct st_t **__prpstk;/* during prep., continue stp */
623 int32 __prpsti;        /* top of nested stmt. stack */
624 int32 __nd_parmpnp_free; /* T => after 1st parmnpp need copy not orig */
625 int32 __num_rem_gate_pnd0s; /* number of removed source #0 gates */
626 int32 __num_flat_rem_gate_pnd0s; /* and flat number */
627 int32 __num_rem_mipds; /* number of per bit flat MIPDs 0 delays rmed */
628 int32 __last_modxi;    /* global counter used by n.l expr xform code */
629 int32 __last_modsti;   /* and counter for statements */
630 int32 __optimized_sim; /* generate c code - compile and dl link */
631 int32 __dump_flowg;    /* dump flow graph for debugging */
632 
633 /* timing queue scheduling variables */
634 word64 __whetime;      /* current timing wheel end time */
635 word64 __simtime;      /* current simulaton time (make 64 bits ?) */
636 word32 __num_execstmts;/* total number of executed statements */
637 word32 __num_addedexec;/* number of executed added statements */
638 word32 __num_proc_tevents;/* total num simulation events processed */
639 word32 __nxtstmt_freq_update; /* next ev count for xbig freq upd. */
640 word32 __num_cancel_tevents; /* total num sim events processed */
641 int32 __num_twhevents; /* num of evs currently in timing wheel */
642 int32 __num_ovflqevents; /* num of events currently in ovflow q */
643 word32 __inertial_cancels; /* num resched form later inertial del */
644 word32 __newval_rescheds; /* num rescheduled for same time */
645 word32 __num_netchges; /* num of processed net change records */
646 word32 __immed_assigns;/* num immed assign (not scheduled) */
647 word32 __proc_thrd_tevents;/* number of processed thread events */
648 struct q_hdr_t *__qlist_hdr; /* for $q_ system task q list header */
649 int32 __num_switch_vtxs_processed; /* total num tranif chan vtx done */
650 int32 __num_switch_chans; /* total num tranif channels in design */
651 
652 /* storage tables variables */
653 byte *__btab;          /* design wide scalar (byte) storage table */
654 int32 __btabbsiz;      /* scalar storage byte table size in bytes */
655 int32 __btabbi;        /* during var init next index to use */
656 byte *__nchgbtab;      /* table for per inst nchg bytes */
657 int32 __nchgbtabbsiz;  /* size in btab of nchg action bits */
658 int32 __nchgbtabbi;    /* during init, next index to use */
659 word32 *__wtab;        /* design wide var but not mem storage area */
660 int32 __wtabwsiz;      /* precomputed size (need ptrs into) in words */
661 int32 __wtabwi;        /* during var init next index to use */
662 
663 /* simulation control and state values */
664 int32 __stmt_suspend;  /* set when behavioral code suspends */
665 int32 __run_state;     /* state of current simulation run */
666 int32 __can_exec;      /* T => for vpi sim ctrl - can now exec */
667 int32 __wire_init;     /* T => initializing wires */
668 int32 __no_tmove_levels; /* T => infinite 0 delay loop warn path dist */
669 struct thread_t *__cur_thd;  /* currently executing thread addr. */
670 struct thread_t *__suspended_thd; /* cur thread before suspend */
671 struct itree_t *__suspended_itp; /* cur inst ptr before suspend */
672 struct itree_t *__inst_ptr; /* current if flattened itree place */
673 struct mod_t *__inst_mod;   /* module of current itree inst */
674 int32 __inum;          /* iti num  of current inst (always set) */
675 struct itree_t **__itstk; /* stack of saved itrees */
676 int32 __itspi;         /* top of itree stack */
677 i_tev_ndx __fsusp_tevpi;/* in func. step, event to undo(cancel) */
678 struct itree_t *__tmpitp_freelst; /* free list of wrk itps */
679 struct inst_t *__tmpip_freelst; /* free list of wrk ips */
680 struct mod_t *__last_libmdp; /* libary module just read */
681 int32 __seed;          /* SJM 01/27/04 - glb seed needed if no arg */
682 
683 /* execution state variables */
684 word32 __new_gateval;  /* new gate out val (st. possible) */
685 word32 __old_gateval;  /* before gate change (st. possible) */
686 word32 __new_inputval; /* new input value for tracing message */
687 word32 __old_inputval; /* prev. value of input for wide udp eval */
688 word64 __pdlatechgtim; /* for path tracing latest path chg time */
689 word64 __pdmindel;     /* for path minimum path delay */
690 int32 __nd_neg_del_warn; /* T => must emit warn (or err) for <0 del */
691 int32 __force_active;  /* T => for trace deassign while force */
692 int32 __assign_active; /* T => for trace release activates assgn */
693 struct dceauxlst_t *__qcaf_dcehdr; /* header of current qcaf dces */
694 int32 __nxt_chan_id;   /* cnter and size for assigning chan ids */
695 int32 __chanallocsize; /* size of allocated chan tables */
696 struct chanrec_t *__chantab;/* tab of channel records (one per id) */
697 struct vtxlst_t *__stvtxtab[8]; /* per stren value vertex list */
698 struct vtxlst_t *__stvtxtabend[8]; /* and ptr to last el on each */
699 struct vtxlst_t *__chg_vtxlst_hdr; /* list of chged vertices to store */
700 struct vtxlst_t *__chg_vtxlst_end; /* and ptr to end */
701 struct vtxlst_t *__off_vtxlst_hdr; /* bid chan vtx list for marks off */
702 struct vtxlst_t *__off_vtxlst_end; /* and ptr to end */
703 struct vtxlst_t *__vtxlst_freelst; /* free list for vtx lists */
704 struct vtx_t *__vtx_freelst;  /* free list for re-using vtxs */
705 struct edge_t *__edge_freelst; /* free list for re-using edges */
706 
707 word32 __acum_sb;      /* accumulator for stren tran chan combined */
708 word32 __acum_a;       /* accumulator for tran chan non stren */
709 word32 __acum_b;
710 byte *__acum_sbp;      /* ptr to stacked strength byte */
711 struct xstk_t *__acum_xsp; /* ptr to stacked strength byte */
712 
713 /* end of time slot variables, strobe, monitor, time check */
714 struct strblst_t *__strobe_hdr; /* list strobe display at slot end */
715 struct strblst_t *__strobe_end; /* end of strobe display list */
716 struct strblst_t *__strb_freelst; /* head of free strobe elements */
717 struct st_t *__monit_stp;/* monit if chg display at slot end stmt */
718 struct itree_t *__monit_itp; /* current monitor itree element */
719 word32 __slotend_action; /* word32 of 1 bit switches set for action */
720 int32 __monit_active;  /* T => monitor can trigger (default) */
721 struct dceauxlst_t *__monit_dcehdr; /* header of current dces */
722 struct fmonlst_t *__fmon_hdr; /* list of execed (enabled) fmonitors */
723 struct fmonlst_t *__fmon_end;
724 struct fmonlst_t *__cur_fmon; /* current fmon list entry */
725 struct fmselst_t *__fmonse_hdr; /* this slot end fmon eval list */
726 struct fmselst_t *__fmonse_end;
727 struct fmselst_t *__fmse_freelst; /* fmon slot end free list head */
728 
729 /* interactive execution variables */
730 struct itree_t *__scope_ptr; /* from $scope itree place */
731 struct task_t *__scope_tskp; /* from $scope task if present */
732 struct symtab_t *__last_iasytp; /* last found symbol symbol table */
733 struct iahist_t *__iahtab;/* table of history commands */
734 int32 __iahsiz;        /* current size of history cmd table */
735 int32 __iah_lasti;     /* current (latest) command */
736 struct hctrl_t *__hctrl_hd; /* head of active iact stmts */
737 struct hctrl_t *__hctrl_end;/* and end */
738 int32 __history_on;    /* collecting and saving history is on */
739 int32 __hist_cur_listnum;/* number to list for :history command */
740 int32 __iasetup;       /* F until interactive entered */
741 int32 __ia_entered;    /* F (also for reset) until iact entered */
742 int32 __iact_state;    /* T => in interactive processing */
743 int32 __iact_can_free; /* T => non monitor/strobe, can free */
744 int32 __no_iact;       /* T => no interactive processing for run */
745 int32 __intsig_prt_snapshot; /* T => on no iact end, print shapshot */
746 int32 __reset_count;   /* count of the number of rests ($reset) */
747 int32 __reset_value;   /* 2nd $reset value preserved after reset */
748 int32 __list_cur_ifi;  /* index in in fils of current source file */
749 int32 __list_cur_fd;   /* current opened file no. (-1 if none) */
750 int32 __list_cur_lini; /* current line no. in current dbg file */
751 int32 __list_cur_listnum;/* number of lines to list at once */
752 int32 __list_arg_lini; /* for :b (:ib), user list argument */
753 int32 __iact_scope_chg;/* T => always move scope to cur on iact st. */
754 struct brkpt_t *__bphdr;/* header of breakpoint list */
755 int32 __nxt_bpnum;     /* next breakpoint number to use */
756 struct dispx_t *__dispxhdr;/* header of display list */
757 int32 __nxt_dispxnum;  /* next display number to use */
758 struct itree_t *__last_stepitp;/* last step inst. itree loc. */
759 struct task_t *__last_steptskp;/* last step task */
760 int32 __last_stepifi;  /* last step in fils index */
761 word64 __last_brktime; /* last break or step time */
762 int32 __dbg_dflt_base; /* :print debugger default base */
763 int32 __iact_stmt_err; /* T => syntax error for iact stmt */
764 struct mod_t *__iact_mdp; /* current iact dummy module */
765 int32 __sav_mtime_units; /* prep of iact statements needs tfmt units */
766 
767 /* interactive variables */
768 char *__iahwrkline;    /* interactive command line work area */
769 int32 __iahwrklen;     /* allocated len of iah work string */
770 int32 __pending_enter_iact;/* T => enter iact as soon as can */
771 int32 __iact_reason;   /* reason for entering interactive state */
772 int32 __single_step;   /* T => need to single step */
773 int32 __step_rep_cnt;  /* number of times to repeat step */
774 int32 __step_from_thread;/* T step from non thread loc. (^c?) */
775 struct itree_t *__step_match_itp; /* for istep, exec itp must match */
776 int32 __step_lini;     /* line stepping from (must step to next) */
777 int32 __step_ifi;      /* and file */
778 int32 __verbose_step;  /* T => emit location each step */
779 int32 __stop_before_sim; /* T => enter interactive before sim */
780 int32 __dbg_stop_before; /* if >100, T (-100) stop before sim */
781 struct st_t *__blklast_stp; /* stmt loc. saved last stmt in block */
782 struct dceauxlst_t *__iact_dcehdr; /* header of current iact dces */
783 
784 /* event list variables */
785 struct telhdr_t **__twheel;
786 int32 __twhsize;       /* current size for timing wheel */
787 int32 __cur_twi;
788 i_tev_ndx __p0_te_hdri;/* pound 0 event list header */
789 i_tev_ndx __p0_te_endi;/* pound 0 event list end */
790 i_tev_ndx __cur_te_hdri;
791 i_tev_ndx __cur_tevpi; /* ptr to event list for adding to front */
792 i_tev_ndx __cur_te_endi;
793 i_tev_ndx __tefreelsti;/* free list for events */
794 struct tedputp_t *__tedpfreelst; /* tf_ putp rec free list header */
795 struct teputv_t *__teputvfreelst; /* vpi_ put value free list hdr */
796 struct nchglst_t *__nchgfreelst; /* change element free list */
797 struct tc_pendlst_t *__tcpendfreelst; /* free slot end changed tchks */
798 struct dltevlst_t *__dltevfreelst; /* pend double event free list */
799 struct tevlst_t *__ltevfreelst; /* pend event free list */
800 i_tev_ndx __nb_te_hdri; /* non-blocking new end queue hd */
801 i_tev_ndx __nb_te_endi; /* and tail */
802 
803 /* net change list variables */
804 struct nchglst_t *__nchg_futhdr; /* header of future net chg list */
805 struct nchglst_t *__nchg_futend; /* end (for add) of future net chgs */
806 struct tc_pendlst_t *__tcpendlst_hdr; /* header of pending */
807 struct tc_pendlst_t *__tcpendlst_end; /* end of pending */
808 i_tev_ndx *__wrkevtab; /* for exit, trace of pending events */
809 int32 __last_wevti;    /* last filled */
810 int32 __size_wrkevtab; /* and current allocated size */
811 
812 /* b tree variables */
813 struct bt_t *__btqroot;/* root of timing overflow q */
814 /* for fringe node, node previous to place where inserted */
815 /* storage for path to fringe - node passed thru if not fringe */
816 struct bt_t **__btndstk; /* nodes with node list length */
817 struct bt_t **__btndhdrstk;
818 int32 __topi;
819 int32 __max_level;
820 int32 __nd_level;
821 
822 
823 static void open_logfile(void);
824 static void init_glbs(void);
825 static void set_tfmt_dflts(void);
826 static void init_ds(void);
827 static void init_cfg(void);
828 static void xpnd_args(int32, char **);
829 static struct optlst_t *alloc_optlst(void);
830 static void copy_xpnd_onelev_args(void);
831 static void ins_optlst_marker(int32, int32);
832 static void dmp_xpnd_olist(register struct optlst_t *);
833 static int32 find_opt(char *);
834 static void do_args(void);
835 static void bld_inflist(void);
836 static void do_sdflocdef(char *, char *, int32);
837 static void do_cmdmacdef(char *, struct optlst_t *);
838 static int32 bld_incdtab(char *, struct optlst_t *);
839 static struct loadpli_t *bld_loadpli_lbs(char *, struct optlst_t *, int32);
840 static int32 bld_boot_rout_list(struct loadpli_t *, char *);
841 static int32 check_rnam_str(char *);
842 static int32 bld_lbxtab(char *, struct optlst_t *);
843 static void add_lbfil(char *, char);
844 static struct vylib_t *alloc_vylib(char *);
845 static int32 add_suppwarn(char *, struct optlst_t *);
846 static void wrhelp(void);
847 static void init_modsymtab(void);
848 static void init_stsymtab(void);
849 static void add_systsksym(struct systsk_t *);
850 static void add_sysfuncsym(struct sysfunc_t *);
851 static void prep_vflist(void);
852 static void do_timescale(void);
853 static int32 prt_summary(void);
854 static void prt_deswide_stats(void);
855 static int32 count_tran_nets(void);
856 static void mem_use_msg(int32);
857 static void prt_alldesmod_tabs(void);
858 static void prt2_desmod_tab(void);
859 static void bld_modnam(char *, struct mod_t *, int32);
860 static void count_mods(int32 *, int32 *);
861 static int32 count_cells(struct mod_t *);
862 static int32 count_gates(struct mod_t *, int32 *);
863 static void prt2_permod_wiretab(void);
864 static int32 cnt_modprt_bits(struct mod_t *);
865 static void cnt_modwires(struct mod_t *, int32 *, int32 *, int32 *, int32 *, int32 *,
866  int32 *, int32 *);
867 static void st_prt2_permod_wiretab(void);
868 static void st_cnt_modprt_bits(struct mod_t *, int32 *, int32 *, int32 *);
869 static void st_cnt_modwires(struct mod_t *, int32 *, int32 *, int32 *, int32 *);
870 static void prt2_permod_tasktabs(void);
871 static void cnt_modtasks(struct mod_t *, int32 *, int32 *, int32 *, int32 *, int32 *,
872  int32 *);
873 static void prt_modhdr(struct mod_t *);
874 static void reset_cntabs(int32 *, int32 *, int32 *, int32 *, int32 *, int32, int32 *,
875  int32 *, int32 *, int32);
876 static void accum_usecnts(struct mod_t *, int32 *, int32 *, int32 *, int32 *, int32 *,
877  int32 *, int32 *, int32 *, int32 *);
878 
879 
880 
881 /* extern prototypes (maybe defined in this module) */
882 extern int32 __dig_main(int32, char **);
883 extern void __setup_dbmalloc(void);
884 extern void __start_chkchain(void);
885 extern void __my_ftime(time_t *, time_t *);
886 extern void __prt_end_msg(void);
887 extern void __add_infil(char *);
888 extern void __grow_infils(int32);
889 extern int32 __open_sfil(void);
890 extern void __push_vinfil(void);
891 extern int32 __pop_vifstk(void);
892 extern void __do_decompile(void);
893 extern void __process_cdir(void);
894 extern char *__get_tmult(char *, word32 *);
895 extern void __prt2_mod_typetab(int32);
896 extern int32 __enum_is_suppressable(int32);
897 
898 /* extern prototypes defined in other module */
899 extern void __xform_nl_to_modtabs(void);
900 extern void __initialize_dsgn_dces(void);
901 extern int32 __comp_sigint_handler(void);
902 extern char *__my_malloc(int32);
903 extern char *__my_realloc(char *, int32 , int32);
904 /* pv stralloc is fast small section string alloc but can't be freed */
905 extern char *__pv_stralloc(char *);
906 extern struct symtab_t *__alloc_symtab(int32);
907 extern char *__prt_vtok(void);
908 extern char *__to_wtnam2(char *, word32);
909 extern int32 __fr_wtnam(int32);
910 extern int32 __get_arrwide(struct net_t *);
911 extern struct tnode_t *__vtfind(char *, struct symtab_t *);
912 extern void __do_foreign_lang(void);
913 extern void __init_acc(void);
914 extern void __my_dv_flush(void);
915 extern void __push_wrkitstk(struct mod_t *, int32);
916 extern void __pop_wrkitstk(void);
917 extern void __setup_contab(void);
918 extern void __my_exit(int32, int32);
919 
920 
921 extern char *__to_timunitnam(char *, word32);
922 extern FILE *__tilde_fopen(char *, char *);
923 extern char *__bld_lineloc(char *, word32, int32);
924 extern char *__schop(char *, char *);
925 extern void __my_fprintf(FILE *, char *, ...);
926 extern void __cv_msg(char *s, ...);
927 extern void __dbg_msg(char *, ...);
928 extern void __crit_msg(char *s, ...);
929 extern void __ip_msg(char *s, ...);
930 extern void __ip2_msg(char *s, ...);
931 extern void __pv_ferr(int32, char *, ...);
932 extern void __pv_err(int32, char *, ...);
933 extern void __pv_warn(int32, char *, ...);
934 extern void __gfwarn(int32, word32, int32, char *, ...);
935 extern void __pv_fwarn(int32, char *, ...);
936 extern void __gfinform(int32, word32, int32, char *, ...);
937 extern void __gferr(int32, word32, int32, char *, ...);
938 extern void __finform(int32, char *, ...);
939 extern void __fterr(int32, char *, ...);
940 extern void __pv_terr(int32, char *, ...);
941 extern void __arg_terr(char *, int32);
942 extern void __case_terr(char *, int32);
943 extern void __misc_terr(char *, int32);
944 extern int32 __fixup_nl(void);
945 extern void __prep_sim(void);
946 extern void __unget_vtok(void);
947 extern void __call_all_checktfs(void);
948 extern int32 __get1_vtok(FILE *);
949 extern void __skipover_line(void);
950 extern int32 __chk_beg_line(int32);
951 extern void __collect_line(void);
952 extern void __process_sdf_files(void);
953 extern void __exec_all_compiletf_routines(void);
954 extern void __vpi_endcomp_trycall(void);
955 extern void __free_design_pnps(void);
956 extern void __rem_0path_dels(void);
957 extern void __init_sim(void);
958 extern void __call_misctfs_streset(void);
959 extern void __vpi_startreset_trycall(void);
960 extern void __reset_to_time0(void);
961 extern void __pv_sim(void);
962 extern void __vpi_endsim_trycall(void);
963 extern void __alloc_xsval(struct xstk_t *, int32);
964 extern void __my_fclose(FILE *);
965 extern void __my_free(char *, int32);
966 extern void __maybe_open_trfile(void);
967 extern int32 __get_cmdtok(FILE *);
968 extern void __do_macdefine(char *, char *);
969 extern void __add_sym(char *, struct tnode_t *);
970 extern void __setup_veriusertf_systfs(void);
971 extern void __call_vlog_startup_procs(void);
972 extern void __dmp_mod(FILE *, struct mod_t *);
973 extern void __dmp_udp(FILE *, struct udp_t *);
974 extern void __get_vtok(void);
975 extern void __rd_ver_src(void);
976 extern void __rd_ver_mod(void);
977 extern int32 __bqline_emptytail(register char *);
978 extern void __process_pli_dynamic_libs(struct loadpli_t *);
979 extern int32 __rd_cfg(void);
980 extern void __expand_lib_wildcards(void);
981 extern void __rd_ver_cfg_src(void);
982 extern void __sym_addprims(void);
983 
984 
985 
986 /* externs for system error messages */
987 extern int32 errno;
988 
989 /* special external for setjmp environment - reset environment */
990 extern jmp_buf __reset_jmpbuf;
991 extern char __pv_ctab[];
992 
993 
994 
995 /*
996  * main
997  */
__dig_main(int32 argc,char ** argv)998 extern int32 __dig_main(int32 argc, char **argv)
999 {
1000  int32 rv, save_quiet;
1001  long t1;
1002  double timd1;
1003  char s1[RECLEN];
1004 
1005  /* only does something if db malloc define set */
1006  __setup_dbmalloc();
1007 
1008 
1009  __start_sp = __end_sp = NULL;
1010  __log_s = NULL;
1011  /* set compilation int32 signal and save entry signal so can restore */
1012 #if defined(INTSIGS)
1013  __old_int_sig = (sighandler *) signal(SIGINT, __comp_sigint_handler);
1014 #else
1015  __old_int_sig = (sighandler *) signal(SIGINT,
1016    (void (*)()) __comp_sigint_handler);
1017 #endif
1018 
1019  init_glbs();
1020 
1021 
1022  /* vpi argument special format argv only set if needed */
1023  __vpi_argc = 0;
1024  __vpi_argv = NULL;
1025  /* no by convention argv 0 always has program name */
1026  __vpi_argv0 = __pv_stralloc(argv[0]);
1027 
1028  /* expand options so have list that looks as if all on command line */
1029  xpnd_args(argc, argv);
1030 
1031  /* process special early options - any errors here only to std out */
1032  /* notice no verbose message for quiet */
1033  if (__quiet_olp != NULL)
1034   {
1035    __quiet_msgs = TRUE;
1036    /* vendor1 runs with -q need to allow verbose switches to be turned on */
1037    __verbose = FALSE;
1038   }
1039  open_logfile();
1040 
1041 #ifdef __linux__
1042 #ifdef __ELF__
1043  __platform = __pv_stralloc("Linux-elf");
1044 #else
1045  __platform = __pv_stralloc("Linux-aout");
1046 #endif
1047 #endif
1048 
1049 #ifdef __CYGWIN32__
1050  __platform = __pv_stralloc("Cygwin32");
1051 #endif
1052 
1053 #ifdef __FreeBSD__
1054  __platform = __pv_stralloc("X86 FreeBSD");
1055 #endif
1056 
1057 #ifdef __APPLE__
1058  __platform = __pv_stralloc("Mac OSX");
1059 #endif
1060 
1061 #ifdef __sparc
1062  __platform = __pv_stralloc("Sparc-Solaris");
1063 #endif
1064 #if defined(__i386__) && defined(__SVR4)
1065  __platform = __pv_stralloc("X86-Solaris");
1066 #endif
1067 
1068 #ifdef __hpux
1069  __platform = __pv_stralloc("hpux");
1070 #endif
1071 
1072 #ifdef __CYGWIN32__
1073  __platform = __pv_stralloc("Cygwin32");
1074 #endif
1075 
1076  __vers = __pv_stralloc(VERS);
1077  __vers2 = __pv_stralloc(VERS2);
1078  __ofdt = __pv_stralloc(OFDT);
1079  __ip2_msg("%s%s of %s (%s).\n", __vers, __vers2, __ofdt, __platform);
1080 
1081  /* SJM 08/27/03 - change so have separate commercial and open source msgs */
1082  __ip_msg("Copyright (c) 1991-2007 Pragmatic C Software Corp.\n");
1083  __ip_msg(
1084   "  All Rights reserved.  Licensed under the GNU General Public License (GPL).\n");
1085  __ip_msg(
1086   "  See the 'COPYING' file for details.  NO WARRANTY provided.\n");
1087 
1088  __cv_msg("Today is %s.\n", __pvdate);
1089 
1090  if (__help_olp != NULL)
1091   {
1092    wrhelp();
1093    __cv_msg("**Special help mode successfully completed.\n");
1094    return(0);
1095   }
1096 
1097  if (__verb_olp != NULL)
1098   {
1099    if (!__quiet_msgs)
1100     { __verbose = TRUE; __cv_msg("  Verbose mode is on.\n"); }
1101   }
1102  if (__log_s != NULL && strcmp(__log_fnam, DFLT_LOGFNAM) != 0)
1103   {
1104    if (__verbose)
1105     __cv_msg("  Output log will be written to \"%s\".\n", __log_fnam);
1106   }
1107  if (__verbose) __cv_msg("  Invoked by: \"%s\".\n", argv[0]);
1108 
1109  do_args();
1110 
1111 
1112  bld_inflist();
1113 
1114  __modhdr = __end_mdp = NULL;
1115  __init_acc();
1116 
1117  init_modsymtab();
1118  /* must initialize pli table after file processed */
1119  init_stsymtab();
1120  /* --- DBG remove
1121  if (__verbose)
1122   __cv_msg("  Initialization used %ld bytes of allocated memory (%ld free).\n",
1123   __memstr_use + __mem_use + TWHINITSIZE*sizeof(struct telhdr_t),
1124   __mem_free);
1125  --- */
1126 
1127 
1128  /* SJM 12/05/03 - for now assuming if +config options to specify lib map */
1129  /* file, then do not read default lib.map in cwd - is that correct? */
1130  if (__map_files_hd == NULL)
1131   {
1132    FILE *fp;
1133 
1134    if ((fp = __tilde_fopen("lib.map", "r")) != NULL)
1135     {
1136      __my_fclose(fp);
1137      __map_files_hd = __map_files_tail = (struct mapfiles_t *)
1138       __my_malloc(sizeof(struct mapfiles_t));
1139      __map_files_hd->mapfnam = __pv_stralloc("lib.map");
1140      __map_files_hd->mapfnxt = NULL;
1141      if (__verbose)
1142       {
1143        __cv_msg(
1144         "  Using map.lib config file because no +config options specified.\n");
1145       }
1146     }
1147    else if (__verbose)
1148     {
1149      __cv_msg(
1150       "  P1364 2001 config map library not specified - using -y/-v libraries.\n");
1151     }
1152   }
1153 
1154  /* read the cfg lib.map file list and build internal d.s. */
1155  if (__verbose) __cv_msg("  Begin Translation:\n");
1156 
1157  if (__map_files_hd != NULL)
1158   {
1159    /* SJM - 05/26/04 if config used, ignore any command line .v files */
1160    if (__last_inf != __last_optf)
1161     {
1162      __pv_warn(3138,
1163       "config used but verilog files specified on command line - files ignored");
1164     }
1165    if (__verbose) __cv_msg("  Reading config map.lib files:\n");
1166    __rd_cfg();
1167    if (__cmdl_library == NULL) __cmdl_library = __pv_stralloc("work");
1168    /* after expansion, each library element is a concrete file name */
1169    __expand_lib_wildcards();
1170    __rd_ver_cfg_src();
1171   }
1172   else
1173    {
1174     /* use pre-2001 files reading routines */
1175     prep_vflist();
1176     __rd_ver_src();
1177    }
1178 
1179  if (__parse_only)
1180   {
1181    __cv_msg("  Parsing only run complete.\n");
1182    __my_ftime(&__end_time, &__end_mstime);
1183    if (__pv_err_cnt != 0) rv = 1; else rv = 0;
1184    goto done2;
1185   }
1186 
1187  if (__in_ifdef_level != 0)
1188   {
1189    __pv_err(924, "last `ifdef unterminated in source stream");
1190   }
1191  if (__end_mdp == NULL)
1192   {
1193    if (__pv_err_cnt != 0) goto err_done;
1194    __crit_msg("**Design contains no modules - nothing to do.\n");
1195    goto set_etime;
1196   }
1197 
1198  /* calls to fixup routines here */
1199  if (__verbose)
1200   {
1201    __cv_msg("  Begin pass 2:\n");
1202   }
1203  /* if verbose off will not print anything */
1204  mem_use_msg(FALSE);
1205  if (!__fixup_nl()) goto err_done;
1206 
1207  if (__pv_err_cnt != 0) goto err_done;
1208  if (__decompile) __do_decompile();
1209  __my_ftime(&__end_comp_time, &__end_comp_mstime);
1210  if (__numtopm == 0)
1211   {
1212    __crit_msg("  Unable to begin simulation - no top level modules.\n");
1213 set_etime:
1214    __my_ftime(&__end_time, &__end_mstime);
1215    rv = 1;
1216    goto done2;
1217   }
1218 
1219  /* notice compilation must include prep. for at least udp checking */
1220  __prep_sim();
1221 
1222  if (__pv_err_cnt == 0)
1223   {
1224    if (__prt_stats || __prt_allstats)
1225     {
1226      save_quiet = __quiet_msgs;
1227      __quiet_msgs = FALSE;
1228      prt_alldesmod_tabs();
1229      __quiet_msgs = save_quiet;
1230     }
1231    else if (__verbose)
1232     {
1233      save_quiet = __quiet_msgs;
1234      __quiet_msgs = FALSE;
1235      prt_deswide_stats();
1236      __quiet_msgs = save_quiet;
1237     }
1238   }
1239  /* RELEASE remove -- */
1240  /* LOOKATME - for now need this even when read source only mode */
1241  if (__verbose)
1242   {
1243    __cv_msg(
1244     "  Variable storage in bytes: %d for scalars, %d for non scalars.\n",
1245     (__btabbsiz + __nchgbtabbsiz), 4*__wtabwsiz);
1246   }
1247 
1248  if (__compile_only)
1249   {
1250    __cv_msg("  Translation only run complete.\n");
1251    __my_ftime(&__end_time, &__end_mstime);
1252    goto done;
1253   }
1254  if (__pv_err_cnt != 0) goto err_done;
1255 
1256  if (__verbose) __cv_msg("  Begin load/optimize:\n");
1257  mem_use_msg(FALSE);
1258 
1259  __run_state = SS_LOAD;
1260  __can_exec = FALSE;
1261 
1262  /* now that all storage allocated and given some val, call checktf */
1263  /* routines, these can call anything not sim queue depended but shouldn't */
1264  if (__tfrec_hdr != NULL)
1265   {
1266    __run_state = SS_RESET;
1267    __call_all_checktfs();
1268    __run_state = SS_LOAD;
1269   }
1270 
1271  /* notice advantage of option is allows use in initialization */
1272  /* assumes called from first top level module */
1273  if (__sdflst != NULL)
1274   {
1275    __process_sdf_files();
1276    if (__pv_err_cnt != 0) goto err_done;
1277   }
1278  __sfnam_ind = 0;
1279  __slin_cnt = 0;
1280  /* final step in loading is calling vpi_ systf checktf routines */
1281  /* can not do until here because d.s. built */
1282  if (__vpi_sysf_hdr != NULL || __vpi_syst_hdr != NULL)
1283   {
1284    /* compiletf run in reset state because no time and no events */
1285    __run_state = SS_RESET;
1286    __exec_all_compiletf_routines();
1287    __run_state = SS_LOAD;
1288   }
1289 
1290  /* still can use changed params (either type) to elaborate delays */
1291  /* from params and set delays even where no delay in source here */
1292  /* BEWARE - must not move to after new compile prep xform because exprs */
1293  /*          exprs not moved (if move later must add link and chg expr ptr */
1294  if (__have_vpi_actions) __vpi_endcomp_trycall();
1295 
1296 
1297  if (__pv_err_cnt != 0) goto err_done;
1298 
1299  /* SJM 01/14/00 - always can free design pnps since (LABEL does not work */
1300  /*                (error emitted) in $sdf_annotate systask calls */
1301  /* SJM for sdf do not free - see if works
1302  __free_design_pnps();
1303  -- */
1304 
1305  /* after here, delays elaborated - only vpi change of delays now possible */
1306  /* but vpi_ change probably not alloed under P1364 */
1307  /* SJM 01/14/00 - must allow param changes from label during sim */
1308  /*                for sdf annotate calls - undefined change points */
1309  /*                also can't remove all 0 paths delays may change still */
1310  if (!__has_sdfann_calls)
1311   {
1312    /* go through disable all 0 delay only paths - never causes error */
1313    if (__rm_path_pnd0s) __rem_0path_dels();
1314   }
1315 
1316  /* but can remove gates and any added all 0 mipds (maybe added again if */
1317  /* annotate systask used later) so need messages here */
1318  if (__num_rem_gate_pnd0s != 0 && __verbose)
1319   {
1320    __cv_msg(
1321     "  %d (%d flat) gate or udp zero delays coded in source removed.\n",
1322     __num_rem_gate_pnd0s, __num_flat_rem_gate_pnd0s);
1323   }
1324  if (__num_rem_mipds != 0 && __verbose)
1325   {
1326    __cv_msg("  %d flattened bits of 0 delay MIPDS removed - no effect.\n",
1327     __num_rem_mipds);
1328   }
1329  /* always do transformations to group elements into per module tables */
1330  __xform_nl_to_modtabs();
1331 
1332  /* SJM 05/04/05 - now can only initialize dce previous values */
1333  __initialize_dsgn_dces();
1334 
1335  __init_sim();
1336  __my_ftime(&__end_prep_time, &__end_prep_mstime);
1337 
1338  if (__verbose) __cv_msg("  Begin simulation:\n");
1339  mem_use_msg(TRUE);
1340  if (__verbose) __cv_msg("\n");
1341 
1342  /* on setup returns 0, on lng jmp returns 1, but always just exec sim */
1343  /* since restart */
1344  /* on set returns 0, do not run re-init code */
1345  if (setjmp(__reset_jmpbuf) != 0)
1346   {
1347    if (__tfrec_hdr != NULL) __call_misctfs_streset();
1348    if (__have_vpi_actions) __vpi_startreset_trycall();
1349    __now_resetting = TRUE;
1350    __run_state = SS_RESET;
1351    /* change to sim run state in here */
1352    __reset_to_time0();
1353    /* by here state back to SIM */
1354   }
1355 
1356 
1357  __pv_sim();
1358  /* LOOKATME - think also call end sim cb here but LRM says $finish */
1359  if (__have_vpi_actions) __vpi_endsim_trycall();
1360 
1361  /* LOOKATME - remove since does not match ovi __cv_msg("\n"); */
1362  /* notice must know current end time */
1363  __my_ftime(&__end_time, &__end_mstime);
1364  __prt_end_msg();
1365  goto done;
1366 
1367 err_done:
1368  __cv_msg("  Unable to begin simulation.\n");
1369  __my_ftime(&__end_time, &__end_mstime);
1370 
1371 done:
1372  if (__dv_fd != -1) __my_dv_flush();
1373  if (__verbose)
1374   {
1375    if (__dv_fd != -1)
1376     {
1377      if ((t1 = lseek(__dv_fd, 0, SEEK_END)) != -1)
1378       {
1379        __cv_msg("  $dumpvars %ld bytes written to file \"%s\".\n", t1,
1380         __dv_fnam);
1381       }
1382     }
1383    mem_use_msg(FALSE);
1384   }
1385  rv = prt_summary();
1386 done2:
1387  /* DBG remove --- */
1388  if (__xspi != -1 || __itspi != -1 || __fcspi != -1)
1389   __misc_terr(__FILE__, __LINE__);
1390  /* --- */
1391  strcpy(s1, ctime(&__end_time));
1392 
1393  s1[24] = '\0';
1394  __pvdate = __pv_stralloc(s1);
1395  timd1 = (double) (__end_time - __start_time)
1396   + ((double) (__end_mstime - __start_mstime))/1000.0;
1397  __cv_msg("End of %s%s at %s (elapsed %.1lf seconds).\n",
1398   __vers,__vers2, __pvdate, timd1);
1399  __my_exit(rv, FALSE);
1400  /* needed to stop warns but exit prevents control from reaching here */
1401  return(0);
1402 }
1403 
1404 #ifdef __DBMALLOC__
1405 /*
1406  * start malloc debugging - can call from anywhere
1407  */
__setup_dbmalloc(void)1408 extern void __setup_dbmalloc(void)
1409 {
1410  union dbmalloptarg m;
1411 
1412  /* m.i = M_HANDLE_IGNORE; */
1413  m.i = M_HANDLE_ABORT;
1414  dbmallopt(MALLOC_WARN,&m);
1415  m.str = "malloc.log";
1416  dbmallopt(MALLOC_ERRFILE,&m);
1417 
1418  /* set to 1 to turn on */
1419  /* --- */
1420  m.i = 1;
1421  dbmallopt(MALLOC_CKCHAIN,&m);
1422  /* -- */
1423 
1424  /* 0 means don't check str/mem func args */
1425  /* --- */
1426  m.i = 1;
1427  dbmallopt(MALLOC_CKDATA,&m);
1428  /* --- */
1429  /* --- */
1430  m.i = 0;
1431  dbmallopt(MALLOC_REUSE,&m);
1432  /* --- */
1433  /* -- */
1434  m.i = 2;
1435  /* m.i = 3; */
1436  dbmallopt(MALLOC_FILLAREA, &m);
1437  /* -- */
1438 }
1439 
__start_chkchain(void)1440 extern void __start_chkchain(void)
1441 {
1442  union dbmalloptarg m;
1443 
1444  m.i = 1;
1445  dbmallopt(MALLOC_CKCHAIN,&m);
1446  /* -- */
1447  m.i = 1;
1448  dbmallopt(MALLOC_CKDATA,&m);
1449  /* -- */
1450 }
1451 #else
1452 /* nil if db malloc not used */
__setup_dbmalloc(void)1453 extern void __setup_dbmalloc(void)
1454 {
1455 }
__start_chkchain(void)1456 extern void __start_chkchain(void)
1457 {
1458 }
1459 #endif
1460 
1461 /*
1462  * routine to compute current time in seconds and milliseconds (if possible)
1463  */
__my_ftime(time_t * secs,time_t * msecs)1464 extern void __my_ftime(time_t *secs, time_t *msecs)
1465 {
1466  struct timeval tv;
1467  struct timezone tz;
1468 
1469  if (gettimeofday(&tv, &tz) == EINVAL) __arg_terr(__FILE__, __LINE__);
1470 
1471  *secs = (long) tv.tv_sec;
1472  *msecs = (long) (tv.tv_usec/1000);
1473 }
1474 
1475 /*
1476  * print ending verbose message
1477  */
__prt_end_msg()1478 extern void __prt_end_msg()
1479 {
1480  int32 t1;
1481  double timd1, timd2, timd3;
1482 
1483  t1 = (int32) __num_proc_tevents - (int32) __proc_thrd_tevents;
1484  if (t1 < 0) t1 = 0;
1485  __cv_msg(
1486   "%d simulation events and %u declarative immediate assigns processed.\n",
1487    t1 , __immed_assigns);
1488  /* number of cancelled should equal newval (0 del.) and inertial cancels? */
1489  if (__num_execstmts - __num_addedexec > 0)
1490   {
1491      __cv_msg("%u behavioral statements executed (%u procedural suspends).\n",
1492       __num_execstmts - __num_addedexec, __proc_thrd_tevents);
1493   }
1494  else
1495   {
1496    if (__proc_thrd_tevents > 0 && __optimized_sim)
1497     {
1498      __cv_msg("Optimized code execution (%u procedural suspends).\n",
1499       __proc_thrd_tevents);
1500     }
1501   }
1502  if (__verbose && __debug_flg)
1503   {
1504    __cv_msg(
1505     "  %u(%u) inertial reschedules, %u net changes, %u continuous assigns,\n",
1506     __num_cancel_tevents, __inertial_cancels + __newval_rescheds,
1507     __num_netchges, __immed_assigns);
1508    __cv_msg("  and %d tran/tranif switch vertices processed.\n",
1509     __num_switch_vtxs_processed);
1510   }
1511 
1512  timd1 = (double) (__end_comp_time - __start_time)
1513   + ((double) (__end_comp_mstime - __start_mstime))/1000.0;
1514  timd2 = (double) (__end_prep_time - __end_comp_time)
1515   + ((double) (__end_prep_mstime - __end_comp_mstime + 50))/1000.0;
1516  timd3 = (double) (__end_time - __end_prep_time)
1517   + ((double) (__end_mstime - __end_prep_mstime + 50))/1000.0;
1518  __cv_msg(
1519   "  Times (in sec.):  Translate %.1f, load/optimize %.1f, simulation %.1f.\n",
1520   timd1, timd2, timd3);
1521 }
1522 
1523 /*
1524  * STARTUP INITIALIZATION ROUTINES
1525  */
1526 
1527 /*
1528  * initialize various globals (including flags)
1529  *
1530  * sets things that are set and then returned to initial value when done
1531  * but routine that uses variable
1532  */
init_glbs(void)1533 static void init_glbs(void)
1534 {
1535  char *cp;
1536  char s1[RECLEN];
1537 
1538  /* initialize things needed before any memory can be allocated */
1539  __mem_use = __mem_freed = __mem_allocated = __memstr_use = 0L;
1540  __mem_udpuse = __arrvmem_use = 0L;
1541 
1542  /* initialize some vars */
1543  __pv_err_cnt = __pv_warn_cnt = __inform_cnt = 0;
1544  __max_errors = MAX_ERRORS;
1545 
1546  /* initialize flags */
1547  __verbose = FALSE;
1548  __quiet_msgs = FALSE;
1549  __lib_verbose = FALSE;
1550  __cfg_verbose = FALSE;
1551  __lib_rescan = FALSE;
1552  __rescanning_lib = FALSE;
1553  __switch_verbose = FALSE;
1554  __chg_portdir = FALSE;
1555  __cmd_s = NULL;
1556  __cmd_fnam = NULL;
1557  __cmd_start_fnam = NULL;
1558  __key_s = __save_key_s = NULL;
1559  /* default for trace output if stdout */
1560  __tr_s = stdout;
1561  __tr_fnam = __pv_stralloc("stdout");
1562  __sdflst = NULL;
1563  __sdf_s = NULL;
1564  __sdf_mdp = NULL;
1565  __sdf_verbose = FALSE;
1566  __sdf_opt_log_fnam = NULL;
1567  __sdf_opt_log_s = NULL;
1568  __has_sdfann_calls = FALSE;
1569 
1570  __map_files_hd = __map_files_tail = NULL;
1571  __cmdl_library = NULL;
1572  __cfglib_hd = __cfglib_tail = NULL;
1573  __cfg_hd = NULL;
1574  __cur_cfg = NULL;
1575  __cfg_mdp = NULL;
1576  __bind_inam_comptab = NULL;
1577  __siz_bind_comps = 0;
1578  __last_bind_comp_ndx = -1;
1579 
1580  __sdf_active = FALSE;
1581  __sdf_no_warns = FALSE;
1582  __sdf_no_errs = FALSE;
1583  __sdf_from_cmdarg = FALSE;
1584  __nokey_seen = FALSE;
1585  __key_fnam = NULL;
1586  /* notice warns on by default */
1587  /* should be more selective about which warnings turned off */
1588  __no_warns = FALSE;
1589  __no_errs = FALSE;
1590  __outlinpos = 0;
1591  /* notice informs off by default */
1592  __no_informs = TRUE;
1593  __compile_only = FALSE;
1594  __parse_only = FALSE;
1595  __optimized_sim = FALSE;
1596  __dump_flowg = FALSE;
1597  __opt_debug_flg = FALSE;
1598  __iact_state = FALSE;
1599  __no_iact = FALSE;
1600  __intsig_prt_snapshot = FALSE;
1601  __pending_enter_iact = FALSE;
1602  __stop_before_sim = FALSE;
1603  /* this is for :reset so off (< 100) on start */
1604  __dbg_stop_before = 0;
1605  __decompile = FALSE;
1606  __debug_flg = FALSE;
1607  __mintypmax_sel = DEL_TYP;
1608  __sdf_mintypmax_sel = __mintypmax_sel;
1609  __chking_conta = FALSE;
1610  __rhs_isgetpat = FALSE;
1611  __expr_rhs_decl = FALSE;
1612  __chg_rng_direct = FALSE;
1613  __has_top_mtm = FALSE;
1614  __nd_0width_catel_remove = FALSE;
1615  __next_dvnum = 0;
1616  __dv_allform_insrc = FALSE;
1617  __st_tracing = FALSE;
1618  __ev_tracing = FALSE;
1619  __pth_tracing = FALSE;
1620  /* SJM 07/13/01 - add option and get code to support src-dst MIPDs working */
1621  __use_impthdels = FALSE;
1622  __gateeater_on = FALSE;
1623  __prt_stats = FALSE;
1624  __prt_allstats = FALSE;
1625  /* show cancel event pulse handling all off (Verilog default inertial) */
1626  __show_cancel_e = FALSE;
1627  __showe_onevent = TRUE;
1628  __warn_cancel_e = FALSE;
1629  /* always want to remove all 0 delay path unless turned off */
1630  __rm_path_pnd0s = TRUE;
1631  __rm_gate_pnd0s = FALSE;
1632  __num_rem_gate_pnd0s = 0;
1633  __num_flat_rem_gate_pnd0s = 0;
1634  __num_rem_mipds = 0;
1635  __dmpvars_all = FALSE;
1636  __num_execstmts = 0;
1637  __num_addedexec = 0;
1638  /* this may get turned on for good in timformat fixup code */
1639  __nd_timstr_suf = FALSE;
1640  __num_glbs = 0;
1641  __num_uprel_glbs = 0;
1642  __num_dfps = __num_glbdfps = __num_locdfps = 0;
1643  __num_inst_pndparams = 0;
1644  __design_gi_arrays = FALSE;
1645  __design_gia_pndparams = FALSE;
1646  __mdlevhdr = NULL;
1647  __xldl_hdr = __last_xldl = NULL;
1648  __xldlvtxind = NULL;
1649  __num_xldlvtxs = 0;
1650  __siz_xldlvtxtab = 0;
1651 
1652  __nets_removable = __flnets_removable = 0;
1653  __gates_removable = __flgates_removable = 0;
1654  __contas_removable = __flcontas_removable = 0;
1655  __num_ys = 0;
1656  __num_inmodglbs = 0;
1657  __accelerate = TRUE;
1658  __history_on = TRUE;
1659 
1660  /* set compiler directive values - can be reset to these with `resetall */
1661  set_tfmt_dflts();
1662  __dflt_ntyp = N_WIRE;
1663  __in_cell_region = FALSE;
1664  __unconn_drive = TOK_NONE;
1665  __no_expand = FALSE;
1666  __no_specify = FALSE;
1667  __no_tchks = FALSE;
1668  __lib_are_cells = TRUE;
1669  __design_has_cells = FALSE;
1670 
1671  /* 06/22/00 - SJM - possible cross macro 2 token must start off */
1672  __macro_sep_width = FALSE;
1673  __maybe_2tok_sized_num = FALSE;
1674  __macro_sav_nwid = FALSE;
1675 
1676  __rding_comment = FALSE;
1677  __splitting = FALSE;
1678  __run_state = SS_COMP;
1679  __no_tmove_levels = INFLOOP_MAX;
1680  __checking_only = TRUE;
1681  __iasetup = FALSE;
1682  __ia_entered = FALSE;
1683  __force_active = FALSE;
1684  __assign_active = FALSE;
1685  __qcaf_dcehdr = NULL;
1686 
1687  /* need to leave these so stmt chking does not do special func body chk */
1688  __name_assigned_to = TRUE;
1689  __locfnamsyp = NULL;
1690  /* assume no strengths - if unc. pull, turned off before stren marking*/
1691  __design_no_strens = TRUE;
1692  __cur_dce_expr = NULL;
1693  __impl_evlst_hd = NULL;
1694  __impl_evlst_tail = NULL;
1695  __canbe_impl_evctrl = FALSE;
1696  __nb_sep_queue = TRUE;
1697 
1698  __my_ftime(&__start_time, &__start_mstime);
1699  cp = ctime(&__start_time);
1700  strcpy(s1, cp);
1701  s1[24] = '\0';
1702  __pvdate = __pv_stralloc(s1);
1703  __pv_timestamp = __pv_stralloc(s1);
1704  __end_comp_time = 0L;
1705  __end_comp_mstime = 0L;
1706  __end_prep_time = 0L;
1707  __end_prep_mstime = 0L;
1708  /* sim time need for possible pli calls */
1709  __simtime = 0ULL;
1710  init_ds();
1711  init_cfg();
1712 }
1713 
1714 /*
1715  * set various time format defaults
1716  */
set_tfmt_dflts(void)1717 static void set_tfmt_dflts(void)
1718 {
1719  /* default is 1 ns. */
1720  __cur_units = 9;
1721  __cur_prec = 0;
1722  /* this is always set to min. of all modules (and is total) */
1723  __des_timeprec = 9;
1724  __tfmt_units = 9;
1725  /* next three default values required by LRM */
1726  __tfmt_precunits = 0;
1727  __tfmt_suf = __pv_stralloc("");
1728 
1729  /* this includes space + suffix if suffix is non empty string */
1730  __tfmt_minfwid = 20;
1731  __des_has_timescales = FALSE;
1732 }
1733 
1734 /*
1735  * initialize data structures if needed
1736  */
init_ds(void)1737 static void init_ds(void)
1738 {
1739  register int32 i;
1740  int32 len;
1741  word64 p, u;
1742  char *chp;
1743 
1744  /* HOME env. variable for use by tilde */
1745  if ((chp = (char *) getenv ("HOME")) == NULL) strcpy(__pv_homedir, ".");
1746  else
1747   {
1748    strcpy(__pv_homedir, chp);
1749    len = strlen(__pv_homedir);
1750    if (__pv_homedir[len - 1] == '/') __pv_homedir[len - 1] = '\0';
1751   }
1752 
1753  __blnkline = __my_malloc(RECLEN + 1);
1754  for (i = 0; i < OUTLINLEN; i++) __blnkline[i] = ' ';
1755  __blnkline[OUTLINLEN] = '\0';
1756 
1757  __venviron = (struct symtab_t **)
1758   __my_malloc(MAXLEVELS*sizeof(struct symtab_t *));
1759  for (i = 0; i < MAXLEVELS; i++) __venviron[i] = NULL;
1760 
1761  __glbsycmps = (struct sy_t **) __my_malloc(MAXGLBCOMPS*sizeof(struct sy_t *));
1762  __glbxcmps = (struct expr_t **)
1763   __my_malloc(MAXGLBCOMPS*sizeof(struct expr_t *));
1764  for (i = 0; i < MAXGLBCOMPS; i++)
1765   { __glbsycmps[i] = NULL; __glbxcmps[i] = NULL; }
1766 
1767  /* allocate a work table for building per module global refs */
1768  __grwrktab = (struct gref_t *) __my_malloc(100*sizeof(struct gref_t));
1769  __grwrktabsiz = 100;
1770  __grwrknum = 0;
1771 
1772  /* initialize expr. parse table and ID name/loc table */
1773  __exprtabsiz = 1000;
1774  __exprtab = (struct expr_t **)
1775   __my_malloc(__exprtabsiz*sizeof(struct expr_t *));
1776  /* need first node in case of null expr. */
1777  __exprtab[0] = (struct expr_t *) __my_malloc(sizeof(struct expr_t));
1778  for (i = 1; i < __exprtabsiz; i++) __exprtab[i] = NULL;
1779  __expr_is_lval = FALSE;
1780 
1781  __expr_idtab = (struct expridtab_t **)
1782   __my_malloc(__exprtabsiz*sizeof(struct expridtab_t *));
1783  for (i = 0; i < __exprtabsiz; i++) __expr_idtab[i] = NULL;
1784 
1785  /* allocate and initialize eval stack - must grow for recursive functions */
1786  __maxxnest = MAXXNEST;
1787  __xstk = (struct xstk_t **) __my_malloc(__maxxnest*sizeof(struct xstk_t *));
1788  /* assume 1 work dummy size here - just need some value */
1789  for (i = 0; i < __maxxnest; i++)
1790   {
1791    __xstk[i] = (struct xstk_t *) __my_malloc(sizeof(struct xstk_t));
1792    /* this fills xstack table fields */
1793    __alloc_xsval(__xstk[i], 1);
1794   }
1795  /* notice this is dynamic nesting of recursive func. calls - must grow */
1796  __maxfcnest = MAXFCNEST;
1797  __fcstk = (struct task_t **)
1798   __my_malloc(__maxfcnest*sizeof(struct task_t *));
1799  for (i = 0; i < __maxfcnest; i++) __fcstk[i] = NULL;
1800 
1801  __nbstk = (struct st_t **) __my_malloc(MAXPRPSTNEST*sizeof(struct st_t *));
1802  for (i = 0; i < MAXPRPSTNEST; i++) __nbstk[i] = NULL;
1803  __nbsti = -1;
1804 
1805  /* allocate macro definition work string (it grows)*/
1806  __macwrklen = IDLEN;
1807  __macwrkstr = __my_malloc(__macwrklen);
1808  __mac_line_len = 0;
1809  __macarg_hdr = NULL;
1810  __macbs_flag = FALSE;
1811 
1812  /* allocate attribute collection work string (it grows)*/
1813  __attrwrklen = IDLEN;
1814  __attrwrkstr = __my_malloc(__attrwrklen);
1815  __attr_line_len = 0;
1816  __attr_prefix = FALSE;
1817 
1818  __attrparsestrlen = IDLEN;
1819  __attrparsestr = __my_malloc(__attrparsestrlen);
1820 
1821  /* make this so big that even if IDLEN length 2 IDs still will fit */
1822  __xs = __my_malloc(2*IDLEN);
1823  __xs2 = __my_malloc(2*IDLEN);
1824  __wrks1 = __my_malloc(2*IDLEN);
1825  __wrks2 = __my_malloc(2*IDLEN);
1826  /* SJM 03/20/00 alloc start size for string and number assembly tokens */
1827  __strtoken = __my_malloc(IDLEN + 1);
1828  __strtok_wid = IDLEN + 1;
1829  __numtoken = __my_malloc(IDLEN + 1);
1830  __numtok_wid = IDLEN + 1;
1831 
1832  /* need malloc since need to be re-allocated */
1833  __acwrk = (word32 *) __my_malloc(WRDBYTES*DFLTIOWORDS);
1834  __bcwrk = (word32 *) __my_malloc(WRDBYTES*DFLTIOWORDS);
1835  __abwrkwlen = DFLTIOWORDS;
1836  /* to turn off number, set to TRUE but must be left in F state */
1837  __exprline = __my_malloc(IDLEN);
1838  __cur_sofs = 0;
1839  __exprlinelen = IDLEN;
1840  __force_base = BNONE;
1841  /* first to use is base */
1842  __last_veriusertf = BASE_VERIUSERTFS - 1;
1843  /* SJM 07/16/02 - nee internal shdown table for dynamic pli1 boostrap ret */
1844  __shadow_veriusertfs = NULL;
1845  /* this is used as counter then added to veriuser tf last */
1846  __last_systf = __last_veriusertf;
1847 
1848  /* globals for $q_ system tasks */
1849  __qlist_hdr = NULL;
1850 
1851  /* not used until sim, but init here */
1852  __tfinst = NULL;
1853  __tfrec = NULL;
1854  __tfrec_hdr = __tfrec_end = NULL;
1855  /* lists of locationss for every registered vpi systf that has compiletf */
1856  __vpi_sysf_hdr = __vpi_syst_hdr = NULL;
1857  /* SJM 07/08/02 - now pli loads dynamic library with bootstrp func */
1858  __vpi_dynlib_hd = __vpi_dynlib_end = NULL;
1859  __pli1_dynlib_hd = __pli1_dynlib_end = NULL;
1860 
1861  __siz_in_fils = MAXFILS;
1862  __in_fils = (char **) __my_malloc(__siz_in_fils*sizeof(char *));
1863  __last_lbf = 0;
1864  __last_srcf = 0;
1865  __inclst_hdr = __inclst_end = NULL;
1866  __vinstk = (struct vinstk_t **)
1867   __my_malloc(MAXFILNEST*sizeof(struct vinstk_t *));
1868  __vyhdr = NULL;
1869  __end_vy = NULL;
1870  __num_ylibs = __num_vlibs = 0;
1871 
1872  /* initialized here since built-in and define + options are added */
1873  __pv_defsyms = __alloc_symtab(FALSE);
1874  /* LOOKATME - need more than thes 6 defines */
1875  __do_macdefine("`__cver__", "");
1876  __do_macdefine("`__CVER__", "");
1877  __do_macdefine("`__P1364__", "");
1878  __do_macdefine("`__p1364__", "");
1879 
1880  __last_lbx = -1;
1881  __lbexts = (char **) __my_malloc(MAXLBEXTS*sizeof(char *));
1882  __lbexts[0] = NULL;
1883 
1884  __last_incdir = -1;
1885  __incdirs = (char **) __my_malloc(MAXINCDIRS*sizeof(char *));
1886  __incdirs[0] = NULL;
1887 
1888  __undefhd = __undeftail = NULL;
1889  __undef_mods = 0;
1890 
1891  __wsupptab = (word32 *) __my_malloc(MAXWSWRDS*sizeof(word32));
1892  for (i = 0; i < MAXWSWRDS; i++) __wsupptab[i] = 0L;
1893  __in_ifdef_level = 0;
1894  __ifdef_skipping = FALSE;
1895  __processing_func = FALSE;
1896  __first_num_eol = FALSE;
1897  __langstr = NULL;
1898  __doing_langdir = FALSE;
1899  __rding_top_level = TRUE;
1900 
1901  __itstk = (struct itree_t **)
1902   __my_malloc((MAXITDPTH + 1)*sizeof(struct itree_t *));
1903  for (i = 0; i <= MAXITDPTH; i++) __itstk[i] = NULL;
1904  __itstk[0] = (struct itree_t *) 0xffffffff;
1905  __itstk = &(__itstk[1]);
1906 
1907  __xspi = __itspi = __fcspi = -1;
1908  __inst_ptr = NULL;
1909  __inst_mod = NULL;
1910  /* change to test different udp reps. */
1911  __ualtrepipnum = UALTREPIPNUM;
1912  /* DBG all wide __ualtrepipnum = 1; */
1913 
1914  /* filled when used */
1915  __wcardtab = (struct wcard_t *)
1916   __my_malloc((MAXUPRTS + 1)*sizeof(struct wcard_t));
1917 
1918  __prpstk = (struct st_t **) __my_malloc(MAXPRPSTNEST*sizeof(struct st_t *));
1919  for (i = 0; i < MAXPRPSTNEST; i++) __prpstk[i] = NULL;
1920 
1921  __btndstk = (struct bt_t **) __my_malloc(MAXBTDPTH*sizeof(struct bt_t *));
1922  __btndhdrstk = (struct bt_t **) __my_malloc(MAXBTDPTH*sizeof(struct bt_t *));
1923  for (i = 0; i < MAXBTDPTH; i++) __btndstk[i] = __btndhdrstk[i] = NULL;
1924 
1925  __tmpitp_freelst = NULL;
1926  __tmpip_freelst = NULL;
1927 
1928  __last_libmdp = NULL;
1929 
1930  /* SJM 01/27/04 - initializing global seed for $random and other dist */
1931  /* systfs in case uses omits the seed inout arg */
1932  /* guessing that 0 will match 2001 LRM rand generator standard */
1933  __seed = 0;
1934 
1935  __dv_fnam = __pv_stralloc(DFLTDVFNAM);
1936  __dv_fd = -1;
1937  __dv_file_size = 0;
1938  __dv_buffer = NULL;
1939  __dv_nxti = 0;
1940 
1941  /* BEWARE - since this table reallocated for cgen access must index */
1942  /* not use address ptr because when reallated to grow ptr will be wrong */
1943  __tevtab = (struct tev_t *) __my_malloc(2048*sizeof(struct tev_t));
1944  /* do not need to initialize because freed and reused where init needed */
1945  __size_tevtab = 2048;
1946 
1947  /* pre-allocate design wide constant table and set some fixed values */
1948  __setup_contab();
1949 
1950  /* no var storage value table until prep */
1951  __wtab = NULL;
1952  __wtabwsiz = -1;
1953  __wtabwi = -1;
1954 
1955  __btab = NULL;
1956  __btabbsiz = -1;
1957  __btabbi = -1;
1958 
1959  __nchgbtab = NULL;
1960  __nchgbtabbsiz = -1;
1961  __nchgbtabbi = -1;
1962 
1963  /* least first one unused */
1964  __numused_tevtab = 0;
1965  /* need to set tev list empty because need to allocate for action cbs */
1966  /* this makes sure at start event table empty */
1967  __tefreelsti = -1;
1968 
1969  /* set ticks long structs - 16 (built into lang.) by word64 values */
1970  __itoticks_tab[0] = 1ULL;
1971  u = 10ULL;
1972  for (i = 1; i < 16; i++)
1973   {
1974    p = u *__itoticks_tab[i - 1];
1975    __itoticks_tab[i] = p;
1976   }
1977  __tim_zero = 0ULL;
1978  /* initialize multichannel descriptor table */
1979  /* notice on reset will be overwritten */
1980  /* SJM 03/26/00 - 32 is unusable for new Verilog 2000 file I/O but */
1981  /* init here so wil show as not open */
1982  for (i = 2; i < 32; i++)
1983   {
1984    __mulchan_tab[i].mc_s = NULL;
1985    __mulchan_tab[i].mc_fnam = NULL;
1986   }
1987  /* desc. 0 is hardwired as stdout and 1 to stderr */
1988  __mulchan_tab[0].mc_s = stdout;
1989  __mulchan_tab[0].mc_fnam = __pv_stralloc("stdout");
1990  __mulchan_tab[1].mc_s = stderr;
1991  __mulchan_tab[1].mc_fnam = __pv_stralloc("stderr");
1992 
1993  /* AIV 09/05/03 - initialization code for new P1364 2001 fileio streams */
1994  /* SJM 09/05/03 - rewrote to match mulchan I/O program organization */
1995 
1996  /* use first free with closing and freeing algorithm per Unix and mcds */
1997  /* SJM 05/17/04 - LOOKATME - stdio.h 16 value is wrong - trying 1024 */
1998  __fio_fdtab = (struct fiofd_t **)
1999   __my_malloc(MY_FOPEN_MAX*sizeof(struct fiofd_t *));
2000 
2001  for (i = 0; i < MY_FOPEN_MAX; i++) __fio_fdtab[i] = NULL;
2002 
2003  /* numbers probably same as unix but LRM requires predefined 0,1,2 */
2004  __fio_fdtab[0] = (struct fiofd_t *) __my_malloc(sizeof(struct fiofd_t));
2005  __fio_fdtab[0]->fd_error = FALSE;
2006  /* name only needed for user opened in case stdio fopen fails */
2007  __fio_fdtab[0]->fd_name = __pv_stralloc("stdin");
2008  __fio_fdtab[0]->fd_s = stdin;
2009 
2010  __fio_fdtab[1] = (struct fiofd_t *) __my_malloc(sizeof(struct fiofd_t));
2011  __fio_fdtab[1]->fd_error = FALSE;
2012  __fio_fdtab[1]->fd_name = __pv_stralloc("stdout");
2013  __fio_fdtab[1]->fd_s = stdout;
2014 
2015  __fio_fdtab[2] = (struct fiofd_t *) __my_malloc(sizeof(struct fiofd_t));
2016  __fio_fdtab[2]->fd_error = FALSE;
2017  __fio_fdtab[2]->fd_name = __pv_stralloc("stdout");
2018  __fio_fdtab[2]->fd_s = stdout;
2019 
2020  __fiolp = NULL;
2021  __fiofp = NULL;
2022  __scanf_pos = -1;
2023 
2024  /* start with no array for ncomp elements */
2025  __ncablk_nxti = -1;
2026  __hdr_ncablks =  NULL;
2027  __cpblk_nxti = -1;
2028  __hdr_cpblks = NULL;
2029  __cppblk_nxti = -1;
2030  __hdr_cppblks = NULL;
2031  __tnblk_nxti = -1;
2032  __hdr_tnblks = NULL;
2033 
2034  /* initialize the vpi_ variables - reset must leave */
2035  __vpi_hfree_hdr = NULL;
2036  __vpi_hrecfree_hdr = NULL;
2037  __have_vpi_actions = FALSE;
2038  __have_vpi_gateout_cbs = FALSE;
2039  /* normal mode is not free iterator handles unless user does explicitly */
2040  __wrkval_buflen = 0;
2041 
2042  __num_vpi_force_cbs = 0;
2043  __vpi_force_cb_always = FALSE;
2044  __vpi_rel_cb_always = FALSE;
2045  __num_vpi_rel_cbs = 0;
2046  /* SJM 07/24/00 - add flag so no all force/rel vc reentry - off until call */
2047  __allforce_cbs_off = FALSE;
2048  __allrel_cbs_off = FALSE;
2049 
2050  __vpi_cbrec_hdr = NULL;
2051  __errorcb_suppress_msg = FALSE;
2052  /* debugging values - set when vpi dump obj routine called */
2053  __cur_vpi_inst = NULL;
2054  __cur_vpi_obj = NULL;
2055  __cbvc_causing_dcep = NULL;
2056  __in_vpi_errorcb = FALSE;
2057  __acc_vpi_erroff = FALSE;
2058  __ithtsiz = 0;
2059  __ithtab = NULL;
2060  __ithrectab = NULL;
2061  __ithtsiz2 = 0;
2062  __ithtab2 = NULL;
2063  __ithrectab2 = NULL;
2064 
2065  __vpicb_tehdri = (i_tev_ndx *)
2066   __my_malloc((TOPVPIVAL + 1)*sizeof(i_tev_ndx));
2067  __vpicb_teendi = (i_tev_ndx *)
2068   __my_malloc((TOPVPIVAL + 1)*sizeof(i_tev_ndx));
2069  for (i = 0; i <= TOPVPIVAL; i++)
2070   __vpicb_tehdri[i] = __vpicb_teendi[i] = -1;
2071 
2072  __rosync_slot = FALSE;
2073  __tehdr_rosynci = __teend_rosynci = -1;
2074  __vpifnam_ind = 0;
2075  __vpilin_cnt = 0;
2076 
2077  /* must allocate first block */
2078  __hdr_cpnblks = (struct cpnblk_t *) __my_malloc(sizeof(struct cpnblk_t));
2079  __hdr_cpnblks->cpnblknxt = NULL;
2080  __hdr_cpnblks->cpnblks = __hdr_cpnblks->cpn_start_sp
2081   = __my_malloc(BIG_ALLOC_SIZE);
2082  __hdr_cpnblks->cpn_end_sp = __hdr_cpnblks->cpn_start_sp + BIG_ALLOC_SIZE - 16;
2083 
2084 }
2085 
2086 /*
2087  * initialize cfg globals
2088  *
2089  * CFG FIXME - just add to init glb do not need routine
2090  */
init_cfg(void)2091 static void init_cfg(void)
2092 {
2093 }
2094 
2095 /*
2096  * OPTION AND COMMAND FILE ARGUMENT PROCESSING ROUTINES
2097  */
2098 
2099 /* these must be positive word32 up to 16 bit values - gaps ok */
2100 #define CO_HELP 1
2101 #define CO_F 2
2102 #define CO_LOG 3
2103 #define CO_KEY 4
2104 #define CO_IAINPUT 5
2105 #define CO_VERB 6
2106 #define CO_QUIET 7
2107 #define CO_MAXERRS 8
2108 #define CO_C 9
2109 #define CO_PARSEONLY 10
2110 #define CO_D 11
2111 #define CO_A 12
2112 #define CO_AOFF 13
2113 #define CO_X 14
2114 #define CO_STOP 15
2115 #define CO_E 16
2116 #define CO_W 17
2117 #define CO_INFORM 18
2118 #define CO_UC 19
2119 #define CO_V 20
2120 #define CO_Y 21
2121 #define CO_LBVERB 22
2122 #define CO_LIBORD 23
2123 #define CO_LIBRESCAN 24
2124 #define CO_LIBNOHIDE 25
2125 #define CO_DEBUG 26
2126 #define CO_MINDEL 27
2127 #define CO_TYPDEL 28
2128 #define CO_MAXDEL 29
2129 /* options than need to be changed to system tasks */
2130 /* also $cleartrace here */
2131 #define CO_SETTRACE 30
2132 #define CO_SETEVTRACE 31
2133 #define CO_SETPTHTRACE 32
2134 #define CO_TRACEFILE 33
2135 /* this uses assumed lengths - if change option name must change consts */
2136 /* also not in normal table */
2137 #define CO_LBEXT 34
2138 #define CO_SUPPWARNS 35
2139 #define CO_DEFINE 36
2140 #define CO_INCDIR 37
2141 #define CO_GATE_EATER 38
2142 #define CO_NO_GATE_EATER 39
2143 #define CO_PRTSTATS 40
2144 #define CO_PRTALLSTATS 41
2145 #define CO_SPIKEANAL 42
2146 #define CO_SDFANNOTATE 43
2147 #define CO_SDFVERB 44
2148 #define CO_NOIACT 45
2149 #define CO_NOSPFY 46
2150 #define CO_NOTCHKS 47
2151 #define CO_LIBNOCELL 48
2152 
2153 
2154 #define CO_SHOWCANCELE 51
2155 #define CO_NOSHOWCANCELE 52
2156 #define CO_PULSEX_ONEVENTE 53
2157 #define CO_PULSEX_ONDETECT 54
2158 #define CO_WARNCANCELE 55
2159 #define CO_NOWARNCANCELE 56
2160 #define CO_RMGATEPND0S 57
2161 #define CO_NORMPTHPND0S 58
2162 #define CO_NOKEEPCOMMANDS 59
2163 #define CO_PLIKEEPSRC 60
2164 #define CO_OPT_SIM 61
2165 #define CO_OPT_DEBUG 62
2166 #define CO_SNAPSHOT 63
2167 #define CO_FRSPICE 64
2168 #define CO_SWITCHVERB 65
2169 #define CO_CHG_PORTDIR 66
2170 #define CO_NB_NOSEP_QUEUE 67
2171 #define CO_SDF_LOG 68
2172 #define CO_SDF_NO_ERRS 69
2173 #define CO_SDF_NO_WARNS 70
2174 #define CO_LOADPLI1 71
2175 #define CO_LOADVPI 72
2176 #define CO_LIBLIST 73
2177 #define CO_LIBMAP 74
2178 
2179 /* command line option table */
2180 /* this does not need to be alphabetical */
2181 /* single token but parsed options not here */
2182 static struct namlst_t cmdopts[] = {
2183  { CO_HELP, "-h" },
2184  { CO_HELP, "-H" },
2185  { CO_HELP,  "-?" },
2186  { CO_F , "-f" },
2187  { CO_LOG, "-l" },
2188  { CO_SDF_LOG, "+sdf_log_file" },
2189  { CO_KEY, "-k" },
2190  { CO_IAINPUT, "-i" },
2191  { CO_VERB, "+verbose" },
2192  { CO_QUIET, "-q" },
2193  { CO_MAXERRS, "+maxerrors" },
2194  { CO_C, "-c" },
2195  { CO_PARSEONLY, "+parseonly" },
2196  { CO_D, "-d" },
2197  { CO_A, "-a" },
2198  { CO_AOFF, "-aoff" },
2199  { CO_X, "-x" },
2200  { CO_STOP,  "-s" },
2201  { CO_E , "-e" },
2202  { CO_W , "-w" },
2203  { CO_INFORM,  "-informs" },
2204  { CO_UC, "-u"},
2205  { CO_V, "-v" },
2206  { CO_Y, "-y" },
2207  { CO_LBVERB, "+libverbose" },
2208  { CO_LIBORD, "+liborder" },
2209  { CO_LIBRESCAN, "+librescan" },
2210  { CO_LIBNOHIDE, "+libnohide" },
2211  { CO_DEBUG, "+debug" },
2212  { CO_MINDEL, "+mindelays" },
2213  { CO_TYPDEL , "+typdelays" },
2214  { CO_MAXDEL , "+maxdelays" },
2215  { CO_SETTRACE, "-t" },
2216  { CO_SETEVTRACE, "-et" },
2217  { CO_SETPTHTRACE, "-pt" },
2218  { CO_TRACEFILE, "+tracefile" },
2219  { CO_NO_GATE_EATER, "+nogateeater" },
2220  { CO_GATE_EATER, "+gateeater" },
2221  { CO_PRTSTATS, "+printstats" },
2222  { CO_PRTALLSTATS, "+printallstats" },
2223  { CO_SDFANNOTATE, "+sdfannotate" },
2224  { CO_SDFANNOTATE, "+sdf_annotate" },
2225  { CO_SDFVERB, "+sdfverbose" },
2226  { CO_SDFVERB, "+sdf_verbose" },
2227  { CO_NOIACT, "+nointeractive" },
2228  { CO_NOSPFY, "+nospecify" },
2229  { CO_NOTCHKS, "+notimingchecks" },
2230  { CO_NOTCHKS, "+notimingcheck" },
2231  { CO_LIBNOCELL, "+libnocell" },
2232  { CO_SPIKEANAL, "+spikes" },
2233  { CO_SHOWCANCELE, "+show_canceled_e" },
2234  { CO_NOSHOWCANCELE, "+noshow_canceled_e" },
2235  { CO_PULSEX_ONEVENTE, "+pulse_e_style_onevent" },
2236  { CO_PULSEX_ONDETECT, "+pulse_e_style_ondetect" },
2237  { CO_WARNCANCELE, "+warn_canceled_e" },
2238  { CO_NOWARNCANCELE, "+nowarn_canceled_e" },
2239  { CO_RMGATEPND0S, "+remove_gate_0delays" },
2240  { CO_NORMPTHPND0S, "+noremove_path_0delays" },
2241  { CO_NOKEEPCOMMANDS, "+nokeepcommands" },
2242  { CO_OPT_SIM, "+optimized_sim" },
2243  { CO_OPT_SIM, "-O" },
2244  { CO_OPT_DEBUG, "+Odebug" },
2245  { CO_SNAPSHOT, "+snapshot" },
2246  { CO_FRSPICE, "+fromspice" },
2247  { CO_SWITCHVERB, "+switchverbose" },
2248  { CO_CHG_PORTDIR, "+change_port_type" },
2249  { CO_NB_NOSEP_QUEUE, "+no_separate_nb_queue" },
2250  { CO_SDF_NO_ERRS, "+sdf_noerrors" },
2251  { CO_SDF_NO_WARNS, "+sdf_nowarns" },
2252  { CO_LIBLIST, "-L"},
2253  { CO_LIBMAP, "+config"}
2254 };
2255 #define NCMDOPTS (sizeof(cmdopts) / sizeof(struct namlst_t))
2256 
2257 /*
2258  * build command option linked list
2259  *
2260  * only fatal errors here since still no log file
2261  */
xpnd_args(int32 argc,char ** argv)2262 static void xpnd_args(int32 argc, char **argv)
2263 {
2264  register int32 i;
2265  int32 oi;
2266  struct optlst_t *olp;
2267  char *chp;
2268 
2269  /* first convert arg list to option list */
2270  /* know argv[0] is name of program */
2271  /* for command args "file" name is [arg] and lin cnt is arg. no. */
2272  /* 0 is [arg] and later none, and 1 is stdin */
2273  __opt_hdr = __opt_end = NULL;
2274  __last_inf = -1;
2275  __add_infil("[args]");
2276  __cur_fnam = __in_fils[__last_inf];
2277  /* for command number, location indicator - literal index for this */
2278  __add_infil("CMD");
2279  __cmd_ifi = __last_inf;
2280 
2281  for (olp = NULL, i = 1; i < argc; i++)
2282   {
2283    if ((int32) strlen(argv[i]) >= IDLEN - 1)
2284     {
2285      __lin_cnt = i;
2286      __pv_ferr(919, "command argument too long (%d) - ignored", IDLEN - 1);
2287      continue;
2288     }
2289    olp = alloc_optlst();
2290    if (__opt_end == NULL) __opt_hdr = __opt_end = olp;
2291    else { __opt_end->optlnxt = olp; __opt_end = olp; }
2292    olp->opt = __pv_stralloc(argv[i]);
2293    /* level is 0 for top */
2294    olp->optlev = 0;
2295    /* this must be index of args */
2296    olp->optfnam_ind = 0;
2297    olp->optlin_cnt = i;
2298   }
2299 
2300  /* repeatedly pass through list and expand good -fs */
2301  copy_xpnd_onelev_args();
2302  /* DBG --- notice no debug flag at this point ---
2303  dmp_xpnd_olist(__opt_hdr);
2304  --- */
2305 
2306  /* final step sets some pointers for special options into tab */
2307  for (olp = __opt_hdr; olp != NULL; olp = olp->optlnxt)
2308   {
2309    chp = olp->opt;
2310    if (olp->is_bmark || olp->is_emark) continue;
2311 
2312    if (*chp == '+' || *chp == '-')
2313     {
2314      oi = find_opt(chp);
2315      olp->optnum = oi;
2316      /* notice - algorithm is to use last if repeated */
2317      switch (oi) {
2318       case CO_LOG: __log_olp = olp; break;
2319       case CO_HELP: __help_olp = olp; break;
2320       case CO_QUIET: __quiet_olp = olp; break;
2321       case CO_VERB: __verb_olp = olp; break;
2322      }
2323     }
2324   }
2325 }
2326 
2327 /*
2328  * allocate and initialize an option list element
2329  */
alloc_optlst(void)2330 static struct optlst_t *alloc_optlst(void)
2331 {
2332  struct optlst_t *olp;
2333 
2334  olp = (struct optlst_t *) __my_malloc(sizeof(struct optlst_t));
2335  olp->opt = NULL;
2336  olp->optnum = 0;
2337  olp->optlev = 0;
2338  olp->is_bmark = FALSE;
2339  olp->is_emark = FALSE;
2340  olp->is_argv = FALSE;
2341  olp->argv_done = FALSE;
2342  olp->optfnam_ind = 0;
2343  olp->optlin_cnt = -1;
2344  olp->optlnxt = NULL;
2345  return(olp);
2346 }
2347 
2348 /*
2349  * copy from 1 level from hdr liast to new list
2350  */
copy_xpnd_onelev_args(void)2351 static void copy_xpnd_onelev_args(void)
2352 {
2353  register struct optlst_t *olp;
2354  int32 savlast_inf, savlin_cnt, some_expanded, lev;
2355  struct optlst_t *olp2, *new_olp;
2356  FILE *opt_s;
2357  char *chp;
2358 
2359  __new_opt_end = __new_opt_hdr = NULL;
2360  for (lev = 1;; lev++)
2361   {
2362    some_expanded = FALSE;
2363    for (olp = __opt_hdr; olp != NULL;)
2364     {
2365      /* anything but -f just remains in list */
2366      /* optnum only CO_F if previous error */
2367      if (olp->is_bmark || olp->is_emark
2368        || strcmp(olp->opt, "-f") != 0 || olp->optnum == CO_F)
2369       {
2370        olp2 = olp->optlnxt;
2371        if (__new_opt_end == NULL) __new_opt_hdr = __new_opt_end = olp;
2372        else { __new_opt_end->optlnxt = olp; __new_opt_end = olp; }
2373        olp->optlnxt = NULL;
2374        olp = olp2;
2375        continue;
2376       }
2377      /* logic to possibly (if can be opened) a -f [file] element */
2378      olp2 = olp->optlnxt;
2379 
2380      if (olp2 == NULL) { olp->optnum = CO_F; break; }
2381      chp = olp2->opt;
2382 
2383      /* if cannot open, or not followed by file name, leave - error later */
2384      /* but leave both -f and [arg] but move 1 past arg */
2385      if (chp == NULL || *chp == '+' || *chp == '-'
2386       || (opt_s = __tilde_fopen(chp, "r")) == NULL)
2387       {
2388        olp->optnum = CO_F;
2389        if (__new_opt_end == NULL) __new_opt_hdr = __new_opt_end = olp;
2390        else { __new_opt_end->optlnxt = olp; __new_opt_end = olp; }
2391        __new_opt_end->optlnxt = olp2;
2392        __new_opt_end = olp2;
2393        olp = olp2->optlnxt;
2394        olp2->optlnxt = NULL;
2395        continue;
2396       }
2397 
2398      /* move olp one past -f and [file name] */
2399      olp = olp2->optlnxt;
2400      __add_infil(chp);
2401      __cur_fnam = __in_fils[__last_inf];
2402      savlin_cnt =  __lin_cnt;
2403      savlast_inf = __last_inf;
2404      __lin_cnt = 1;
2405 
2406      /* add beginning marker */
2407      ins_optlst_marker(TRUE, lev);
2408      /* fill a new option list */
2409      for (;;)
2410       {
2411        if ((__toktyp = __get_cmdtok(opt_s)) == TEOF) break;
2412 
2413        new_olp = alloc_optlst();
2414        if (__new_opt_end == NULL) __new_opt_hdr = __new_opt_end = new_olp;
2415        else { __new_opt_end->optlnxt = new_olp; __new_opt_end = new_olp; }
2416        new_olp->opt = __pv_stralloc(__token);
2417        new_olp->optlev = lev;
2418        new_olp->optfnam_ind = __last_inf;
2419        new_olp->optlin_cnt = __lin_cnt;
2420        some_expanded = TRUE;
2421       }
2422      /* add end marker */
2423      ins_optlst_marker(FALSE, lev);
2424      __my_fclose(opt_s);
2425      __cur_fnam = __in_fils[savlast_inf];
2426      __lin_cnt = savlin_cnt;
2427     }
2428    /* DBG --- no debug flag at this point ---
2429    dmp_xpnd_olist(__new_opt_hdr);
2430    --- */
2431    __opt_hdr = __new_opt_hdr;
2432    __opt_end = __new_opt_end;
2433    if (!some_expanded) break;
2434    __new_opt_hdr = __new_opt_end = NULL;
2435   }
2436  /* DBG remove --- no debug flag at this point ---
2437  dmp_xpnd_olist(__opt_hdr);
2438  --- */
2439 }
2440 
2441 /*
2442  * insert a marker
2443  */
ins_optlst_marker(int32 is_bmark,int32 lev)2444 static void ins_optlst_marker(int32 is_bmark, int32 lev)
2445 {
2446  struct optlst_t *new_olp;
2447 
2448  /* this also initializes */
2449  new_olp = alloc_optlst();
2450  if (__new_opt_end == NULL) __new_opt_hdr = __new_opt_end = new_olp;
2451  else { __new_opt_end->optlnxt = new_olp; __new_opt_end = new_olp; }
2452  /* must not be seen as input file */
2453  new_olp->optnum = -2;
2454  if (is_bmark) new_olp->is_bmark = TRUE;
2455  else new_olp->is_emark = TRUE;
2456  new_olp->optlev = lev;
2457  new_olp->optfnam_ind = __last_inf;
2458  new_olp->optlin_cnt = __lin_cnt;
2459 }
2460 
2461 /*
2462  * dump expanded option list
2463  */
dmp_xpnd_olist(register struct optlst_t * olp)2464 static void dmp_xpnd_olist(register struct optlst_t *olp)
2465 {
2466  int32 olnum;
2467 
2468  if (olp == NULL)
2469   {
2470    __dbg_msg("&& argument list empty.\n");
2471    return;
2472   }
2473  __dbg_msg("&&& start of expanded argument list dump.\n");
2474  for (olnum = 1; olp != NULL; olp = olp->optlnxt, olnum++)
2475   {
2476    if (olp->is_bmark || olp->is_emark)
2477     {
2478      if (olp->is_bmark)
2479       {
2480        __dbg_msg(">> no. %d lev %d: BEGIN MARK at %s\n", olnum, olp->optlev,
2481         __bld_lineloc(__xs, olp->optfnam_ind, olp->optlin_cnt));
2482       }
2483      else
2484       {
2485        __dbg_msg("<< no. %d lev %d: END MARK at %s\n", olnum, olp->optlev,
2486        __bld_lineloc(__xs, olp->optfnam_ind, olp->optlin_cnt));
2487       }
2488     }
2489    else
2490     {
2491      __dbg_msg("&& no. %d level %d: %s (value %d) at %s\n", olnum,
2492       olp->optlev, olp->opt, olp->optnum, __bld_lineloc(__xs,
2493       olp->optfnam_ind, olp->optlin_cnt));
2494     }
2495   }
2496  __dbg_msg("&&& expanded argument list end.\n");
2497 }
2498 
2499 /*
2500  * find an option from table
2501  * scheme assume no options with arguments but directions can have arguments
2502  * assuming then end with ;
2503  */
find_opt(char * aval)2504 static int32 find_opt(char *aval)
2505 {
2506  register int32 i;
2507 
2508  /* first search for normal option (if arg white space separated) */
2509  for (i = 0; i < NCMDOPTS; i++)
2510   {
2511    if (strcmp(aval, cmdopts[i].lnam) == 0) return((int32) cmdopts[i].namid);
2512   }
2513  /* notice these special options are not in cmdopts table */
2514  if (strncmp(aval, "+libext+", 8) == 0) return(CO_LBEXT);
2515  if (strncmp(aval, "+incdir+", 8) == 0) return(CO_INCDIR);
2516  if (strncmp(aval, "+suppress_warns+", 16) == 0) return(CO_SUPPWARNS);
2517  if (strncmp(aval, "+define+", 8) == 0) return(CO_DEFINE);
2518  /* notice next 2 unusual because use = instead of + since only one pair */
2519  if (strncmp(aval, "+loadpli1=", 10) == 0) return(CO_LOADPLI1);
2520  if (strncmp(aval, "+loadvpi=", 9) == 0) return(CO_LOADVPI);
2521  return(-1);
2522 }
2523 
2524 /*
2525  * open log file (need if at all possible)
2526  */
open_logfile(void)2527 static void open_logfile(void)
2528 {
2529  char *chp;
2530  struct optlst_t *arg_olp;
2531  char s1[RECLEN];
2532 
2533  strcpy(s1, DFLT_LOGFNAM);
2534  __save_log_s = NULL;
2535  if (__log_olp != NULL)
2536   {
2537    arg_olp = __log_olp->optlnxt;
2538    if (arg_olp != NULL) chp = arg_olp->opt; else chp = NULL;
2539    if (chp == NULL || *chp == '+' || *chp == '-')
2540     {
2541      __gfwarn(505, __log_olp->optfnam_ind, __log_olp->optlin_cnt,
2542       "-l option not followed by log file name - %s used", DFLT_LOGFNAM);
2543      goto no_explicit;
2544     }
2545    /* must mark so not seen as input file */
2546    arg_olp->optnum = -2;
2547    if ((__log_s = __tilde_fopen(chp, "w")) == NULL)
2548     {
2549      __gfwarn(505, arg_olp->optfnam_ind, arg_olp->optlin_cnt,
2550       "cannot open -l log file %s - trying default", chp);
2551      goto no_explicit;
2552     }
2553    __log_fnam = __pv_stralloc(chp);
2554    goto done;
2555   }
2556 
2557 no_explicit:
2558  if ((__log_s = __tilde_fopen(s1, "w")) == NULL)
2559   {
2560    __pv_fwarn(505, "cannot open default log file %s - no log file", s1);
2561    return;
2562   }
2563  else __log_fnam = __pv_stralloc(s1);
2564 
2565 done:;
2566  /* SM 03/26/00 - 2 (bit 4) no longer used for log file - lumped in with 1 */
2567  /* ---
2568  __mulchan_tab[2].mc_s = __log_s;
2569  --- */
2570  /* know this is closed so no previous name to free */
2571  /* ---
2572  __mulchan_tab[2].mc_fnam = __pv_stralloc(__log_fnam);
2573  --- */
2574 }
2575 
2576 /*
2577  * read command line args
2578  */
do_args(void)2579 static void do_args(void )
2580 {
2581  register struct optlst_t *olp;
2582  int32 oi, tmp, len;
2583  FILE *f;
2584  struct optlst_t *sav_olp;
2585  struct loadpli_t *ldp;
2586  struct mapfiles_t *mapfp;
2587  char *chp, *chp2, *chp3;
2588  char s1[2*RECLEN];
2589 
2590  /* notice for options with arguments must mark arg as -2 or will be */
2591  /* seen as input file */
2592  for (olp = __opt_hdr; olp != NULL;)
2593   {
2594    /* ignore markers added for building vpi argc/argv */
2595    if (olp->is_bmark || olp->is_emark)
2596     { olp = olp->optlnxt; continue; }
2597 
2598    chp = olp->opt;
2599    /* no + or -, ignore for now - next pass add to file list */
2600    if (*chp != '-' && *chp != '+') { olp = olp->optlnxt; continue; }
2601 
2602    /* unrecognized +/-, if -, warning, else inform */
2603    if (olp->optnum == -1)
2604     {
2605      if (strlen(chp) == 1)
2606       {
2607        __gfwarn(506, olp->optfnam_ind, olp->optlin_cnt,
2608         "%s option prefix without following option name illegal - ignored",
2609          chp);
2610        olp = olp->optlnxt;
2611        continue;
2612       }
2613 
2614      if (*chp == '-')
2615       __gfwarn(506, olp->optfnam_ind, olp->optlin_cnt,
2616        "unrecogized option %s - ignored ", olp->opt);
2617      else __gfinform(410, olp->optfnam_ind, olp->optlin_cnt,
2618       "assuming unrecognized option %s for pli or other simulator",
2619       olp->opt);
2620 
2621      olp = olp->optlnxt;
2622      continue;
2623     }
2624    oi = olp->optnum;
2625    switch (oi) {
2626     /* ignore already processed */
2627     case CO_LOG: case CO_HELP: case CO_QUIET: case CO_VERB: break;
2628     /* if was not able to open nest file error here */
2629     case CO_F:
2630      /* if -f option expanded - will be removed before here */
2631      /* left only if error (cannot open file) */
2632      if (olp->optlnxt == NULL)
2633       {
2634        __gferr(920, olp->optfnam_ind, olp->optlin_cnt,
2635         "-f include argument not followed by file name");
2636        continue;
2637       }
2638      olp = olp->optlnxt;
2639      /* -f not followed by file name in nested -f file */
2640      if (olp->is_emark)
2641       {
2642        /* here may have long list of emarks that must be skipped */
2643        __gferr(920, olp->optfnam_ind, olp->optlin_cnt,
2644         "nested -f include argument not followed by file name");
2645        break;
2646       }
2647      __gferr(920, olp->optfnam_ind, olp->optlin_cnt,
2648       "cannot open -f include argument file %s", olp->opt);
2649      olp->optnum = -2;
2650      break;
2651 
2652     /* options followed by 1 white space separated argument */
2653     case CO_IAINPUT:
2654      sav_olp = olp;
2655      olp = olp->optlnxt;
2656      if (olp != NULL) chp = olp->opt;
2657      if (olp == NULL || olp->is_emark || chp == NULL || *chp == '+'
2658       || *chp == '-')
2659       {
2660        __gfwarn(505, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2661         "-i option not followed by startup interactive input file name");
2662        continue;
2663       }
2664      olp->optnum = -2;
2665      /* make sure it can be opened */
2666      if ((f = __tilde_fopen(chp, "r")) == NULL)
2667       {
2668        __gfwarn(505, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2669         "cannot open -i startup interactive input file %s - input from stdin",
2670         chp);
2671        break;
2672       }
2673      __my_fclose(f);
2674      __cmd_start_fnam = __pv_stralloc(chp);
2675      if (__verbose)
2676       __cv_msg("  Startup interactive input will be read from file \"%s\".\n",
2677        __cmd_start_fnam);
2678      break;
2679     case CO_KEY:
2680      sav_olp = olp;
2681      olp = olp->optlnxt;
2682      if (olp != NULL) chp = olp->opt;
2683      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2684       {
2685        __gfwarn(505, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2686         "-k option not followed by file name for transcript of typed keys");
2687        continue;
2688       }
2689      olp->optnum = -2;
2690      __gfwarn(621, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2691       "-k option no effect - key files not supported (use $input scripts)");
2692      /* only open if needed (must go in malloc as separate) */
2693      break;
2694     case CO_TRACEFILE:
2695      sav_olp = olp;
2696      olp = olp->optlnxt;
2697      if (olp != NULL) chp = olp->opt;
2698      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2699       {
2700        __gfwarn(509, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2701        "+tracefile option not followed by file name - previous (stdout?) used");
2702        continue;
2703       }
2704      olp->optnum = -2;
2705      /* only open when tracing enabled */
2706      if (strcmp(chp, "STDOUT") == 0) strcpy(chp, "stdout");
2707      if (__tr_fnam != NULL) __my_free(__tr_fnam, strlen(__tr_fnam) + 1);
2708      __tr_fnam = __pv_stralloc(chp);
2709      __tr_s = NULL;
2710      if (__verbose)
2711       __cv_msg(
2712        "  Statement and/or event trace output will be written to file \"%s\".\n",
2713        __tr_fnam);
2714       /* in case -t or -et precedes this option open now */
2715      if (__st_tracing || __ev_tracing || __pth_tracing) __maybe_open_trfile();
2716      break;
2717     case CO_SDF_LOG:
2718      sav_olp = olp;
2719      olp = olp->optlnxt;
2720      if (olp != NULL) chp = olp->opt;
2721      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2722       {
2723        __gfwarn(505, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2724         "+sdf_log_file setting option not followed by file name");
2725        continue;
2726       }
2727      olp->optnum = -2;
2728      if (__sdf_opt_log_fnam != NULL)
2729       __my_free(__sdf_opt_log_fnam, strlen(__sdf_opt_log_fnam) + 1);
2730      __sdf_opt_log_fnam = __pv_stralloc(chp);
2731 
2732      if (__verbose)
2733       {
2734        __cv_msg(
2735         "  SDF messages and errors will be written to separate SDF log file %s.\n",
2736         __sdf_opt_log_fnam);
2737       }
2738      break;
2739     case CO_SDFANNOTATE:
2740      sav_olp = olp;
2741      olp = olp->optlnxt;
2742      if (olp != NULL) chp = olp->opt;
2743      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2744       {
2745        __gfwarn(593, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2746         "+sdf_annotate option not followed by [file][+<optional scope name>] - ignored");
2747        continue;
2748       }
2749      olp->optnum = -2;
2750      do_sdflocdef(chp, __in_fils[sav_olp->optfnam_ind], sav_olp->optlin_cnt);
2751      break;
2752     case CO_MAXERRS:
2753      sav_olp = olp;
2754      olp = olp->optlnxt;
2755      if (olp != NULL) chp = olp->opt;
2756      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2757       {
2758 bad_maxerrs:
2759        __gfwarn(502, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2760         "maximum error number must be 0 (no limit) or positive");
2761        continue;
2762       }
2763      olp->optnum = -2;
2764      if (sscanf(chp, "%d", &tmp) != 1 || tmp < 0) goto bad_maxerrs;
2765      __max_errors = tmp;
2766      if (__max_errors != 0 && __verbose)
2767       __cv_msg(
2768        "  Translation will stop after %d errors instead of default %d.\n",
2769        __max_errors, MAX_ERRORS);
2770      else
2771       {
2772        if (__verbose)
2773         __cv_msg("  Default error termination limit disabled.\n");
2774       }
2775      break;
2776 #ifdef __CVLIC__
2777     case CO_LICPTH:
2778      sav_olp = olp;
2779      olp = olp->optlnxt;
2780      if (olp != NULL) chp = olp->opt;
2781      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2782       {
2783        __gfwarn(502, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2784         "+licpath option not followed by required [path] - ignored");
2785        continue;
2786       }
2787      olp->optnum = -2;
2788      __lic_path = __pv_stralloc(chp);
2789      if (__verbose)
2790       {
2791        __cv_msg(
2792         "  License authorization file cver.lic searched for in directory \"%s\".\n",
2793         __lic_path);
2794       }
2795      break;
2796 #endif
2797     case CO_V:
2798      sav_olp = olp;
2799      olp = olp->optlnxt;
2800      if (olp != NULL) chp = olp->opt;
2801      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2802       {
2803        __gfwarn(501, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2804         "-v library file option not followed by file name - ignored");
2805        continue;
2806       }
2807      olp->optnum = -2;
2808      if (strcmp(chp, ".") == 0 || strcmp(chp, "..") == 0)
2809       {
2810        __gfwarn(623, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2811         "-v library file %s illegal", chp);
2812       }
2813      add_lbfil(chp, 'v');
2814      if (__verbose)
2815       __cv_msg("  File \"%s\" in library from -v option.\n", chp);
2816      break;
2817     case CO_LIBLIST:
2818      /* -L library */
2819      sav_olp = olp;
2820      olp = olp->optlnxt;
2821      if (olp != NULL) chp = olp->opt;
2822      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2823       {
2824        __gfwarn(501, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2825         "-L library map file option not followed by file name - ignored");
2826        continue;
2827       }
2828      olp->optnum = -2;
2829      /* set the global name of the -L library name */
2830      __cmdl_library = __pv_stralloc(chp);
2831      if (__verbose)
2832       __cv_msg("  File \"%s\" in library from -L option.\n", chp);
2833      break;
2834     case CO_LIBMAP:
2835      /* +config [filename] */
2836      sav_olp = olp;
2837      olp = olp->optlnxt;
2838      if (olp != NULL) chp = olp->opt;
2839      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2840       {
2841        __gfwarn(501, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2842         "+config [file] library map file option not followed by file name - ignored");
2843        continue;
2844       }
2845      olp->optnum = -2;
2846 
2847      mapfp = (struct mapfiles_t *) __my_malloc(sizeof(struct mapfiles_t));
2848      mapfp->mapfnam = __pv_stralloc(chp);
2849      mapfp->mapfnxt = NULL;
2850 
2851      if (__map_files_hd == NULL) __map_files_hd = __map_files_tail = mapfp;
2852      else
2853       {
2854        __map_files_tail->mapfnxt = mapfp;
2855        __map_files_tail = mapfp;
2856       }
2857      if (__verbose)
2858       __cv_msg(
2859        "  Will read \"%s\" map lib file specified by +config [file] option.\n",
2860        mapfp->mapfnam);
2861      break;
2862     case CO_FRSPICE:
2863      break;
2864     case CO_Y:
2865      sav_olp = olp;
2866      olp = olp->optlnxt;
2867      if (olp != NULL) chp = olp->opt;
2868      if (olp == NULL || olp->is_emark || *chp == '+' || *chp == '-')
2869       {
2870        __gfwarn(593, sav_olp->optfnam_ind, sav_olp->optlin_cnt,
2871         "-y library directory option not followed by path name - ignored");
2872        continue;
2873       }
2874      olp->optnum = -2;
2875      add_lbfil(chp, 'y');
2876      if (__verbose)
2877       __cv_msg("  Directory \"%s\" searched for libraries from -y option.\n",
2878       olp->opt);
2879      break;
2880     case CO_DEFINE:
2881      chp = olp->opt;
2882      do_cmdmacdef(&(chp[8]), olp);
2883      break;
2884     case CO_INCDIR:
2885      chp2 = olp->opt;
2886      /* error message on bad format emitted inside here */
2887      if (!bld_incdtab(&(chp2[8]), olp)) break;
2888      if (__verbose)
2889       {
2890        __cv_msg(
2891         "  %s additional +incdir+ paths searched to find `include files.\n",
2892         &(olp->opt[7]));
2893       }
2894      break;
2895     case CO_LOADPLI1:
2896 #ifdef __STATIC_PLI__
2897     __gfwarn(3123, olp->optfnam_ind, olp->optlin_cnt,
2898      "+loadpli1 = option illegal when using old style statically linked cverobj.o - ignored");
2899 #else
2900      chp2 = olp->opt;
2901      if ((ldp = bld_loadpli_lbs(&(chp2[10]), olp, TRUE)) == NULL) break;
2902      if (__verbose)
2903       {
2904        /* this can't fail since know well formed */
2905        chp3 = strrchr(chp2, ':');
2906        /* DBG LINT remove -- */
2907        if (chp3 == NULL) __misc_terr(__FILE__, __LINE__);
2908        /* -- */
2909        if (strcmp(chp3, "") == 0) strcpy(__xs, "[none]");
2910        else strcpy(__xs, chp3);
2911        __cv_msg(
2912         "  +loadpli1 dynamic library %s loaded with bootstrap routine(s) %s\n",
2913         ldp->libnam, __xs);
2914       }
2915 #endif
2916      break;
2917     case CO_LOADVPI:
2918 #ifdef __STATIC_PLI__
2919     __gfwarn(3123, olp->optfnam_ind, olp->optlin_cnt,
2920      "+loadvpi= option illegal when using old style statically linked cverobj.o - ignored");
2921 #else
2922      chp2 = olp->opt;
2923      if ((ldp = bld_loadpli_lbs(&(chp2[9]), olp, FALSE)) == NULL) break;
2924      if (__verbose)
2925       {
2926        /* this can't fail since know well formed */
2927        chp3 = strrchr(chp2, ':');
2928        /* DBG LINT remove -- */
2929        if (chp3 == NULL) __misc_terr(__FILE__, __LINE__);
2930        /* -- */
2931        if (strcmp(chp3, "") == 0) strcpy(__xs, "[none]");
2932        else strcpy(__xs, chp3);
2933        __cv_msg(
2934         "  +loadvpi= dynamic library %s loaded with bootstrap routine(s) %s\n",
2935         ldp->libnam, __xs);
2936       }
2937 #endif
2938      break;
2939     case CO_LBEXT:
2940      chp2 = olp->opt;
2941      if (__last_lbx != -1)
2942       {
2943        __gfwarn(598, olp->optfnam_ind, olp->optlin_cnt,
2944         "+libext+ option for -y library directories cannot be repeated - ignored");
2945        /* need to move to next option */
2946        break;
2947       }
2948 
2949      if (!bld_lbxtab(&(chp2[8]), olp)) break;
2950      if (__verbose)
2951       {
2952        __cv_msg(
2953         "  %s suffix(es) used for -y library extensions from +libext+ options.\n",
2954         &(olp->opt[7]));
2955       }
2956      break;
2957     /* options where arg is suffix of option */
2958     case CO_SUPPWARNS:
2959      chp2 = olp->opt;
2960      len = strlen(chp2);
2961      /* if optional ending plus left out - add here */
2962      if (chp2[len - 1] != '+')
2963       {
2964        /* SJM - 12/20/02 - must copy to work string because no room to add */
2965        /* plus if not added by user */
2966        strcpy(s1, chp2);
2967        s1[len] = '+'; s1[len + 1] = '\0';
2968        chp2 = s1;
2969       }
2970 
2971      /* returns F on error, so tracing for not emitted on T */
2972      if (add_suppwarn(chp2, olp))
2973       {
2974        if (__verbose)
2975         __cv_msg(
2976          "  Following warning or interactive message(s) %s will not be emitted.\n",
2977          &(chp2[16]));
2978       }
2979      break;
2980     /* options without arguments */
2981     case CO_C:
2982      if (__verbose)
2983       {
2984        __cv_msg(
2985         "  Translate only - all files and library directories will be checked.\n");
2986       }
2987      __compile_only = TRUE;
2988      break;
2989     case CO_PARSEONLY:
2990      if (__verbose)
2991       {
2992        __cv_msg(
2993         "  Parse only - for quick syntax check of separate modules.\n");
2994       }
2995      __parse_only = TRUE;
2996      break;
2997     case CO_STOP:
2998      if (__verbose)
2999       __cv_msg("  Stopping into interactive mode before simulation begins.\n");
3000      /* this is not checked until sim begins (if it does) */
3001      __stop_before_sim = TRUE;
3002      break;
3003     case CO_E:
3004      __no_errs = TRUE;
3005      if (__verbose) __cv_msg("  Error messages will not be printed.\n");
3006      break;
3007     case CO_D:
3008      __decompile = TRUE;
3009      if (__verbose)
3010       __cv_msg(
3011        "  Source after defparam expansion will be decompiled and printed.\n");
3012      break;
3013     case CO_A:
3014      if (__verbose)
3015       __cv_msg("-a accelerate option no effect - on by default.\n");
3016      break;
3017     case CO_AOFF:
3018      if (__verbose)
3019       __cv_msg("port and gate assignments will not be accelerated.\n");
3020      __accelerate = FALSE;
3021      break;
3022     case CO_X:
3023      if (__verbose)
3024       __cv_msg("-x option no effect - vector wires expanded by default.\n");
3025      break;
3026     case CO_DEBUG:
3027      __debug_flg = TRUE;
3028      if (__verbose)
3029       __cv_msg("  Debugging information will be printed.\n");
3030      break;
3031     case CO_MINDEL:
3032      __mintypmax_sel = DEL_MIN;
3033      if (__verbose)
3034       __cv_msg("  Min:typ:max expressions will use the minimum value.\n");
3035      break;
3036     case CO_TYPDEL:
3037      __mintypmax_sel = DEL_TYP;
3038      if (__verbose)
3039       __cv_msg(
3040        "  Min:typ:max expressions will use the typical value (default).\n");
3041      break;
3042     case CO_MAXDEL:
3043      __mintypmax_sel = DEL_MAX;
3044      if (__verbose)
3045       __cv_msg("  Min:typ:max expressions will use the maximum value.\n");
3046      break;
3047     case CO_SETTRACE:
3048      __st_tracing = TRUE;
3049      __maybe_open_trfile();
3050      if (__verbose)
3051       __cv_msg("  Execution of behavioral statements will be traced.\n");
3052      break;
3053     case CO_SETEVTRACE:
3054      __ev_tracing = TRUE;
3055      __maybe_open_trfile();
3056      if (__verbose) __cv_msg("  Event processing will be traced.\n");
3057      break;
3058     case CO_SETPTHTRACE:
3059      __pth_tracing = TRUE;
3060      __maybe_open_trfile();
3061      if (__verbose)
3062       __cv_msg("  Specify delay Path will be traced in detail.\n");
3063      break;
3064     case CO_GATE_EATER: case CO_NO_GATE_EATER:
3065      __gfwarn(507, olp->optfnam_ind, olp->optlin_cnt,
3066       "  +gateeater option obsolete - option ignored");
3067      break;
3068     case CO_W:
3069      __no_warns = TRUE;
3070      if (__verbose) __cv_msg("  Warning messages will not be printed.\n");
3071      break;
3072     case CO_INFORM:
3073      __no_informs = FALSE;
3074      if (__verbose) __cv_msg("  Inform messages will be printed.\n");
3075      break;
3076     case CO_UC:
3077      __gfwarn(507, olp->optfnam_ind, olp->optlin_cnt,
3078       "  -u option unsupported - input is case sensitive");
3079      break;
3080     case CO_SDFVERB:
3081      __sdf_verbose = TRUE;
3082 
3083      if (__verbose)
3084       __cv_msg("  SDF annotation tracing verbose mode is on.\n");
3085      break;
3086     case CO_SDF_NO_ERRS:
3087      __sdf_no_errs = TRUE;
3088      if (__verbose) __cv_msg("  SDF error messages will not be printed.\n");
3089      break;
3090     case CO_SDF_NO_WARNS:
3091      __sdf_no_warns = TRUE;
3092      if (__verbose) __cv_msg("  SDF warning messages will not be printed.\n");
3093      break;
3094     case CO_LBVERB:
3095      __lib_verbose = TRUE;
3096      __cfg_verbose = TRUE;
3097      if (__verbose) __cv_msg("  Library tracing verbose mode is on.\n");
3098      break;
3099     case CO_SWITCHVERB:
3100      __switch_verbose = TRUE;
3101      /* SJM 11/29/00 - message only output if verbose not switch verbose */
3102      if (__verbose)
3103       __cv_msg("  Switch channel construction verbose mode is on.\n");
3104      break;
3105     case CO_CHG_PORTDIR:
3106      /* SJM 11/29/00 - new option that changes port direction if connected */
3107      /* as inout, most designs do not need this option but some do */
3108      __chg_portdir = TRUE;
3109      if (__verbose)
3110       __cv_msg(
3111        "  Changing port type (direction) to inout for ports connected as inout.\n");
3112      break;
3113     case CO_NB_NOSEP_QUEUE:
3114      /* AIV 06/28/05 - new option that changes causes old non blocking */
3115      /* algorithm that did not have separate after pnd0 (each section) */
3116      /* event queue to be used */
3117      __nb_sep_queue = FALSE;
3118      if (__verbose)
3119       {
3120        __cv_msg(
3121         "  Using old Cver non-blocking scheduling - no separate non blocking queuel\n");
3122       }
3123      break;
3124     case CO_LIBRESCAN:
3125      __lib_rescan = TRUE;
3126      if (__verbose)
3127       __cv_msg(
3128        "  Library rescanned from beginning after every name resolved.\n");
3129      break;
3130     case CO_LIBORD:
3131      __gfwarn(503, olp->optfnam_ind, olp->optlin_cnt,
3132       "+liborder option unsupported");
3133 lib_mth:
3134      if (__verbose)
3135       __cv_msg("  Using default or +librescan library scanning method.\n");
3136      break;
3137     case CO_LIBNOHIDE:
3138      __gfwarn(594, olp->optfnam_ind, olp->optlin_cnt,
3139       "+libnohide option unsupported");
3140      goto lib_mth;
3141     case CO_PRTSTATS:
3142      __prt_stats = TRUE;
3143      if (__verbose) __cv_msg("  Design content tables will be written.\n");
3144      break;
3145     case CO_PRTALLSTATS:
3146      __prt_allstats = TRUE;
3147      if (__verbose)
3148       __cv_msg(
3149        "  Voluminous design and module content tables will be written.\n");
3150      break;
3151     case CO_SPIKEANAL:
3152      __gfwarn(591, olp->optfnam_ind, olp->optlin_cnt,
3153       "+spikes option name changed - use standardized +show_canceled_e instead");
3154      break;
3155     case CO_SHOWCANCELE:
3156      __show_cancel_e = TRUE;
3157      if (__verbose)
3158       __cv_msg("  Pulse canceled events X shown (glitches cause X output).\n");
3159      break;
3160     case CO_NOSHOWCANCELE:
3161      __show_cancel_e = FALSE;
3162      if (__verbose)
3163       __cv_msg(
3164        "  Pulse canceled events not shown (glitches removed - default).\n");
3165      break;
3166     case CO_PULSEX_ONEVENTE:
3167      __showe_onevent = TRUE;
3168      if (__verbose)
3169       __cv_msg("  Pulse shown Xs scheduled at pulse leading edge (default).\n");
3170      break;
3171     case CO_PULSEX_ONDETECT:
3172      __showe_onevent = FALSE;
3173      if (__verbose)
3174       __cv_msg("  Pulse shown Xs set when pulse (glitch) detected.\n");
3175      break;
3176     case CO_WARNCANCELE:
3177      __warn_cancel_e = TRUE;
3178      if (__verbose)
3179       __cv_msg("  Warning message emitted when pulse (glitch) detected.\n");
3180      break;
3181     case CO_NOWARNCANCELE:
3182      __warn_cancel_e = FALSE;
3183      if (__verbose)
3184       {
3185        __cv_msg(
3186         "  No warning message emitted when pulse (glitch) detected (detected).\n");
3187       }
3188      break;
3189     case CO_RMGATEPND0S:
3190      __rm_gate_pnd0s = TRUE;
3191      if (__verbose)
3192       {
3193        __cv_msg(
3194         "  All gate #0 delays converted to no delay to speed up simulation.\n");
3195       }
3196      break;
3197     case CO_NORMPTHPND0S:
3198      /* remove path pound 0 delays by default */
3199      __rm_path_pnd0s = FALSE;
3200      if (__verbose)
3201       {
3202        __cv_msg("  Disabling removal of all 0 (no effect) path delays.\n");
3203       }
3204      break;
3205     case CO_NOKEEPCOMMANDS:
3206      __history_on = FALSE;
3207      if (__verbose)
3208       {
3209        __cv_msg(
3210        "  Entered (or $input or piped in) commands not kept on history list.\n");
3211       }
3212      break;
3213     case CO_PLIKEEPSRC:
3214      if (__verbose)
3215       {
3216        __cv_msg(
3217         "  +pli_keep_source option removed - all PLI source access kept");
3218       }
3219      break;
3220     case CO_NOIACT:
3221      /* if no signal - then no interactive automatic but flag must be */
3222      /* off since still need callbacks for invoking signal handler */
3223      __no_iact = TRUE;
3224      if (__verbose)
3225       __cv_msg("  No interactive commands for this run - ^c causes finish.\n");
3226      break;
3227     case CO_SNAPSHOT:
3228      __intsig_prt_snapshot = TRUE;
3229      if (__verbose)
3230       __cv_msg(
3231        "  Activity snap shot printed upon interrupt signal (^c) termination");
3232      break;
3233     case CO_NOSPFY:
3234      __no_specify = TRUE;
3235      if (__verbose)
3236       __cv_msg("  Specify section(s) will be discarded before simulation.\n");
3237      break;
3238     case CO_NOTCHKS:
3239      __no_tchks = TRUE;
3240      if (__verbose)
3241       __cv_msg("  Timing checks will be discarded before simulation.\n");
3242      break;
3243     case CO_LIBNOCELL:
3244      __lib_are_cells = FALSE;
3245      if (__verbose)
3246       __cv_msg(
3247        "  Library modules will not be cells unless in `celldefine region.\n");
3248      break;
3249     /* just ignore if optimization not compiled in */
3250     case CO_OPT_DEBUG:
3251     case CO_OPT_SIM:
3252      __gfwarn(3121, olp->optfnam_ind, olp->optlin_cnt,
3253       " -O native assembly code simulation not enabled in this version.\n");
3254      break;
3255 
3256     default: __case_terr(__FILE__, __LINE__);
3257    }
3258    olp = olp->optlnxt;
3259   }
3260  /* some option consistency checks */
3261  if (__intsig_prt_snapshot && !__no_iact)
3262   {
3263    __pv_warn(508,
3264      "+snapshot option no effect because +nointeractive (or +compiled_sim) not selected");
3265   }
3266 }
3267 
3268 /*
3269  * build input file list after freeing list for argumnts
3270  * know now done with arguments
3271  */
bld_inflist(void)3272 static void bld_inflist(void)
3273 {
3274  register struct optlst_t *olp;
3275  struct optlst_t *olp2;
3276 
3277  /* must not free option files - need for mc scan args pli task ? */
3278  /* notice can copy because [args] and *none* same length */
3279  strcpy(__in_fils[0], "*none*");
3280  __last_optf = __last_inf;
3281 
3282  for (olp = __opt_hdr; olp != NULL; olp = olp->optlnxt)
3283   {
3284    /* -1 are unrecognized +/- options, -2 is file used as arg, > 0 is opt */
3285    /* so 0 is verilog input file */
3286    if (olp->optnum == CO_F)
3287     {
3288      olp2 = olp->optlnxt;
3289      if (olp2 != NULL) olp = olp2;
3290      continue;
3291     }
3292    /* added markers automaticaly ignored */
3293    if (olp->optnum == 0) __add_infil(olp->opt);
3294   }
3295 }
3296 
3297 /*
3298  * add an in file
3299  * used first for -f command file and then reused for source and include
3300  * files
3301  * last inf is location of new file
3302  * fatal error if more than 64k in files
3303  */
__add_infil(char * fnam)3304 extern void __add_infil(char *fnam)
3305 {
3306  if (++__last_inf >= __siz_in_fils) __grow_infils(__last_inf);
3307  __in_fils[__last_inf] = __pv_stralloc(fnam);
3308 }
3309 
3310 /*
3311  * re allocate in fils pointer table
3312  */
__grow_infils(int32 new_last)3313 extern void __grow_infils(int32 new_last)
3314 {
3315  int32 osize, nsize;
3316 
3317  /* file index must fit in word32 16 bits still */
3318  if (new_last >= 0xfffe)
3319   {
3320    __fterr(305,
3321     "too many comand -f , input, `include and library files (%d)",
3322     0xfffe);
3323   }
3324  /* re-alloc area */
3325  osize = __siz_in_fils*sizeof(char *);
3326  __siz_in_fils *= 2;
3327  /* if hits fffd this will do a realloc that does nothing */
3328  if (__siz_in_fils >= 0xfffd) __siz_in_fils = 0xffff;
3329  nsize = __siz_in_fils*sizeof(char *);
3330  /* notice realloc may move but works because ptrs to the strings */
3331  __in_fils = (char **) __my_realloc((char *) __in_fils, osize, nsize);
3332 }
3333 
3334 /*
3335  * extract SDF annotation file name and optional scope and save in list
3336  */
do_sdflocdef(char * sdfloc,char * optfnam,int32 oplin_cnt)3337 static void do_sdflocdef(char *sdfloc, char *optfnam, int32 oplin_cnt)
3338 {
3339  register char *chp;
3340  struct sdfnamlst_t *sdfp, *sdfp2, *last_sdfp;
3341  char *chp2;
3342  char fnam[IDLEN], pthnam[IDLEN];
3343 
3344  /* form is [file name]+[optional scope] */
3345  strcpy(pthnam, "");
3346  if ((chp = strchr(sdfloc, '+')) == NULL) strcpy(fnam, sdfloc);
3347  else
3348   {
3349    if (chp == sdfloc || chp[-1] == '\\')
3350     {
3351      chp2 = chp + 1;
3352      for (;;)
3353       {
3354        if ((chp = strchr(chp2, '+')) == NULL)
3355         { strcpy(fnam, sdfloc); goto sep_done; }
3356 
3357        if (chp[-1] != '\\') goto bld_both;
3358        chp2 = chp + 1;
3359       }
3360     }
3361 bld_both:
3362    strncpy(fnam, sdfloc, chp - sdfloc);
3363    fnam[chp - sdfloc] = '\0';
3364    strcpy(pthnam, ++chp);
3365   }
3366 
3367 sep_done:
3368  sdfp = (struct sdfnamlst_t *) __my_malloc(sizeof(struct sdfnamlst_t));
3369  sdfp->fnam = __pv_stralloc(fnam);
3370  sdfp->scopnam = __pv_stralloc(pthnam);
3371  sdfp->optfnam = __pv_stralloc(optfnam);
3372  sdfp->opt_slcnt = oplin_cnt;
3373  sdfp->sdfnamnxt = NULL;
3374  last_sdfp = NULL;
3375 
3376  /* put on end since must do in order */
3377  for (sdfp2 = __sdflst; sdfp2 != NULL; sdfp2 = sdfp2->sdfnamnxt)
3378   last_sdfp = sdfp2;
3379  if (last_sdfp == NULL) __sdflst = sdfp; else last_sdfp->sdfnamnxt = sdfp;
3380  if (strcmp(sdfp->scopnam, "") == 0)
3381   {
3382    if (__verbose)
3383     {
3384      __cv_msg(
3385       "  Delay annotation values read from SDF 3.0 file \"%s\" design context.\n",
3386       sdfp->fnam);
3387     }
3388   }
3389  else
3390   {
3391    if (__verbose)
3392     {
3393      __cv_msg(
3394       "  Delay annotation values read from SDF 3.0 file \"%s\" scope context %s.\n",
3395      sdfp->fnam, sdfp->scopnam);
3396     }
3397   }
3398 }
3399 
3400 /*
3401  * process a +define argument and do the define and emit verbose msg
3402  *
3403  * know defarg starts just after +define+
3404  */
do_cmdmacdef(char * defarg,struct optlst_t * olp)3405 static void do_cmdmacdef(char *defarg, struct optlst_t *olp)
3406 {
3407  int32 slen;
3408  char *chp, *chp2, *chp3;
3409  char optnam[IDLEN], optval[IDLEN], s1[3*IDLEN];
3410 
3411  for (chp = defarg;;)
3412   {
3413    /* know chp pointer to char after current + */
3414    /* separate off string to next '+' */
3415    if ((chp2 = strchr(chp, '+')) == NULL) { strcpy(s1, chp); goto got_def; }
3416 
3417 got_plus:
3418    chp2--;
3419    /* if escaped +, keep looking until find end non escaped */
3420    if (*chp2 == '\\')
3421     {
3422      chp2++; chp2++;
3423      chp3 = chp2;
3424      if ((chp2 = strchr(chp3, '+')) == NULL)
3425       { strcpy(s1, chp); goto got_def; }
3426      goto got_plus;
3427     }
3428    /* nove back to point to + */
3429    chp2++;
3430    strncpy(s1, chp, chp2 - chp);
3431    s1[chp2 - chp] = '\0';
3432 
3433 got_def:
3434    /* now have define in s1 with chp2 either name nil */
3435    optnam[0] = '`';
3436    if ((chp = strchr(s1, '=')) == NULL)
3437     {
3438      if (strcmp(s1, "") == 0)
3439       {
3440 bad_nam:
3441        __gferr(962, olp->optfnam_ind, olp->optlin_cnt,
3442         "+define+[name]+ ... or +define+[name]=[value] option empty [name] illegal");
3443        return;
3444       }
3445      strcpy(&(optnam[1]), s1);
3446      if (__verbose)
3447       __cv_msg("  `define of %s (no value form) added from command option.\n",
3448        s1);
3449      __do_macdefine(optnam, "");
3450     }
3451    else
3452     {
3453      strncpy(&(optnam[1]), s1, chp - s1);
3454      /* notice plus 1 because 1st char of optnam already filled */
3455      optnam[chp - s1 + 1] = '\0';
3456      if (strcmp(optnam, "`") == 0) goto bad_nam;
3457      chp++;
3458      if (*chp == '\\' && *chp == '"') chp++;
3459      strcpy(optval, chp);
3460      slen = strlen(optval);
3461      /* if escaped " remove escape */
3462      if (slen > 1)
3463       {
3464        if (optval[slen - 2] == '\\' && optval[slen - 1] == '"')
3465         { optval[slen - 2] = optval[slen - 1]; optval[slen - 1] = '\0'; }
3466       }
3467      if (__verbose)
3468       __cv_msg("  `define of %s value %s added from command option.\n",
3469        &(optnam[1]), optval);
3470      __do_macdefine(optnam, optval);
3471     }
3472    /* chp2 either points to NULL or ending '+' */
3473    /* end can be NULL or final '+' */
3474    if (chp2 == NULL) break;
3475    chp2++;
3476    if (*chp2 == '\0') break;
3477    chp = chp2;
3478   }
3479 }
3480 
3481 /*
3482  * build (add to) +incdir path table
3483  *
3484  * concatenate on end (in option order) for +incdir+ list
3485  * if path does not end in / one is added - `include cated on end
3486  * and attempt is made to open that path
3487  */
bld_incdtab(char * incdirptr,struct optlst_t * olp)3488 static int32 bld_incdtab(char *incdirptr, struct optlst_t *olp)
3489 {
3490  int32 len;
3491  char *cp, *cpbg, *chp2;
3492  char s1[IDLEN], s2[IDLEN];
3493 
3494  len = strlen(incdirptr);
3495  if (len == 0)
3496   {
3497    __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3498     "+incdir+ option missing include file path name list - option ignored");
3499    return(FALSE);
3500   }
3501 
3502  /* if optional ending plus left out - add here */
3503  if (incdirptr[len - 1] != '+')
3504   {
3505    chp2 = s2;
3506    strcpy(chp2, incdirptr);
3507    chp2[len] = '+';
3508    chp2[len + 1] = '\0';
3509   }
3510  else chp2 = incdirptr;
3511 
3512  for (cpbg = chp2, len = 0;;)
3513   {
3514    /* notice - if no + will just be one - this is internal fmt screw up */
3515    if ((cp = strchr(cpbg, '+')) == NULL || (len = cp - cpbg) >= IDLEN - 1)
3516     __misc_terr(__FILE__, __LINE__);
3517 
3518    if (++__last_incdir >= MAXINCDIRS)
3519     __pv_terr(306, "+incdir+ option - too many include file paths (%d)",
3520      MAXINCDIRS);
3521    if (len > 0)
3522     {
3523      strncpy(s1, cpbg, len);
3524      if (s1[len - 1] != '/') { s1[len] = '/'; len++; }
3525      s1[len] = '\0';
3526      __incdirs[__last_incdir] = __pv_stralloc(s1);
3527     }
3528    else
3529     {
3530      __gfwarn(514, olp->optfnam_ind, olp->optlin_cnt,
3531       "+incdir+ path list contains empty (++) path - just skipping");
3532      __last_incdir--;
3533     }
3534    cpbg = ++cp;
3535    if (*cpbg == '\0') break;
3536   }
3537  return(TRUE);
3538 }
3539 
3540 /*
3541  * process +loadpli1 or +loadvpi PLI dynamic library and bootstrap load arg
3542  *
3543  * formats exactly:
3544  *   +loadpli1=[.so lib]:[boostrap routines (, sep - none legal)]
3545  *   +loadvpi=[.so lib]:[boostrap routines (, sep - none legal)]
3546  *
3547  * LOOKATME - option must be contiguous - some shells may require
3548  * quoting on command line (not in -f files) but quotes stripped by shell
3549  */
bld_loadpli_lbs(char * loadpliptr,struct optlst_t * olp,int32 is_pli1)3550 static struct loadpli_t *bld_loadpli_lbs(char *loadpliptr,
3551  struct optlst_t *olp, int32 is_pli1)
3552 {
3553  int32 len;
3554  char *cp;
3555  char lbnam[IDLEN], rnams[IDLEN], onam[RECLEN];
3556  struct loadpli_t *ldp;
3557 
3558  if (is_pli1) strcpy(onam, "+loadpli1="); else strcpy(onam, "+loadvpi=");
3559  len = strlen(loadpliptr);
3560  if (len == 0)
3561   {
3562    __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3563     "%s option missing [dynamic lib]:[bootstrap routine list] pair - option ignored",
3564     onam);
3565    return(NULL);
3566   }
3567  /* if dynamic library missing - use dlsym look up in all other libs */
3568  if (loadpliptr[0] == ':')
3569   {
3570    /* library missing - ok if boot routine defined in some other dyn lib */
3571    __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3572     "%s [dynamic lib] omitted - required because mixed static/dynamic not supported - option ignored",
3573     onam);
3574    return(NULL);
3575   }
3576  for (cp = &(loadpliptr[len - 1]);;)
3577   {
3578    if (*cp == ':') break;
3579    if (--cp == loadpliptr)
3580     {
3581      __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3582     "%s [dynamic lib] and [bootstrap routine] ':' separator missing - option ignored",
3583      onam);
3584      return(NULL);
3585     }
3586   }
3587  strncpy(lbnam, loadpliptr, cp - loadpliptr);
3588  lbnam[cp - loadpliptr] = '\0';
3589  cp++;
3590  strcpy(rnams, cp);
3591  /* FIXME ??? - think should allow omitted lib and static and dynamic  */
3592  if (strcmp(rnams, "") == 0)
3593   {
3594    /* missing bootstrap ok since other load pli option can supply boostrap */
3595    __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3596     "%s [bootstrap routine] missing - ok since not required", onam);
3597    return(NULL);
3598   }
3599 
3600  /* LOOKATME - maybe should remove extra ' or " */
3601  /* fill the load pli record */
3602  ldp = (struct loadpli_t *) __my_malloc(sizeof(struct loadpli_t));
3603  if (is_pli1) ldp->pli1_option = TRUE; else ldp->pli1_option = FALSE;
3604  ldp->libnam = __pv_stralloc(lbnam);
3605  ldp->load_plinxt = NULL;
3606  if (!bld_boot_rout_list(ldp, rnams))
3607   {
3608    __my_free((char *) ldp, sizeof(struct loadpli_t));
3609    return(NULL);
3610   }
3611 
3612  if (is_pli1)
3613   {
3614    /* need separate lists since pli1 can add user systf tfcell elements */
3615    if (__pli1_dynlib_hd == NULL)
3616     { __pli1_dynlib_hd = __pli1_dynlib_end = ldp; }
3617    else
3618     {
3619      /* add to end - libs must be processed in option order */
3620      __pli1_dynlib_end->load_plinxt = ldp;
3621      __pli1_dynlib_end = ldp;
3622     }
3623    return(ldp);
3624   }
3625 
3626  /* build the vpi list */
3627  if (__vpi_dynlib_hd == NULL) { __vpi_dynlib_hd = __vpi_dynlib_end = ldp; }
3628  else
3629   {
3630    /* add to end - libs must be processed in option order */
3631    __vpi_dynlib_end->load_plinxt = ldp;
3632    __vpi_dynlib_end = ldp;
3633   }
3634  return(ldp);
3635 }
3636 
3637 /*
3638  * routine to check
3639  */
bld_boot_rout_list(struct loadpli_t * ldp,char * rnams)3640 static int32 bld_boot_rout_list(struct loadpli_t *ldp, char *rnams)
3641 {
3642  int32 len;
3643  struct dynboot_t *dnbp, *last_dnbp;
3644  char *chp2, *chp;
3645  char s1[RECLEN];
3646 
3647  /* first check for one routine name or , separated list - no spaces */
3648  if (!check_rnam_str(rnams)) return(FALSE);
3649 
3650  last_dnbp = NULL;
3651  chp2 = rnams;
3652  for (chp = rnams;; chp++)
3653   {
3654    if (*chp == ',' || *chp == '\0')
3655     {
3656      len = chp - chp2;
3657      strncpy(s1, chp2, len);
3658      s1[len] = '\0';
3659      dnbp = (struct dynboot_t *) __my_malloc(sizeof(struct dynboot_t));
3660      dnbp->bootrout_nam = __pv_stralloc(s1);
3661      dnbp->dynu.vpi_rout = NULL;
3662      dnbp->ret_veriusertf = NULL;
3663      dnbp->dynbootnxt = NULL;
3664 
3665      if (last_dnbp == NULL) ldp->dynblst = dnbp;
3666      else last_dnbp->dynbootnxt = dnbp;
3667      last_dnbp = dnbp;
3668 
3669      if (*chp == '\0') break;
3670      chp2 = chp;
3671      chp2++;
3672     }
3673   }
3674  return(TRUE);
3675 }
3676 
3677 /*
3678  * check to make sure boot routine has legal no space , sep list
3679  */
check_rnam_str(char * rnams)3680 static int32 check_rnam_str(char *rnams)
3681 {
3682  int32 len;
3683  char *chp, *chp2;
3684 
3685  if (strlen(rnams) == 1 && rnams[0] == ',') return(FALSE);
3686  chp2 = rnams;
3687  for (chp = rnams; *chp != '\0'; chp++)
3688   {
3689    if (isspace(*chp)) return(FALSE);
3690    if (*chp == '.') return(FALSE);
3691    if (*chp == ',')
3692     {
3693      len = chp - chp2;
3694      if (len == 0) return(FALSE);
3695      chp2 = chp + 1;
3696     }
3697   }
3698  chp--;
3699  if (*chp == ',') return(FALSE);
3700  return(TRUE);
3701 }
3702 
3703 /*
3704  * build (add to) lib. ext. table
3705  * concatenate on end (in option order) for +libext+ list
3706  *
3707  * LOOKATME - following XL only one +libext+ option allowed - maybe should
3708  * allow more (this routine never called if __last lbx > -1)
3709  */
bld_lbxtab(char * lbxptr,struct optlst_t * olp)3710 static int32 bld_lbxtab(char *lbxptr, struct optlst_t *olp)
3711 {
3712  int32 len;
3713  char *cp, *cpbg, *chp2;
3714  char s1[IDLEN], s2[IDLEN];
3715 
3716  len = strlen(lbxptr);
3717  if (len == 0)
3718   {
3719    __gfwarn(505, olp->optfnam_ind, olp->optlin_cnt,
3720     "+libext+ option missing libary extension list - ignored");
3721    return(FALSE);
3722   }
3723 
3724  /* if optional ending plus left out - add here */
3725  if (lbxptr[len - 1] != '+')
3726   { chp2 = s2; strcpy(chp2, lbxptr); chp2[len] = '+'; chp2[len + 1] = '\0'; }
3727  else chp2 = lbxptr;
3728 
3729  for (cpbg = chp2, len = 0;;)
3730   {
3731    /* notice - if no + will just be one - this is internal fmt screw up */
3732    if ((cp = strchr(cpbg, '+')) == NULL || (len = cp - cpbg) >= IDLEN - 1)
3733     __misc_terr(__FILE__, __LINE__);
3734 
3735    if (++__last_lbx >= MAXLBEXTS)
3736     {
3737      __pv_terr(306, "+libext+ option - too many library suffixes (%d)",
3738       MAXLBEXTS);
3739     }
3740    /* notice empty is legal extension - name as is */
3741    if (len > 0) strncpy(s1, cpbg, len);
3742    s1[len] = '\0';
3743    __lbexts[__last_lbx] = __pv_stralloc(s1);
3744    cpbg = ++cp;
3745    if (*cpbg == '\0') break;
3746   }
3747  return(TRUE);
3748 }
3749 
3750 /*
3751  * add one library file to list
3752  */
add_lbfil(char * fnam,char tlet)3753 static void add_lbfil(char *fnam, char tlet)
3754 {
3755  struct vylib_t *vyp;
3756 
3757  vyp = alloc_vylib(fnam);
3758  if (tlet == 'y') __num_ylibs++;
3759  else if (tlet == 'v') __num_vlibs++;
3760  else __case_terr(__FILE__, __LINE__);
3761  vyp->vytyp = tlet;
3762  if (__vyhdr == NULL) __vyhdr = vyp; else __end_vy->vynxt = vyp;
3763  __end_vy = vyp;
3764 }
3765 
3766 /*
3767  * allocate a vylib entry
3768  */
alloc_vylib(char * nam)3769 static struct vylib_t *alloc_vylib(char *nam)
3770 {
3771  struct vylib_t *vyp;
3772 
3773  vyp = (struct vylib_t *) __my_malloc(sizeof(struct vylib_t));
3774  vyp->vyu.vyfnam = __pv_stralloc(nam);
3775  vyp->vyfnam_ind = 0;
3776  vyp->vytyp = ' ';
3777  vyp->yfiles = NULL;
3778  vyp->vynxt = NULL;
3779  return(vyp);
3780 }
3781 
3782 struct warnsup_t {
3783   int32 rngbeg;
3784   int32 rngend;
3785 };
3786 
3787 struct warnsup_t warnsuptab[] = {
3788  /* 1 to 399 - fatal errors */
3789  /* 400 to 679 suppressable normal informs and warnings */
3790  { 400, 679 },
3791  /* 680 to 1399 normal errors */
3792  /* iact errors 1400 to 1499 can be suppressed */
3793  { 1400, 1499 },
3794  /* 1500 to 1599 are SDF errors - not suppressable */
3795  /* 1600-1699 are iact warnings - can be suppressed */
3796  { 1600, 1699 },
3797  /* 1700 to 1999 are PLI errors */
3798  /* 2000 to 2199 are PLI warns and informs */
3799  { 2000, 2199 },
3800  /* 2200 to 2499 are vendor specific warns and informs */
3801  { 2200, 2499 },
3802  /* 2500 to 2599 are code gen warns and informs */
3803  { 2500, 2599 },
3804 
3805  /* 2600 - 2899 vendor specific errors or unused - not suppressable */
3806  /* 2900 - 2999 optimizer errors or unused - not suppressable */
3807  /* 3000 to 3099 are new Verilog 2000 informs - suppressable */
3808  /* 3100 to 3499 are new Verilog 2000 warns - suppressable */
3809  { 3000, 3399 },
3810  /* 3400 to 4000 Verilog 2000 errors - not suppressable */
3811  { -1, -1 }
3812 };
3813 
3814 /*
3815  * return T if error message is suppressable (i.e. inform or warn)
3816  */
__enum_is_suppressable(int32 errnum)3817 extern int32 __enum_is_suppressable(int32 errnum)
3818 {
3819  register int32 i;
3820 
3821  for (i = 0;; i++)
3822   {
3823    if (warnsuptab[i].rngbeg == -1) break;
3824 
3825    if (errnum >= warnsuptab[i].rngbeg && errnum <= warnsuptab[i].rngend)
3826     return(TRUE);
3827   }
3828  return(FALSE);
3829 }
3830 
3831 /*
3832  * add each +num+ num to table of suppressed warnings (or in 1)
3833  * this returns F on error
3834  * know if + at end left off, will have been added
3835  */
add_suppwarn(char * pluslst,struct optlst_t * olp)3836 static int32 add_suppwarn(char *pluslst, struct optlst_t *olp)
3837 {
3838  int32 ernum, len, noerr;
3839  char *cp, *cpbg;
3840  char s1[IDLEN];
3841 
3842  cpbg = &(pluslst[16]);
3843  for (noerr = TRUE, len = 0;;)
3844   {
3845    if ((cp = strchr(cpbg, '+')) == NULL || (len = cp - cpbg) >= IDLEN)
3846     {
3847      __misc_terr(__FILE__, __LINE__);
3848      return(FALSE);
3849     }
3850    strncpy(s1, cpbg, len);
3851    s1[len] = '\0';
3852    if (sscanf(s1, "%d", &ernum) != 1)
3853     {
3854 bad_num:
3855      __gfwarn(513, olp->optfnam_ind, olp->optlin_cnt,
3856       "+suppress_warnings number %s not warn, not inform, or out of range - ignored",
3857       s1);
3858      noerr = FALSE;
3859      goto nxt_msg;
3860     }
3861    if (!__enum_is_suppressable(ernum)) goto bad_num;
3862 
3863    __wsupptab[ernum/WBITS] |= (1 << (ernum % WBITS));
3864 
3865 nxt_msg:
3866    cpbg = ++cp;
3867    if (*cpbg == '\0') break;
3868   }
3869  return(noerr);
3870 }
3871 
3872 #include "gpl_wrhelp.h"
3873 
3874 /*
3875  * write the help message to standard output and log file
3876  */
wrhelp(void)3877 static void wrhelp(void)
3878 {
3879  int32 i;
3880 
3881  for (i = 0; *txhelp[i] != '\0'; i++) __crit_msg("%s\n", txhelp[i]);
3882 }
3883 
3884 /*
3885  * BUILT IN INITIALIZATTON ROUTINES
3886  */
3887 
3888 /* built-in Verilog gates */
3889 /* gateid is, if has corresponding operator gate id, else G_ symbol */
3890 static struct primtab_t prims[] = {
3891  /* special gate for continuous assign */
3892  /* notice since starts with number can never be found accidently */
3893  { G_ASSIGN, GC_LOGIC, NULL, "1-bit-assign" },
3894  { G_BITREDAND, GC_LOGIC , NULL, "and" },
3895  { G_BUF, GC_LOGIC, NULL, "buf" },
3896  { G_BUFIF0, GC_BUFIF, NULL, "bufif0" },
3897  { G_BUFIF1, GC_BUFIF, NULL, "bufif1" },
3898  { G_CMOS, GC_CMOS, NULL, "cmos" },
3899  { G_NAND, GC_LOGIC, NULL, "nand" },
3900  { G_NMOS, GC_MOS, NULL, "nmos" },
3901  { G_NOR, GC_LOGIC, NULL, "nor" },
3902  { G_NOT, GC_LOGIC, NULL, "not" },
3903  { G_NOTIF0, GC_BUFIF, NULL, "notif0" },
3904  { G_NOTIF1, GC_BUFIF, NULL, "notif1" },
3905  { G_BITREDOR, GC_LOGIC, NULL, "or" },
3906  { G_PMOS, GC_MOS, NULL, "pmos" },
3907  /* next 2 initialized so can drive fi>1 wires but do not exist */
3908  { G_PULLDOWN, GC_PULL, NULL, "pulldown" },
3909  { G_PULLUP, GC_PULL, NULL, "pullup" },
3910  { G_RCMOS, GC_CMOS, NULL, "rcmos" },
3911  { G_RNMOS, GC_MOS, NULL, "rnmos" },
3912  { G_RPMOS, GC_MOS, NULL, "rpmos" },
3913  { G_RTRAN, GC_TRAN, NULL, "rtran" },
3914  { G_RTRANIF0, GC_TRANIF, NULL, "rtranif0" },
3915  { G_RTRANIF1, GC_TRANIF, NULL, "rtranif1" },
3916  { G_TRAN, GC_TRAN, NULL, "tran" },
3917  { G_TRANIF0, GC_TRANIF, NULL, "tranif0" },
3918  { G_TRANIF1, GC_TRANIF, NULL, "tranif1" },
3919  { G_BITREDXOR, GC_LOGIC, NULL, "xor" },
3920  { G_REDXNOR, GC_LOGIC, NULL, "xnor" },
3921 };
3922 #define NPRIMS (sizeof(prims) / sizeof(struct primtab_t))
3923 
init_modsymtab(void)3924 static void init_modsymtab(void)
3925 {
3926  __cur_fnam_ind = 0;
3927 
3928  __cur_fnam = __in_fils[__cur_fnam_ind];
3929  __lin_cnt = 0;
3930  /* disguised trigger for expired copy expiration */
3931  __slotend_action = 0;
3932  /* this symbol table is not a symbol table of any symbol */
3933  __modsyms = __alloc_symtab(FALSE);
3934  __sym_addprims();
3935 }
3936 
3937 /*
3938  * add primitives to module type name symbol table - separate name space
3939  */
__sym_addprims(void)3940 extern void __sym_addprims(void)
3941 {
3942  register int32 i;
3943  struct sy_t *syp;
3944  struct tnode_t *tnp;
3945  struct primtab_t *primp;
3946 
3947  for (i = 0, primp = prims; i < NPRIMS; i++, primp++)
3948   {
3949    /* spcial 1 bit continuous assign primitive - not searched in table */
3950    tnp = __vtfind(primp->gatnam, __modsyms);
3951    /* err if inconsistent primitive table */
3952    if (!__sym_is_new) __misc_terr(__FILE__, __LINE__);
3953    __add_sym(primp->gatnam, tnp);
3954    (__modsyms->numsyms)++;
3955    syp = tnp->ndp;
3956    syp->sytyp = SYM_PRIM;
3957    syp->sydecl = TRUE;
3958    syp->el.eprimp = primp;
3959 
3960    /* need global when 1 bit continuous assigns converted */
3961    if (primp->gateid == G_ASSIGN) __ca1bit_syp = syp;
3962   }
3963 }
3964 
3965 /*
3966  * predefined built-in system tasks
3967  *
3968  * system task arguments are defined by fixup checking code and follow
3969  * no pattern
3970  */
3971 static struct systsk_t vsystasks[] = {
3972  { STN_CLEARDEBUG, "$cleardebug" },
3973  { STN_CLEAREVTRACE, "$clearevtrace" },
3974  { STN_CLEARTRACE, "$cleartrace" },
3975  { STN_DEFINEGROUPWAVES, "$define_group_waves" },
3976  { STN_DISPLAY, "$display" },
3977  { STN_DISPLAYB, "$displayb" },
3978  { STN_DISPLAYH, "$displayh" },
3979  { STN_DISPLAYO, "$displayo" },
3980  { STN_DUMPALL, "$dumpall" },
3981  { STN_DUMPFILE, "$dumpfile" },
3982  { STN_DUMPFLUSH, "$dumpflush" },
3983  { STN_DUMPLIMIT, "$dumplimit" },
3984  { STN_DUMPOFF, "$dumpoff" },
3985  { STN_DUMPON, "$dumpon" },
3986  { STN_DUMPVARS, "$dumpvars" },
3987  { STN_FCLOSE, "$fclose" },
3988  { STN_FDISPLAY, "$fdisplay" },
3989  { STN_FDISPLAYB, "$fdisplayb" },
3990  { STN_FDISPLAYH, "$fdisplayh" },
3991  { STN_FDISPLAYO, "$fdisplayo" },
3992  { STN_FINISH, "$finish" },
3993  { STN_FLUSHLOG, "$flushlog" },
3994  { STN_FMONITOR , "$fmonitor" },
3995  { STN_FMONITORB, "$fmonitorb" },
3996  { STN_FMONITORH, "$fmonitorh" },
3997  { STN_FMONITORO, "$fmonitoro" },
3998  { STN_FREEZEWAVES, "$freeze_waves" },
3999  { STN_FSTROBE, "$fstrobe" },
4000  { STN_FSTROBEB, "$fstrobeb" },
4001  { STN_FSTROBEH, "$fstrobeh" },
4002  { STN_FSTROBEO, "$fstrobeo" },
4003  { STN_FWRITE, "$fwrite" },
4004  { STN_FWRITEB, "$fwriteb" },
4005  { STN_FWRITEH, "$fwriteh" },
4006  { STN_FWRITEO, "$fwriteo" },
4007  { STN_GRREMOTE, "$gr_remote" },
4008  { STN_GRREGS, "$gr_regs" },
4009  { STN_GRSYNCHON, "$gr_synchon" },
4010  { STN_GRWAVES, "$gr_waves" },
4011  { STN_HISTORY, "$history" },
4012  { STN_INCSAVE, "$incsave" },
4013  { STN_INPUT, "$input" },
4014  { STN_KEEPCMDS, "$keepcommands" },
4015  { STN_KEY, "$key" },
4016  { STN_LIST, "$list" },
4017  { STN_LOG, "$log" },
4018  { STN_MEMUSE, "$memuse" },
4019  { STN_MONITOR, "$monitor" },
4020  { STN_MONITORB, "$monitorb" },
4021  { STN_MONITORH, "$monitorh" },
4022  { STN_MONITORO, "$monitoro" },
4023  { STN_MONITOROFF, "$monitoroff" },
4024  { STN_MONITORON, "$monitoron" },
4025  { STN_NOKEEPCMDS, "$nokeepcommands" },
4026  { STN_NOKEY, "$nokey" },
4027  { STN_NOLOG, "$nolog" },
4028  { STN_PRINTTIMESCALE, "$printtimescale" },
4029  { STN_PSWAVES, "$ps_waves" },
4030  { STN_Q_ADD, "$q_add" },
4031  { STN_Q_EXAM, "$q_exam" },
4032  { STN_Q_INITIALIZE, "$q_initialize" },
4033  { STN_Q_REMOVE, "$q_remove" },
4034  { STN_READMEMB, "$readmemb" },
4035  { STN_READMEMH, "$readmemh" },
4036  { STN_RESET, "$reset" },
4037  { STN_RESTART, "$restart" },
4038  { STN_SAVE, "$save" },
4039  { STN_SCOPE, "$scope" },
4040  { STN_SDF_ANNOTATE, "$sdf_annotate" },
4041  { STN_SETDEBUG, "$setdebug" },
4042  { STN_SETEVTRACE, "$setevtrace" },
4043  { STN_SETTRACE, "$settrace" },
4044  { STN_SHOWALLINSTANCES, "$showallinstances" },
4045  { STN_SHOWEXPANDEDNETS, "$showexpandednets" },
4046  { STN_SHOWSCOPES, "$showscopes" },
4047  { STN_SHOWVARIABLES, "$showvariables" },
4048  { STN_SHOWVARS, "$showvars" },
4049  { STN_SNAPSHOT, "$snapshot" },
4050  { STN_SREADMEMB, "$sreadmemb" },
4051  { STN_SREADMEMH, "$sreadmemh" },
4052  { STN_STOP, "$stop" },
4053  { STN_STROBE, "$strobe" },
4054  { STN_STROBEB, "$strobeb" },
4055  { STN_STROBEH, "$strobeh" },
4056  { STN_STROBEO, "$strobeo" },
4057  { STN_SUPWARNS, "$suppress_warns" },
4058  { STN_ALLOWWARNS, "$allow_warns" },
4059  { STN_SYSTEM, "$system" },
4060  { STN_TIMEFORMAT, "$timeformat" },
4061  { STN_TRACEFILE, "$tracefile" },
4062  { STN_WRITE, "$write" },
4063  { STN_WRITEB, "$writeb" },
4064  { STN_WRITEH, "$writeh" },
4065  { STN_WRITEO, "$writeo" },
4066  /* AIV 09/05/03 - added for fileio - only one that is sys task */
4067  { STN_FFLUSH, "$fflush"},
4068  /* SJM 09/05/03 - also add the new fileio string forms - see 2001 LRM */
4069  /* SJM 05/21/04 - these are sys tasks not functs (but LRM inconsistent) */
4070  { STN_SWRITE, "$swrite" },
4071  { STN_SWRITEB, "$swriteb" },
4072  { STN_SWRITEH, "$swriteh" },
4073  { STN_SWRITEO, "$swriteo" },
4074  /* same as $swrite except 2nd arg (can be var) must be only format string */
4075  { STN_SFORMAT, "$sformat" },
4076  /* patches for getting models to compile pli tasks -- */
4077  /* STN_LAI_INPUTS, "$lai_inputs", */
4078  /* STN_LAI_OUTPUTS, "$lai_outputs", */
4079  /* STN_ERRORNTL, "$errorNTL", */
4080  /* STN_SUSPENDCHECK, "$suspendCheck", */
4081  { 0, "" }
4082 };
4083 
4084 /* predefined built-in system functions */
4085 /* mostly alphabetical but for now really does not need to be */
4086 /* and new transcendentals at end */
4087 struct sysfunc_t __vsysfuncs[] = {
4088  /* { internal num., ret. type, signed (1), type, returned width, name } */
4089  { STN_BITSTOREAL, N_REAL, 1, SYSF_BUILTIN, REALBITS, "$bitstoreal"},
4090  { STN_COUNT_DRIVERS, N_REG, 0, SYSF_BUILTIN, WBITS, "$countdrivers"},
4091  { STN_DIST_CHI_SQUARE, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_chi_square"},
4092  { STN_DIST_ERLANG, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_erlang"},
4093  { STN_DIST_EXPONENTIAL, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_exponential"},
4094  { STN_DIST_NORMAL, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_normal"},
4095  { STN_DIST_POISSON, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_poisson"},
4096  { STN_DIST_T, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_t"},
4097  { STN_DIST_UNIFORM, N_REG, 1, SYSF_BUILTIN, WBITS, "$dist_uniform"},
4098  { STN_FOPEN, N_REG, 1, SYSF_BUILTIN, WBITS, "$fopen"},
4099  /* width is really width of argument memory */
4100  /* only allow on rhs of cont. assign */
4101  { STN_GETPATTERN, N_REG, 0, SYSF_BUILTIN, WBITS, "$getpattern"},
4102  { STN_ITOR, N_REAL, 1, SYSF_BUILTIN, REALBITS, "$itor"},
4103  { STN_Q_FULL, N_REG, 0, SYSF_BUILTIN, WBITS, "$q_full"},
4104  { STN_RANDOM, N_REG, 1, SYSF_BUILTIN, WBITS, "$random"},
4105  { STN_REALTIME, N_REAL, 1, SYSF_BUILTIN, REALBITS , "$realtime"},
4106  /* this codes the real as 64 bit and b part */
4107  { STN_REALTOBITS, N_REG, 0, SYSF_BUILTIN, 64, "$realtobits"},
4108  { STN_RESET_COUNT, N_REG, 0, SYSF_BUILTIN, WBITS, "$reset_count" },
4109  { STN_RESET_VALUE, N_REG, 1, SYSF_BUILTIN, WBITS, "$reset_value"},
4110  { STN_RTOI, N_REG, 1, SYSF_BUILTIN, WBITS, "$rtoi"},
4111  /* scale takes as argument the module whose scale to return */
4112  { STN_SCALE, N_REAL, 0, SYSF_BUILTIN, REALBITS, "$scale"},
4113  /* SJM 10/01/03 - special conversion to signed - arg size is ret size */
4114  { STN_SIGNED, N_REG, 1, SYSF_BUILTIN, 0, "$signed" },
4115  { STN_STIME, N_REG, 0, SYSF_BUILTIN, WBITS, "$stime"},
4116  { STN_TESTPLUSARGS, N_REG, 0, SYSF_BUILTIN, WBITS, "$test$plusargs" },
4117  { STN_SCANPLUSARGS, N_REG, 0, SYSF_BUILTIN, WBITS, "$scan$plusargs" },
4118  { STN_VALUEPLUSARGS, N_REG, 0, SYSF_BUILTIN, WBITS, "$value$plusargs" },
4119  { STN_TIME, N_TIME, 0, SYSF_BUILTIN, TIMEBITS, "$time"},
4120  /* cver system function extensions */
4121  { STN_STICKSTIME, N_REG, 0, SYSF_BUILTIN, WBITS, "$stickstime"},
4122  { STN_TICKSTIME, N_TIME, 0, SYSF_BUILTIN, TIMEBITS, "$tickstime"},
4123  /* SJM 10/01/03 - special conversion to signed - arg size is ret size */
4124  { STN_UNSIGNED, N_REG, 0, SYSF_BUILTIN, 0, "$unsigned" },
4125  /* new transcendental functions */
4126  { STN_COS, N_REAL, 1, SYSF_BUILTIN, WBITS, "$cos"},
4127  { STN_SIN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$sin"},
4128  { STN_TAN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$tan"},
4129  { STN_ACOS, N_REAL, 1, SYSF_BUILTIN, WBITS, "$acos"},
4130  { STN_ASIN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$asin"},
4131  { STN_ATAN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$atan"},
4132  { STN_ATAN2, N_REAL, 1, SYSF_BUILTIN, WBITS, "$atan2"},
4133  { STN_COSH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$cosh"},
4134  { STN_SINH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$sinh"},
4135  { STN_TANH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$tanh"},
4136  { STN_ACOSH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$acosh"},
4137  { STN_ASINH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$asinh"},
4138  { STN_ATANH, N_REAL, 1, SYSF_BUILTIN, WBITS, "$atanh"},
4139  /* LOOKATME - think this should be removed - other ways to get sign */
4140  /* next 2 new transcendental except returns int32 */
4141  { STN_SGN, N_REG, 1, SYSF_BUILTIN, WBITS, "$sgn"},
4142  { STN_INT, N_REG, 1, SYSF_BUILTIN, WBITS, "$int"},
4143  { STN_LN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$ln"},
4144  { STN_LOG10, N_REAL, 1, SYSF_BUILTIN, WBITS, "$log10"},
4145  { STN_ABS, N_REAL, 1, SYSF_BUILTIN, WBITS, "$abs"},
4146  { STN_POW, N_REAL, 1, SYSF_BUILTIN, WBITS, "$pow"},
4147  { STN_SQRT, N_REAL, 1, SYSF_BUILTIN, WBITS, "$sqrt"},
4148  { STN_EXP, N_REAL, 1, SYSF_BUILTIN, WBITS, "$exp"},
4149  { STN_MIN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$min"},
4150  { STN_MAX, N_REAL, 1, SYSF_BUILTIN, WBITS, "$max"},
4151  { STN_HSQRT, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hsqrt" },
4152  { STN_HPOW, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hpow" },
4153  { STN_HPWR, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hpwr" },
4154  { STN_HLOG, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hlog" },
4155  { STN_HLOG10, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hlog10" },
4156  { STN_HDB, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hdb" },
4157  { STN_HSIGN, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hsign" },
4158  { STN_HYPOT, N_REAL, 1, SYSF_BUILTIN, WBITS, "$hypot" },
4159  /* AIV 09/05/03 - add the fileio sy funcs */
4160  { STN_FGETC, N_REG, 1, SYSF_BUILTIN, WBITS, "$fgetc" },
4161  { STN_UNGETC, N_REG, 1, SYSF_BUILTIN, WBITS, "$ungetc" },
4162  { STN_FGETS, N_REG, 1, SYSF_BUILTIN, WBITS, "$fgets" },
4163  { STN_FTELL, N_REG, 1, SYSF_BUILTIN, WBITS, "$ftell" },
4164  { STN_REWIND, N_REG, 1, SYSF_BUILTIN, WBITS, "$rewind" },
4165  { STN_FSEEK, N_REG, 1, SYSF_BUILTIN, WBITS, "$fseek" },
4166  { STN_FERROR, N_REG, 1, SYSF_BUILTIN, WBITS, "$ferror" },
4167  { STN_FREAD, N_REG, 1, SYSF_BUILTIN, WBITS, "$fread" },
4168  { STN_FSCANF, N_REG, 1, SYSF_BUILTIN, WBITS, "$fscanf" },
4169  { STN_SSCANF, N_REG, 1, SYSF_BUILTIN, WBITS, "$sscanf" },
4170  { 0, 0, 0, 0, 0, "" }
4171 };
4172 
4173 /*
4174  * initialize the system task symbol table
4175  * this is special symbol table used to find module and primitives
4176  * not in normal symbol table stack
4177  */
init_stsymtab(void)4178 static void init_stsymtab(void)
4179 {
4180  register int32 i;
4181  struct systsk_t *stbp;
4182  struct sysfunc_t *sfbp;
4183 
4184  /* system symbols handled specially - only tasks and funcs */
4185  /* this sets symbol table to emtpy also */
4186  /* not a symbol table of any symbol */
4187  __syssyms = __alloc_symtab(FALSE);
4188  __cur_fnam_ind = 0;
4189  __cur_fnam = __in_fils[__cur_fnam_ind];
4190  __lin_cnt = 0;
4191 
4192  /* add system tasks */
4193  /* then normal system tasks - var. (or unknown) args */
4194  for (i = 0;; i++)
4195   {
4196    stbp = &(vsystasks[i]);
4197    if (strcmp(stbp->stsknam, "") == 0) break;
4198    add_systsksym(stbp);
4199   }
4200  /* add system functions */
4201  for (i = 0;; i++)
4202   {
4203    sfbp = &(__vsysfuncs[i]);
4204    if (strcmp(sfbp->syfnam, "") == 0) break;
4205    add_sysfuncsym(sfbp);
4206   }
4207 
4208  /* SJM 07/08/02 - setup both old veriusertfs systf and new +loadpli1 */
4209  __setup_veriusertf_systfs();
4210 
4211 
4212  /* SJM 07/08/02 - handle all +loadvpi option dynamic lib loading */
4213  __process_pli_dynamic_libs(__vpi_dynlib_hd);
4214 
4215  /* because variable number of vpi_ systf (dynamic registering), must add */
4216  /* tf_ first, vpi_ registered systfs one after last tf_ */
4217  __call_vlog_startup_procs();
4218 }
4219 
4220 /*
4221  * add system tasks symbol to syssyms table
4222  */
add_systsksym(struct systsk_t * stbp)4223 static void add_systsksym(struct systsk_t *stbp)
4224 {
4225  struct tnode_t *tnp;
4226  struct sy_t *syp;
4227 
4228  tnp = __vtfind(stbp->stsknam, __syssyms);
4229  /* built in system task table mis-coded */
4230  if (!__sym_is_new) __misc_terr(__FILE__, __LINE__);
4231  __add_sym(stbp->stsknam, tnp);
4232  (__syssyms->numsyms)++;
4233  syp = tnp->ndp;
4234  syp->sytyp = SYM_STSK;
4235  syp->sydecl = TRUE;
4236  syp->sylin_cnt = 0;
4237  syp->syfnam_ind = 0;
4238  syp->el.esytbp = stbp;
4239 }
4240 
4241 /*
4242  * add system function to system symbol symbol table
4243  */
add_sysfuncsym(struct sysfunc_t * sfbp)4244 static void add_sysfuncsym(struct sysfunc_t *sfbp)
4245 {
4246  struct tnode_t *tnp;
4247  struct sy_t *syp;
4248 
4249  tnp = __vtfind(sfbp->syfnam, __syssyms);
4250  /* built in system function table mis-coded */
4251  if (!__sym_is_new) __misc_terr(__FILE__, __LINE__);
4252  __add_sym(sfbp->syfnam, tnp);
4253  (__syssyms->numsyms)++;
4254  syp = tnp->ndp;
4255  syp->sytyp = SYM_SF;
4256  syp->sydecl = TRUE;
4257  syp->sylin_cnt = 0;
4258  syp->syfnam_ind = 0;
4259  syp->el.esyftbp = sfbp;
4260 }
4261 
4262 /*
4263  * INPUT FILE PREPARATION ROUTINES
4264  */
4265 
4266 /*
4267  * prepare the input file stack (know input files infiles[0:__last_inf])
4268  * macro expansions and `include put on top of stack
4269  * this puts one open file struct on tos and open 1st file with guts
4270  */
prep_vflist(void)4271 static void prep_vflist(void)
4272 {
4273  register int32 fi;
4274 
4275  /* no files since 0  and 1 are special */
4276  if (__last_inf == __last_optf)
4277   __pv_terr(301, "no Verilog input files specified");
4278  __last_lbf = __last_inf;
4279 
4280  /* set open file/macro exp./include stack to empty */
4281  for (fi = 0; fi < MAXFILNEST; fi++) __vinstk[fi] = NULL;
4282  __vin_top = -1;
4283  __lasttoktyp = UNDEF;
4284  __last_attr_prefix = FALSE;
4285  /* this builds the empty top of stack entry */
4286  __push_vinfil();
4287  /* fill with 1st file and open it */
4288  /* __in_fils[0] is no file "none" */
4289  /* set to one after last option file */
4290  __cur_infi = __last_optf + 1;
4291  if (!__open_sfil())
4292   __pv_terr(301, "no Verilog input - all files empty or cannot be opened");
4293 }
4294 
4295 
4296 /*
4297  * try to open the next input source file and fill top of stack with its info
4298  * file must be openable and have contents
4299  * return F on no sucess in opening any of succeeding files
4300  */
__open_sfil(void)4301 extern int32 __open_sfil(void)
4302 {
4303 again:
4304  /* if not first time, close previous file */
4305  if (__visp->vi_s != NULL)
4306   { __my_fclose(__visp->vi_s); __visp->vi_s = NULL; }
4307  __cur_fnam = __in_fils[__cur_infi];
4308  if ((__in_s = __tilde_fopen(__cur_fnam, "r")) == NULL)
4309   {
4310    __pv_err(700, "cannot open Verilog input file %s - skipped", __cur_fnam);
4311 try_next:
4312    if (__cur_infi + 1 > __last_inf) return(FALSE);
4313    __cur_infi++;
4314    goto again;
4315   }
4316  if (feof(__in_s))
4317   {
4318    __pv_warn(508, "Verilog input file %s empty", __cur_fnam);
4319    goto try_next;
4320   }
4321  /* whenever open new file must discard pushed back */
4322  __lasttoktyp = UNDEF;
4323  __visp->vi_s = __in_s;
4324  /* in fils of 0 is no file "none" */
4325  /* vilin_cnt always 0 when opened */
4326  __visp->vifnam_ind = __cur_infi;
4327  __cur_fnam_ind = __cur_infi;
4328  __cur_fnam = __in_fils[__cur_fnam_ind];
4329  __lin_cnt = 1;
4330  /* emit source filed compiled unless -q */
4331  __cv_msg("Compiling source file \"%s\"\n", __cur_fnam);
4332  __file_just_op = TRUE;
4333  __first_num_eol = FALSE;
4334  /* 06/22/00 - SJM - possible cross macro 2 token number off on new file */
4335  __macro_sep_width = FALSE;
4336  __maybe_2tok_sized_num = FALSE;
4337  __macro_sav_nwid = FALSE;
4338  return(TRUE);
4339 }
4340 
4341 /*
4342  * allocate a new Verilog input file stack element on top
4343  * this does not open or fill anything just builds the tos entry
4344  * this sets global __visp
4345  */
__push_vinfil(void)4346 extern void __push_vinfil(void)
4347 {
4348  if (++__vin_top >= MAXFILNEST)
4349   __pv_terr(308, "`define macro and `include nesting level too large (%d)",
4350    MAXFILNEST);
4351  if (__vinstk[__vin_top] == NULL)
4352   {
4353    __vinstk[__vin_top] = (struct vinstk_t *)
4354      __my_malloc(sizeof(struct vinstk_t));
4355   }
4356  __visp = __vinstk[__vin_top];
4357  __visp->vilin_cnt = 0;
4358  /* in fils of 0 is no file "none" */
4359  __visp->vifnam_ind = 0;
4360  __visp->vi_s = NULL;
4361  __visp->vichp = NULL;
4362  __visp->vichplen = -1;
4363  __visp->vichp_beg = NULL;
4364 }
4365 
4366 /*
4367  * previous file(s) eof encounted pop stack (know thing under open)
4368  */
__pop_vifstk(void)4369 extern int32 __pop_vifstk(void)
4370 {
4371  /* first pop previous */
4372  if (__vin_top == 0)
4373   {
4374    /* PUT ME BACK */
4375    return(FALSE);
4376   }
4377  /* notice never pop below bottom open current source file */
4378  /* if reached end of current source file, pop */
4379  /* define stack should never be popped below bottom */
4380  if (__vin_top < 0) __misc_terr(__FILE__, __LINE__);
4381 
4382  /* close current top file if open or null out macro */
4383  __visp = __vinstk[__vin_top];
4384  if (__visp->vi_s != NULL)
4385   { __my_fclose(__visp->vi_s); __visp->vi_s = NULL; }
4386  if (__visp->vichp != NULL)
4387   {
4388    /* if -1, pointing to non arg macro in symbol table must not free */
4389    /* for use of fixed visp for parsing from history list will just be -1 */
4390    /* else len built for arg macro and must be freed */
4391    /* need original start which is - length since at ending 0 */
4392    if (__visp->vichplen != -1)
4393     __my_free(__visp->vichp_beg, __visp->vichplen + 1);
4394    __visp->vichp = NULL;
4395    __visp->vichp_beg = NULL;
4396    __visp->vichplen = -1;
4397   }
4398 
4399  /* once popped gone for ever except in_fils entry stays */
4400  __visp = __vinstk[--__vin_top];
4401 
4402  /* then access under - notice number of simultaneously open files may */
4403  /* be limited by os */
4404 
4405  /* handle nested macro expansion */
4406  /* notice here can never be first token for reprocessing `directive */
4407  /* since "`define xx `include "yy"" then line with `xx only is illegal */
4408  /* FIXME - this can never be exec because already set to nil ??? */
4409  if (__visp->vichp != NULL)
4410   {
4411    /* must not change file name and line number */
4412    __in_s = NULL;
4413    return(TRUE);
4414   }
4415  /* pop down to previously opened file - macro exp. end or `include */
4416  __cur_fnam_ind = __visp->vifnam_ind;
4417  __cur_fnam = __in_fils[__cur_fnam_ind];
4418  __lin_cnt = __visp->vilin_cnt;
4419  __in_s = __visp->vi_s;
4420  __file_just_op = TRUE;
4421  __first_num_eol = FALSE;
4422  return(TRUE);
4423 }
4424 
4425 /*
4426  * return to print internally stored source
4427  * know only called if no errors
4428  *
4429  * must save cur iti num since this is debug routine that can be called
4430  * from anywhere
4431  */
__do_decompile(void)4432 extern void __do_decompile(void)
4433 {
4434  register struct mod_t *mdp;
4435  register struct udp_t *udpp;
4436  int32 first_time;
4437 
4438  __cv_msg("  Reconstructing post compilation source:\n");
4439 
4440  /* for debugging dump every inst. need flag for has IS forms */
4441  for (first_time = TRUE, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4442   {
4443    if (!mdp->msym->sydecl) continue;
4444    if (first_time)
4445     { __cur_units = 9; __cur_prec = 0; first_time = FALSE; }
4446    __push_wrkitstk(mdp, 0);
4447    __dmp_mod(stdout, mdp);
4448    __pop_wrkitstk();
4449   }
4450  for (udpp = __udphead; udpp != NULL; udpp = udpp->udpnxt)
4451   __dmp_udp(stdout, udpp);
4452 
4453 }
4454 
4455 /*
4456  * TOP LEVEL SOURCE PROCESSING ROUTINES - ALSO DIRECTIVE HANDLING
4457  */
4458 
4459 /*
4460  * read the Verilog source input
4461  * know 1st file and 1st token read
4462  */
__rd_ver_src(void)4463 extern void __rd_ver_src(void)
4464 {
4465  __total_rd_lines = 0;
4466  __total_lang_dirs = 0;
4467  /* go through loop once for each module */
4468  /* everything in Verilog in modules */
4469  /* enter loop with first token in toktyp */
4470  for (;;)
4471   {
4472    /* EOF is eof of all in files - get tok. will open next input if need */
4473    __get_vtok();
4474    if (__toktyp == TEOF) break;
4475    /* system tasks not allowed at top level - interacte mode handled */
4476    /* elsewhere - but may be a compiler directive */
4477    if (__toktyp >= CDIR_TOKEN_START && __toktyp <= CDIR_TOKEN_END)
4478     __process_cdir();
4479    /* if ever will have synced to one before file level thing */
4480    else
4481     {
4482      /* SJM 03/20/00 - build top level attribute if present */
4483      if (__attr_prefix)
4484       {
4485        __wrk_attr.attr_tok = MODULE;
4486        __wrk_attr.attr_seen = TRUE;
4487        __wrk_attr.attrnam = __pv_stralloc(__attrwrkstr);
4488        __wrk_attr.attr_fnind = __attr_fnam_ind;
4489        __wrk_attr.attrlin_cnt = __attr_lin_cnt;
4490       }
4491      else __wrk_attr.attr_seen = FALSE;
4492 
4493      __rding_top_level = FALSE;
4494      __rd_ver_mod();
4495      __rding_top_level = TRUE;
4496     }
4497    if (__toktyp == TEOF) break;
4498   }
4499 }
4500 
4501 /*
4502  * process built in compiler directives
4503  * know directive read and for now just reads what is needed
4504  * if `define form will be handled by get tok
4505  * directive here only if allowed (and probably required) outside of module
4506  */
__process_cdir(void)4507 extern void __process_cdir(void)
4508 {
4509  int32 wtyp, savlin_cnt;
4510  char s1[RECLEN];
4511 
4512  if (!__chk_beg_line(__toktyp))
4513   {
4514    __pv_fwarn(605, "directive %s not first token on line - ignored",
4515     __prt_vtok());
4516    /* still skip rest of line */
4517    if (!__iact_state) __skipover_line();
4518    return;
4519   }
4520  switch ((byte) __toktyp) {
4521   case CDIR_TIMESCALE:
4522    do_timescale();
4523    return;
4524   case CDIR_DFLNTYP:
4525    savlin_cnt = __lin_cnt;
4526    __toktyp = __get1_vtok(__in_s);
4527    if (savlin_cnt != __lin_cnt)
4528     {
4529      __pv_ferr(927,
4530       "`defaultnettype directive wire type must be on same line");
4531      __unget_vtok();
4532      return;
4533     }
4534    if ((wtyp = __fr_wtnam(__toktyp)) == -1)
4535     __pv_ferr(704,
4536      "`defaultnettype compiler directive not followed by wire type - %s read",
4537      __prt_vtok());
4538    else if (wtyp >= NONWIRE_ST || wtyp == N_SUPPLY0 || wtyp == N_SUPPLY1)
4539     {
4540      __pv_ferr(705, "`defaultnettype compiler directive wire type %s illegal",
4541       __to_wtnam2(s1, (word32) wtyp));
4542     }
4543    else __dflt_ntyp = wtyp;
4544    break;
4545   case CDIR_AEXPVECNETS:
4546   case CDIR_XPNDVNETS:
4547    /* this is default */
4548    __no_expand = FALSE;
4549    break;
4550   case CDIR_NOXPNDVNETS:
4551    __no_expand = TRUE;
4552    break;
4553   case CDIR_CELLDEF:
4554    __in_cell_region = TRUE;
4555    break;
4556   case CDIR_ECELLDEF:
4557    __in_cell_region = FALSE;
4558    break;
4559   /* this takes pull0 or pull1 and connects pull up to unc. input port ? */
4560   case CDIR_UNCONNDRIVE:
4561    savlin_cnt = __lin_cnt;
4562    __toktyp = __get1_vtok(__in_s);
4563    if (savlin_cnt != __lin_cnt)
4564     {
4565      __pv_ferr(1037,
4566       "`unconnected_drive directive strength must be on same line");
4567      __unget_vtok();
4568      return;
4569     }
4570    if (__toktyp != PULL0 && __toktyp != PULL1)
4571     {
4572      __pv_ferr(1041,
4573       "`unconnected_drive directive requires pull0 or pull1 argument - %s read",
4574       __prt_vtok());
4575      __unget_vtok();
4576      return;
4577     }
4578    __unconn_drive = __toktyp;
4579    break;
4580   case CDIR_NOUNCONNDRIVE:
4581    __unconn_drive = TOK_NONE;
4582    break;
4583   case CDIR_RESETALL:
4584    /* this does not effect `ifdef, `define, i.e. symbol tables left as is */
4585    set_tfmt_dflts();
4586    __dflt_ntyp = N_WIRE;
4587    __in_cell_region = FALSE;
4588    __unconn_drive = TOK_NONE;
4589    __no_expand = FALSE;
4590    __cur_units = 9;
4591    __cur_prec = 0;
4592    break;
4593   case CDIR_LANG:
4594    __do_foreign_lang();
4595    /* must return since already skipped to end of line */
4596    return;
4597 
4598   /* these need to be supported */
4599   case CDIR_ENDPROTECT:
4600   case CDIR_ENDPROTECTED:
4601   case CDIR_PROTECT:
4602   case CDIR_PROTECTED:
4603    __pv_fwarn(619, "directive %s unimplemented", __prt_vtok());
4604    break;
4605 
4606   /* these do not do anything */
4607   case CDIR_ACCEL:
4608   case CDIR_NOACCEL:
4609   case CDIR_REMGATESNAMES:
4610   case CDIR_REMNETNAMES:
4611   case CDIR_NOREMGATENAMES:
4612   case CDIR_NOREMNETNAMES:
4613   case CDIR_DFLTDECAYTIME:
4614   case CDIR_DFLTTRIREGSTREN:
4615   case CDIR_DELMODEDIST:
4616   case CDIR_DELMODEPATH:
4617   case CDIR_DELMODEUNIT:
4618   case CDIR_DELMODEZERO:
4619 
4620    /* these are all one name and ignored for now */
4621    __finform(430, "directive %s has no effect", __prt_vtok());
4622    break;
4623   default: __case_terr(__FILE__, __LINE__);
4624  }
4625  /* this skip over anything else (such as comments) on line */
4626  __skipover_line();
4627 }
4628 
4629 /*
4630  * process the time scale directive
4631  * must be on line by itself and cannot tokenize
4632  * anything on line after `timescale not read - / * cannot start there
4633  * fomrmat is `timescale <time_unit>/<time_prec>
4634  * this sets globals cur_units and cur_prec
4635  *
4636  * storage is time exponent - 1s is 1, 100 ms = 3, 1 ns = 9, 10 ns = 10, etc
4637  */
do_timescale(void)4638 static void do_timescale(void)
4639 {
4640  register char *cp, *cp2;
4641  word32 tuexp, tpexp, tunit, tprec;
4642  char *s1;
4643 
4644  __collect_line();
4645  s1 = (char *) __my_malloc(__macwrklen);
4646  /* copy line removing all white space */
4647  for (cp2 = __macwrkstr, cp = s1; *cp2 != '\0'; cp2++)
4648   { if (!vis_nonnl_white_(*cp2)) *cp++ =  *cp2; }
4649  *cp = '\0';
4650 
4651  /* first expect 1, 10, or 100 */
4652  cp = s1;
4653  tunit = 0;
4654  tuexp = 0;
4655  if (*cp++ != '1') goto tscale_bad;
4656  if (*cp++ == '0') tuexp = 1; else { cp--; goto get_tunit; }
4657  if (*cp++ == '0') tuexp = 2; else cp--;
4658 
4659 get_tunit:
4660  if ((cp = __get_tmult(cp, &tunit)) == NULL) goto tscale_bad;
4661  if (*cp != '/') goto tscale_bad;
4662  /* if second must be 1 */
4663  if (tunit == 0 && tuexp > 0) goto tscale_bad;
4664  cp++;
4665  tunit -= tuexp;
4666 
4667  tpexp = 0;
4668  if (*cp++ != '1') goto tscale_bad;
4669  if (*cp++ == '0') tpexp = 1; else { cp--; goto get_tprec; }
4670  if (*cp++ == '0') tpexp = 2; else  cp--;
4671 get_tprec:
4672  if ((cp = __get_tmult(cp, &tprec)) == NULL) goto tscale_bad;
4673  /* if 10s and 100s illegal */
4674  if (tprec == 0 && tpexp > 0) goto tscale_bad;
4675  tprec -= tpexp;
4676 
4677  /* precision must be smaller or = tick or higher or = exponent */
4678  if (tprec < tunit)
4679   {
4680    __pv_ferr(936,
4681     "time unit %s cannot be smaller than precision %s - `timescale ignored",
4682      __to_timunitnam(__xs, tunit),  __to_timunitnam(__xs2, tprec));
4683    goto done;
4684   }
4685  /* cur units stored as inverse of exponenent so 1 ns 9 not -9 as returned */
4686  __cur_units = tunit;
4687  /* cur precision is amount to add to cur units */
4688  __cur_prec = tprec - __cur_units;
4689  /* warning if extra stuff on end of line - should not be there */
4690  if (!__bqline_emptytail(cp))
4691   __pv_fwarn(567, "`timescale non white space at end of line ignored");
4692  __des_has_timescales = TRUE;
4693  goto done;
4694 
4695 tscale_bad:
4696  __pv_ferr(934, "`timescale directive format incorrect - time scale unchanged");
4697 
4698 done:
4699  __my_free(s1, __macwrklen);
4700 }
4701 
4702 /*
4703  * get a time unit - returns NULL on error else ending cp
4704  */
__get_tmult(char * cp,word32 * num_zeros)4705 extern char *__get_tmult(char *cp, word32 *num_zeros)
4706 {
4707  switch (*cp) {
4708   case 'f': *num_zeros = 15; break;
4709   case 'p': *num_zeros = 12; break;
4710   case 'n': *num_zeros = 9; break;
4711   case 'u': *num_zeros = 6; break;
4712   case 'm': *num_zeros = 3; break;
4713   case 's': *num_zeros = 0; return(++cp);
4714   default: return(NULL);
4715  }
4716  if (*(++cp) != 's') return(NULL);
4717  return(++cp);
4718 }
4719 
4720 
4721 
4722 
4723 
4724 
4725 /*
4726  * SUMMARY AND DESIGN CONTENTS ROUTINES
4727  */
4728 
4729 /*
4730  * routine to print the summary for entire run
4731  */
prt_summary(void)4732 static int32 prt_summary(void)
4733 {
4734  if (__pv_err_cnt != 0 || __pv_warn_cnt != 0 || __inform_cnt != 0)
4735   __cv_msg("  There were %d error(s), %d warning(s), and %d inform(s).\n",
4736    __pv_err_cnt, __pv_warn_cnt, __inform_cnt);
4737 
4738  if (__pv_err_cnt != 0 || __undef_mods > 0) return(1);
4739  if (__verbose)
4740   {
4741    if (__pv_warn_cnt == 0 && __inform_cnt == 0)
4742     __cv_msg("  No errors and no warnings.\n");
4743   }
4744  return(0);
4745 }
4746 
4747 /*
4748  * print the design wide stats
4749  */
prt_deswide_stats(void)4750 static void prt_deswide_stats(void)
4751 {
4752  register struct udp_t *udpp;
4753  register struct mod_t *mdp;
4754  int32 numudps, nummods, numsplitmods, num_tran_nets;
4755 
4756  for (numudps = 0, udpp = __udphead; udpp != NULL; udpp = udpp->udpnxt)
4757   numudps++;
4758  for (nummods = numsplitmods = 0, mdp = __modhdr; mdp != NULL;
4759   mdp = mdp->mnxt)
4760   {
4761    numsplitmods++;
4762    if (!mdp->msplit && !mdp->mpndsplit) nummods++;
4763   }
4764 
4765  if (__verbose)
4766   {
4767    __cv_msg("  Verbose mode statistics:\n");
4768    __cv_msg("  %d source lines read (includes -v/-y library files).\n",
4769     __total_rd_lines);
4770    if (__total_lang_dirs != 0)
4771     __cv_msg("  %d non Verilog source inclusion `language directive(s) read.\n",
4772      __total_lang_dirs);
4773    if (numsplitmods == nummods)
4774     __cv_msg("  Design contains %d module types.\n", nummods);
4775    else
4776     __cv_msg(
4777      "  Design contains %d module types (%d after parameter substitution).\n",
4778       nummods, numsplitmods);
4779 
4780    /* notice memory here goes to next higher 160k from end - i.e. 900k is 2m */
4781    if (numudps != 0)
4782     __cv_msg(
4783      "  %d instantiated udp tables of total size less than %d million bytes.\n",
4784      numudps, (__mem_udpuse + 1160000)/1000000);
4785    if (__num_glbs != 0 || __num_inmodglbs != 0)
4786     __cv_msg(
4787      "  There are %d cross module and %d intra module hierarchical references.\n",
4788      __num_glbs - __num_inmodglbs, __num_inmodglbs);
4789    if ((num_tran_nets = count_tran_nets()) != 0)
4790     {
4791      __cv_msg(
4792       "  %d nets in inout or tran gate connecting transistor channels.\n",
4793       num_tran_nets);
4794     }
4795    if (__gates_removable != 0 || __contas_removable != 0)
4796     {
4797      __cv_msg(
4798       "  %d gates (%d flat) and %d assigns (%d flat) disconnected by gate eater.\n",
4799       __gates_removable, __flgates_removable, __contas_removable,
4800       __flcontas_removable);
4801     }
4802    if (__nets_removable != 0)
4803     {
4804      __cv_msg("  %d nets (%d flat) disconnected by gate eater.\n",
4805       __nets_removable, __flnets_removable);
4806     }
4807    __cv_msg("\n");
4808   }
4809 }
4810 
4811 /*
4812  * count design total nets in transistor or inout channels
4813  */
count_tran_nets(void)4814 static int32 count_tran_nets(void)
4815 {
4816  register int32 ni;
4817  register struct net_t *np;
4818  register struct mod_t *mdp;
4819  int32 ntrnets;
4820 
4821  for (ntrnets = 0, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4822   {
4823    if (mdp->mnnum == 0 || (!mdp->mod_hasbidtran && !mdp->mod_hastran))
4824     continue;
4825    for (ni = 0, np = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, np++)
4826     { if (np->ntraux != NULL) ntrnets++; }
4827   }
4828  return(ntrnets);
4829 }
4830 
4831 /*
4832  * print a message giving memory use
4833  */
mem_use_msg(int32 also_mems)4834 static void mem_use_msg(int32 also_mems)
4835 {
4836  double d1;
4837 
4838  if (__verbose)
4839   {
4840    __cv_msg("  Approximately %ld bytes storage allocated (excluding udps).\n",
4841     __mem_use);
4842    d1 = 100.0*((double) __arrvmem_use/(double) (__memstr_use + __mem_use));
4843    if (also_mems && __arrvmem_use != 0)
4844     {
4845      __cv_msg(
4846       "  Verilog arrays (memories) require %ld bytes (%.2lf%% of total).\n",
4847       __arrvmem_use, d1);
4848     }
4849    /* RELEASE remove --
4850    __prt_memstats();
4851    -- */
4852   }
4853 }
4854 
4855 /*
4856  * print all the design 1 line per module type tables
4857  */
prt_alldesmod_tabs(void)4858 static void prt_alldesmod_tabs(void)
4859 {
4860  __cv_msg("+++ Printing Design Statistics +++\n");
4861  /* even if verbose print design wide statistics here */
4862  prt_deswide_stats();
4863  /* first general module. declarative counts - 1 line per mod */
4864  prt2_desmod_tab();
4865  /* then 1 line per mod of wire stats */
4866  prt2_permod_wiretab();
4867  /* 1 line per mod of strength wires stats if design has strength wires */
4868  st_prt2_permod_wiretab();
4869  /* print task both wire and numbers stats - 1 line per mod with tasks */
4870  prt2_permod_tasktabs();
4871 
4872  /* print the per module type usage tables */
4873  __prt2_mod_typetab(__prt_allstats);
4874  __cv_msg("+++ End of Design Statistics +++\n");
4875 }
4876 
4877 /*
4878  * print table of summary modules statistics for every module
4879  */
prt2_desmod_tab(void)4880 static void prt2_desmod_tab(void)
4881 {
4882  register struct mod_t *mdp;
4883  int32 num_mods, num_tops, num_cells, num_insts, num_gates, num_contas;
4884  int32 num_nets, tot_num_cells, tot_num_insts, tot_num_gates;
4885  int32 tot_num_contas, tot_num_nets;
4886  int32 fltot_num_cells, fltot_num_insts, fltot_num_gates, fltot_num_contas;
4887  int32 fltot_num_nets, num1bcas, fltot_insts_in;
4888  char s1[RECLEN];
4889 
4890  tot_num_cells = tot_num_insts = tot_num_gates = 0;
4891  tot_num_contas = tot_num_nets = 0;
4892  fltot_num_cells = fltot_num_insts = fltot_num_gates = fltot_num_contas = 0;
4893  fltot_num_nets = fltot_insts_in = 0;
4894 
4895  count_mods(&num_mods, &num_tops);
4896  __cv_msg("  Design Module Table: %d modules (%d top level):\n", num_mods,
4897   num_tops);
4898  __cv_msg(
4899   "Module            Level Cells-in Insts-in Primitives  Assigns    Nets");
4900  __cv_msg("  Insts-of\n");
4901  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4902   {
4903    num_cells = count_cells(mdp);
4904    tot_num_cells += num_cells;
4905    fltot_num_cells += num_cells*(int32) mdp->flatinum;
4906    num_insts = (int32) mdp->minum - num_cells;
4907    tot_num_insts += num_insts;
4908    fltot_num_insts += num_insts*(int32) mdp->flatinum;
4909    num_gates = count_gates(mdp, &num1bcas);
4910    tot_num_gates += num_gates;
4911    fltot_num_gates += num_gates*(int32) mdp->flatinum;
4912    num_contas = num1bcas;
4913    num_contas += mdp->mcanum;
4914    tot_num_contas += num_contas;
4915    fltot_num_contas += num_contas*(int32) mdp->flatinum;
4916    num_nets = mdp->mnnum;
4917    tot_num_nets += num_nets;
4918    fltot_num_nets += num_nets*(int32) mdp->flatinum;
4919    fltot_insts_in += mdp->flatinum;
4920    bld_modnam(s1, mdp, 20);
4921    __cv_msg("%-20s%3d   %6d   %6d     %6d   %6d  %6d    %6d\n", s1,
4922     mdp->mlpcnt, num_cells, num_insts, num_gates, num_contas,
4923     num_nets, mdp->flatinum);
4924   }
4925  __cv_msg(
4926   "                          ------   ------     ------   ------  ------");
4927  __cv_msg("    ------\n");
4928  __cv_msg("Static Total:            %7d  %7d    %7d  %7d %7d\n",
4929   tot_num_cells, tot_num_insts, tot_num_gates, tot_num_contas, tot_num_nets);
4930  __cv_msg("Flat Total:              %7d  %7d    %7d  %7d %7d   %7d\n",
4931   fltot_num_cells, fltot_num_insts, fltot_num_gates, fltot_num_contas,
4932   fltot_num_nets, fltot_insts_in);
4933 }
4934 
4935 /*
4936  * build mod name with trunc. and add (C) for cells
4937  * s must be big enough
4938  */
bld_modnam(char * s,struct mod_t * mdp,int32 fldsiz)4939 static void bld_modnam(char *s, struct mod_t *mdp, int32 fldsiz)
4940 {
4941  int32 mlen;
4942 
4943  if (mdp->m_iscell)
4944   {
4945    mlen = strlen(mdp->msym->synam);
4946    if (mlen + 3 > fldsiz)
4947     {
4948      strncpy(s, mdp->msym->synam, fldsiz - 4);
4949      s[fldsiz - 4] = '-';
4950      s[fldsiz - 3] = '\0';
4951      strcat(s, "(C)");
4952     }
4953    else { strcpy(s, mdp->msym->synam); strcat(s, "(C)"); }
4954    return;
4955   }
4956  if ((mlen = strlen(mdp->msym->synam)) > fldsiz)
4957   {
4958    strncpy(s, mdp->msym->synam, fldsiz - 1);
4959    s[fldsiz - 1] = '-';
4960    s[fldsiz] = '\0';
4961   }
4962  else strcpy(s, mdp->msym->synam);
4963 }
4964 
4965 /*
4966  * count number of modules and top modules in circuit
4967  */
count_mods(int32 * nummods,int32 * numtops)4968 static void count_mods(int32 *nummods, int32 *numtops)
4969 {
4970  register struct mod_t *mdp;
4971 
4972  *nummods = 0;
4973  *numtops = 0;
4974  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4975   {
4976    (*nummods)++;
4977    if (mdp->minstnum == 0) (*numtops)++;
4978   }
4979 }
4980 
4981 /*
4982  * count number of instances in module that are cells
4983  */
count_cells(struct mod_t * mdp)4984 static int32 count_cells(struct mod_t *mdp)
4985 {
4986  register int32 ii;
4987  int32 cnum;
4988  struct inst_t *ip;
4989  struct mod_t *imdp;
4990 
4991  for (cnum = 0, ii = 0; ii < mdp->minum; ii++)
4992   {
4993    ip = &(mdp->minsts[ii]);
4994    imdp = ip->imsym->el.emdp;
4995    if (imdp->m_iscell) cnum++;
4996   }
4997  return(cnum);
4998 }
4999 
5000 /*
5001  * count the number of gates in module (includes udps)
5002  *
5003  * cannot just use number because 1 bit contas in gate array
5004  */
count_gates(struct mod_t * mdp,int32 * num1bitcas)5005 static int32 count_gates(struct mod_t *mdp, int32 *num1bitcas)
5006 {
5007  register int32 gi;
5008  register struct gate_t *gp;
5009  int32 gcnt, n1bcas;
5010 
5011  for (gcnt = 0, n1bcas = 0, gi = 0; gi < mdp->mgnum; gi++)
5012   {
5013    gp = &(mdp->mgates[gi]);
5014    if (gp->gmsym->el.eprimp->gateid == G_ASSIGN) n1bcas++;
5015    else gcnt++;
5016   }
5017  *num1bitcas = n1bcas;
5018  return(gcnt);
5019 }
5020 
5021 /*
5022  * print the per module wiring table
5023  */
prt2_permod_wiretab(void)5024 static void prt2_permod_wiretab(void)
5025 {
5026  register struct mod_t *mdp;
5027  int32 prts, prtbits, wires, wirebits, regs, regbits, arrs, arrcells, arrbits;
5028  int32 tot_prts, tot_prtbits, tot_wires, tot_wirebits, tot_regs;
5029  int32 tot_regbits, tot_arrs, tot_arrcells, tot_arrbits;
5030  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[RECLEN], s5[RECLEN];
5031 
5032  tot_prts = tot_prtbits = 0;
5033  tot_wires = tot_wirebits = tot_regs = tot_regbits = tot_arrs = 0;
5034  tot_arrcells = tot_arrbits = 0;
5035  __cv_msg("\n  Per Module Wiring Table (Task Variables Excluded):\n");
5036  __cv_msg("Module           Ports(Bits)   Wires(Bits) Registers(Bits)");
5037  __cv_msg(" Memory(Cells, Bits)\n");
5038  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5039   {
5040    prts = (int32) mdp->mpnum;
5041    prtbits = cnt_modprt_bits(mdp);
5042    cnt_modwires(mdp, &wires, &wirebits, &regs, &regbits, &arrs, &arrcells,
5043     &arrbits);
5044 
5045    tot_prts += prts*(int32) mdp->flatinum;
5046    tot_prtbits += prtbits*(int32) mdp->flatinum;
5047    tot_wires += wires*(int32) mdp->flatinum;
5048    tot_wirebits += wirebits*(int32) mdp->flatinum;
5049    tot_regs += regs*(int32) mdp->flatinum;
5050    tot_regbits += regbits*(int32) mdp->flatinum;
5051    tot_arrs += arrs*(int32) mdp->flatinum;
5052    tot_arrcells += arrcells*(int32) mdp->flatinum;
5053    tot_arrbits += arrbits*(int32) mdp->flatinum;
5054    if (prts == 0) strcpy(s1, ""); else sprintf(s1, "%d(%d)", prts, prtbits);
5055    if (wires == 0) strcpy(s2, "");
5056    else sprintf(s2, "%d(%d)", wires, wirebits);
5057    if (regs == 0) strcpy(s3, ""); else sprintf(s3, "%d(%d)", regs, regbits);
5058    if (arrs == 0) strcpy(s4, "");
5059    else sprintf(s4, "%d(%d, %d)", arrs, arrcells, arrbits);
5060    bld_modnam(s5, mdp, 18);
5061    __cv_msg("%-18s%10s%14s%16s%20s\n", s5, s1, s2, s3, s4);
5062   }
5063  __cv_msg("                ------------ ------------- ---------------");
5064  __cv_msg(" -------------------\n");
5065  if (tot_prts == 0) strcpy(s1, "");
5066  else sprintf(s1, "%d(%d)", tot_prts, tot_prtbits);
5067  if (tot_wires == 0) strcpy(s2, "");
5068  else sprintf(s2, "%d(%d)", tot_wires, tot_wirebits);
5069  if (tot_regs == 0) strcpy(s3, "");
5070  else sprintf(s3, "%d(%d)", tot_regs, tot_regbits);
5071  if (tot_arrs == 0) strcpy(s4, "");
5072  else sprintf(s4, "%d(%d, %d)", tot_arrs, tot_arrcells, tot_arrbits);
5073  __cv_msg("Flat total:    %13s%14s%16s%20s\n", s1, s2, s3, s4);
5074 }
5075 
5076 /*
5077  * count the number of module port bits
5078  */
cnt_modprt_bits(struct mod_t * mdp)5079 static int32 cnt_modprt_bits(struct mod_t *mdp)
5080 {
5081  register int32 pi;
5082  int32 modpbits;
5083  struct mod_pin_t *mpp;
5084 
5085  for (modpbits = 0, pi = 0; pi < mdp->mpnum; pi++)
5086   {
5087    mpp = &(mdp->mpins[pi]);
5088    modpbits += (int32) mpp->mpwide;
5089   }
5090  return(modpbits);
5091 }
5092 
5093 /*
5094  * count the number of top level (non in task/func) wires and bits
5095  */
cnt_modwires(struct mod_t * mdp,int32 * wires,int32 * wirebits,int32 * regs,int32 * regbits,int32 * arrs,int32 * arrcells,int32 * arrbits)5096 static void cnt_modwires(struct mod_t *mdp, int32 *wires, int32 *wirebits,
5097  int32 *regs, int32 *regbits, int32 *arrs, int32 *arrcells, int32 *arrbits)
5098 {
5099  register int32 ni;
5100  register struct net_t *np;
5101  int32 acells;
5102 
5103  *wires = 0;
5104  *wirebits = 0;
5105  *regs = 0;
5106  *regbits = 0;
5107  *arrs = 0;
5108  *arrcells = 0;
5109  *arrbits = 0;
5110 
5111  /* mnets of 0 will not exist unless has at least one net */
5112  if (mdp->mnnum == 0) return;
5113  for (ni = 0, np = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, np++)
5114   {
5115    /* module ports not counted here */
5116    if (np->iotyp != NON_IO) continue;
5117    if (np->ntyp < NONWIRE_ST)
5118     {
5119      (*wires)++;
5120      *wirebits += np->nwid;
5121      continue;
5122     }
5123    if (np->n_isarr)
5124     {
5125      (*arrs)++;
5126      acells = (int32) __get_arrwide(np);
5127      *arrcells += acells;
5128      *arrbits += acells*np->nwid;
5129      continue;
5130     }
5131    (*regs)++;
5132    *regbits += np->nwid;
5133   }
5134 }
5135 
5136 /*
5137  * print the per module strength wiring table
5138  */
st_prt2_permod_wiretab(void)5139 static void st_prt2_permod_wiretab(void)
5140 {
5141  register struct mod_t *mdp;
5142  int32 first_time;
5143  int32 prts, prtbits, wires, wirebits;
5144  int32 st_prts, st_prtbits, st_wires, st_wirebits;
5145  int32 tot_prts, tot_prtbits, tot_wires, tot_wirebits;
5146  int32 st_tot_prts, st_tot_prtbits, st_tot_wires, st_tot_wirebits;
5147  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[RECLEN], s5[RECLEN];
5148 
5149  if (__design_no_strens) return;
5150 
5151  tot_prts = tot_prtbits = st_tot_prts = st_tot_prtbits = 0;
5152  tot_wires = tot_wirebits = st_tot_wires = st_tot_wirebits = 0;
5153  first_time = TRUE;
5154  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5155   {
5156    /* always need to count wires and ports even if no strengths */
5157    prts = (int32) mdp->mpnum;
5158    st_cnt_modprt_bits(mdp, &prtbits, &st_prts, &st_prtbits);
5159    st_cnt_modwires(mdp, &wires, &wirebits, &st_wires, &st_wirebits);
5160    tot_prts += prts*(int32) mdp->flatinum;
5161    tot_prtbits += prtbits*(int32) mdp->flatinum;
5162    tot_wires += wires*(int32) mdp->flatinum;
5163    tot_wirebits += wirebits*(int32) mdp->flatinum;
5164 
5165    /* even if module no strengths, goes in total wires */
5166    if (!mdp->mhassts) continue;
5167    if (first_time)
5168     {
5169      __cv_msg("\n  Per Module Strength Wiring Table:\n");
5170      __cv_msg(
5171       "Module                Ports(Bits)       Percent      Wires(Bits)");
5172      __cv_msg("       Percent\n");
5173      first_time = FALSE;
5174     }
5175    st_tot_prts += st_prts*(int32) mdp->flatinum;
5176    st_tot_prtbits += st_prtbits*(int32) mdp->flatinum;
5177    st_tot_wires += st_wires*(int32) mdp->flatinum;
5178    st_tot_wirebits += st_wirebits*(int32) mdp->flatinum;
5179 
5180    if (st_prts == 0) { strcpy(s1, ""); strcpy(s2, ""); }
5181    else
5182     {
5183      sprintf(s1, "%d(%d)", st_prts, st_prtbits);
5184      sprintf(s2, "%.1f(%.1f)", 100.0*((double) st_prts/prts),
5185       100.0*((double) st_prtbits/prtbits));
5186     }
5187    if (st_wires == 0) { strcpy(s3, ""); strcpy(s4, ""); }
5188    else
5189     {
5190      sprintf(s3, "%d(%d)", st_wires, st_wirebits);
5191      sprintf(s4, "%.1f(%.1f)", 100.0*((double) st_wires/wires),
5192       100.0*((double) st_wirebits/wirebits));
5193     }
5194    bld_modnam(s5, mdp, 20);
5195    __cv_msg("%-20s%13s  %12s  %15s  %12s\n", s5, s1, s2, s3, s4);
5196   }
5197  __cv_msg(
5198   "                      -----------    ----------      -----------  ");
5199  __cv_msg("------------\n");
5200  if (st_tot_prts == 0) { strcpy(s1, ""); strcpy(s2, ""); }
5201  else
5202   {
5203    sprintf(s1, "%d(%d)", st_tot_prts, st_tot_prtbits);
5204    sprintf(s2, "%.1f(%.1f)", 100.0*((double) st_tot_prts/tot_prts),
5205     100.0*((double) st_tot_prtbits/tot_prtbits));
5206   }
5207  if (tot_wires == 0) { strcpy(s3, ""); strcpy(s4, ""); }
5208  else
5209   {
5210    sprintf(s3, "%d(%d)", st_tot_wires, st_tot_wirebits);
5211    sprintf(s4, "%.1f(%.1f)", 100.0*((double) st_tot_wires/tot_wires),
5212     100.0*((double) st_tot_wirebits/tot_wirebits));
5213   }
5214  __cv_msg("Strength total:   %15s   %11s%17s  %12s\n", s1, s2, s3, s4);
5215 }
5216 
5217 /*
5218  * count the number of strength module ports and bits
5219  */
st_cnt_modprt_bits(struct mod_t * mdp,int32 * prtbits,int32 * st_prts,int32 * st_prtbits)5220 static void st_cnt_modprt_bits(struct mod_t *mdp, int32 *prtbits, int32 *st_prts,
5221  int32 *st_prtbits)
5222 {
5223  register int32 pi;
5224  register struct expr_t *catxp;
5225  int32 st_modpbits, modpbits, st_modprts;
5226  struct mod_pin_t *mpp;
5227  struct expr_t *mxp;
5228 
5229  st_modprts = 0;
5230  for (modpbits = st_modpbits = 0, pi = 0; pi < mdp->mpnum; pi++)
5231   {
5232    mpp = &(mdp->mpins[pi]);
5233    modpbits += (int32) mpp->mpwide;
5234    mxp = mpp->mpref;
5235    if (!mxp->x_stren) continue;
5236    st_modprts++;
5237    if (mxp->optyp != LCB) { st_modpbits += (int32) mpp->mpwide; continue; }
5238 
5239    /* notice for concats some ports may be strength others not ? */
5240    for (catxp = mxp->ru.x; catxp != NULL; catxp = catxp->ru.x)
5241     { if (catxp->lu.x->x_stren) st_modpbits += (int32) catxp->lu.x->szu.xclen; }
5242   }
5243  *prtbits = modpbits;
5244  *st_prts = st_modprts;
5245  *st_prtbits = st_modpbits;
5246 }
5247 
5248 /*
5249  * count the number of top level (non in task/func) wires and bits
5250  */
st_cnt_modwires(struct mod_t * mdp,int32 * wires,int32 * wirebits,int32 * st_wires,int32 * st_wirebits)5251 static void st_cnt_modwires(struct mod_t *mdp, int32 *wires, int32 *wirebits,
5252  int32 *st_wires, int32 *st_wirebits)
5253 {
5254  register int32 ni;
5255  register struct net_t *np;
5256  int32 mwires, mwirebits, st_mwires, st_mwirebits;
5257 
5258  mwires = 0;
5259  mwirebits = 0;
5260  st_mwires = 0;
5261  st_mwirebits = 0;
5262  if (mdp->mnnum != 0)
5263   {
5264    for (ni = 0, np = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, np++)
5265     {
5266      /* module ports not counted here */
5267      if (np->iotyp != NON_IO) continue;
5268      if (np->ntyp >= NONWIRE_ST) continue;
5269 
5270      mwires++;
5271      mwirebits += np->nwid;
5272      if (!np->n_stren) continue;
5273      st_mwires++;
5274      st_mwirebits += np->nwid;
5275     }
5276   }
5277  *wires = mwires;
5278  *wirebits = mwirebits;
5279  *st_wires = st_mwires;
5280  *st_wirebits = st_mwirebits;
5281 }
5282 
5283 /*
5284  * print the per module task numbers
5285  * notice number of instances of module does not multiply here
5286  */
prt2_permod_tasktabs(void)5287 static void prt2_permod_tasktabs(void)
5288 {
5289  register struct mod_t *mdp;
5290  int32 inits, always, tasks, funcs, begblks, frks;
5291  int32 tot_inits, tot_always, tot_tasks, tot_funcs, tot_begblks, tot_frks;
5292  int32 first_time;
5293  char s1[RECLEN];
5294 
5295  tot_inits = tot_always = tot_tasks = tot_funcs = tot_begblks = tot_frks = 0;
5296  for (first_time = TRUE, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5297   {
5298    if (mdp->mtasks == NULL) continue;
5299    if (first_time)
5300     {
5301      __cv_msg("\n  Per Module Task Definition Table:\n");
5302      __cv_msg(
5303      "Module            Initial  Always    Task  Function   Lab. Begin");
5304      __cv_msg("  Lab. Fork\n");
5305      first_time = FALSE;
5306     }
5307 
5308    cnt_modtasks(mdp, &inits, &always, &tasks, &funcs, &begblks, &frks);
5309    tot_inits += inits;
5310    tot_always += always;
5311    tot_tasks += frks;
5312    tot_funcs += funcs;
5313    tot_begblks += begblks;
5314    tot_frks += frks;
5315    bld_modnam(s1, mdp, 20);
5316    __cv_msg("%-20s%5d   %5d   %5d     %5d        %5d      %5d\n", s1, inits,
5317     always, tasks, funcs, begblks, frks);
5318   }
5319  if (!first_time)
5320   {
5321    __cv_msg("                    -----   -----   -----     -----        ");
5322    __cv_msg("-----      -----\n");
5323    __cv_msg("Static Total       %6d  %6d  %6d    %6d       %6d     %6d\n",
5324     tot_inits, tot_always, tot_tasks, tot_funcs, tot_begblks, tot_frks);
5325   }
5326 }
5327 
5328 /*
5329  * count the number of tasks, named blocks and funcs
5330  */
cnt_modtasks(struct mod_t * mdp,int32 * inits,int32 * always,int32 * tsks,int32 * funcs,int32 * begblks,int32 * frks)5331 static void cnt_modtasks(struct mod_t *mdp, int32 *inits, int32 *always,
5332  int32 *tsks, int32 *funcs, int32 *begblks, int32 *frks)
5333 {
5334  register struct ialst_t *ialp;
5335  register struct task_t *tskp;
5336  int32 iat;
5337 
5338  *inits = *always = *tsks = *funcs = *begblks = *frks = 0;
5339  for (ialp = mdp->ialst; ialp != NULL; ialp = ialp->ialnxt)
5340   {
5341    iat = ialp->iatyp;
5342    if (iat == INITial) (*inits)++;
5343    else if (iat == ALWAYS) (*always)++;
5344    else __case_terr(__FILE__, __LINE__);
5345   }
5346  for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
5347   {
5348    if (tskp->tsktyp == FUNCTION) (*funcs)++;
5349    else if (tskp->tsktyp == TASK) (*tsks)++;
5350    else if (tskp->tsktyp == Begin) (*begblks)++;
5351    else if (tskp->tsktyp == FORK) (*frks)++;
5352    else __case_terr(__FILE__, __LINE__);
5353   }
5354 }
5355 
5356 /*
5357  * dump every module's table of instantiated types and gate statistics
5358  */
__prt2_mod_typetab(int32 prt_all)5359 extern void __prt2_mod_typetab(int32 prt_all)
5360 {
5361  register struct mod_t *mdp;
5362  register struct udp_t *udpp;
5363  register int32 i;
5364  int32 gid;
5365  int32 *gftab, *gstab, *cgftab, *mftab, *mstab, *uftab, *ustab, *cuftab;
5366  int32 num_mods, num_udps, mhasudps, first_time;
5367  int32 num_contas, tot_insts, tot_gates, tot_udps, tot_fcontas, tot_scontas;
5368  int32 tot_cells, tot_cellgates, tot_celludps, tot_cellassigns;
5369  struct mod_t *imdp;
5370  struct primtab_t *primp;
5371  struct sy_t *syp;
5372  char s1[RECLEN], s2[RECLEN], filref[RECLEN];
5373 
5374  /* allocate the needed tables */
5375  gftab = (int32 *) __my_malloc((LAST_GSYM + 1)*sizeof(int32));
5376  gstab = (int32 *) __my_malloc((LAST_GSYM + 1)*sizeof(int32));
5377  cgftab = (int32 *) __my_malloc((LAST_GSYM + 1)*sizeof(int32));
5378 
5379  for (num_mods = 0, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5380   {
5381    /* need to assign sequence no. to each module */
5382    /* NOTICE - lastinum used for mod splitting but no more needed by here */
5383    mdp->lastinum = num_mods;
5384    num_mods++;
5385   }
5386  /* know there will always be at least one inst or not get here */
5387  mftab = (int32 *) __my_malloc(num_mods*sizeof(int32));
5388  mstab = (int32 *) __my_malloc(num_mods*sizeof(int32));
5389 
5390  num_udps = 0;
5391  uftab = ustab = cuftab = NULL;
5392  if (__udphead != NULL)
5393   {
5394    for (udpp = __udphead; udpp != NULL; udpp = udpp->udpnxt)
5395     {
5396      /* need to assign sequence no. to each udp type */
5397      udpp->uidnum = num_udps;
5398      num_udps++;
5399     }
5400    uftab = (int32 *) __my_malloc(num_udps*sizeof(int32));
5401    ustab = (int32 *) __my_malloc(num_udps*sizeof(int32));
5402    cuftab = (int32 *) __my_malloc(num_udps*sizeof(int32));
5403   }
5404  reset_cntabs(gftab, gstab, cgftab, mftab, mstab, num_mods, uftab, ustab,
5405   cuftab, num_udps);
5406 
5407  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5408   {
5409    /* to get design totals do not zero fields each time through */
5410    accum_usecnts(mdp, gftab, gstab, cgftab, mftab, mstab, uftab, ustab,
5411     cuftab, &mhasudps);
5412   }
5413  /* print design wide totals */
5414  __cv_msg("\n  Design Usage Table:\n");
5415  __cv_msg("Type                      Class  Static   Flat   Location\n");
5416  __cv_msg("                                 Number  Number\n");
5417  /* first 1 line per mod inst - need sorted so must go through mods */
5418  tot_insts = tot_gates = tot_udps = tot_fcontas = tot_scontas = 0;
5419  tot_cells = tot_cellgates = tot_cellassigns = tot_celludps = 0;
5420  for (imdp = __modhdr; imdp != NULL; imdp = imdp->mnxt)
5421   {
5422    syp = imdp->msym;
5423    if (strlen(syp->synam) > 24)
5424     { strncpy(s1, syp->synam, 23); s1[23] = '-'; s1[24] = '\0'; }
5425    else strcpy(s1, syp->synam);
5426 
5427    if (imdp->minstnum == 0) strcpy(s2, "top");
5428    else if (imdp->m_iscell) strcpy(s2, "cell");
5429    else strcpy(s2, "module");
5430    __cv_msg("%-24s  %-6s%7d %7d  %s:%d\n", s1, s2, mstab[imdp->lastinum],
5431     mftab[imdp->lastinum], __schop(filref, __in_fils[syp->syfnam_ind]),
5432     syp->sylin_cnt);
5433    tot_insts += (int32) mftab[imdp->lastinum];
5434    num_contas = imdp->mcanum;
5435    if (imdp->m_iscell)
5436     {
5437      tot_cellassigns += (int32) imdp->flatinum*num_contas;
5438      tot_cells += (int32) mftab[imdp->lastinum];
5439     }
5440    tot_fcontas += (int32) imdp->flatinum*num_contas;
5441    tot_scontas += num_contas;
5442   }
5443  for (udpp = __udphead; udpp != NULL; udpp = udpp->udpnxt)
5444   {
5445    /* if udp defined list even if not used */
5446    syp = udpp->usym;
5447    if (strlen(syp->synam) > 24)
5448     { strncpy(s1, syp->synam, 23); s1[23] = '-'; s1[24] = '\0'; }
5449     else strcpy(s1, syp->synam);
5450    __cv_msg("%-24s  %-6s%7d %7d  %s:%d\n", s1, "udp", ustab[udpp->uidnum],
5451     uftab[udpp->uidnum], __schop(filref, __in_fils[syp->syfnam_ind]),
5452     syp->sylin_cnt);
5453 
5454    tot_udps += (int32) uftab[udpp->uidnum];
5455    tot_celludps += (int32) cuftab[udpp->uidnum];
5456   }
5457  for (i = 0, primp = prims; i < NPRIMS; i++, primp++)
5458   {
5459    gid = primp->gateid;
5460    if (gstab[gid] == 0) continue;
5461    __cv_msg("%-24s  %-6s%7d %7d\n", primp->gatnam, "gate", gstab[gid],
5462     gftab[gid]);
5463    tot_gates += gftab[gid];
5464    tot_cellgates += cgftab[gid];
5465   }
5466  if (tot_fcontas != 0 || tot_scontas != 0)
5467   __cv_msg("%-24s  %-6s%7d %7d\n", "wide-assign", "assign", tot_scontas,
5468    tot_fcontas);
5469 
5470  if (tot_cells == 0)
5471   {
5472    __cv_msg(
5473     "\n  Flattened Design: %d instances, %d udps, %d gates and %d assigns.\n",
5474     tot_insts, tot_udps, tot_gates - gftab[G_ASSIGN],
5475     tot_fcontas + gftab[G_ASSIGN]);
5476   }
5477  else
5478   {
5479    __cv_msg(
5480    "\n  Flattened Design: %d instances (%d of cells), %d udps (%d in cells),\n",
5481     tot_insts, tot_cells, tot_udps, tot_celludps);
5482    __cv_msg("   %d gates (%d in cells) and %d assigns (%d in cells).\n",
5483     tot_gates - gftab[G_ASSIGN], tot_cellgates - cgftab[G_ASSIGN],
5484     tot_fcontas + gftab[G_ASSIGN], tot_cellassigns + cgftab[G_ASSIGN]);
5485   }
5486 
5487  if (!prt_all) goto free_tabs;
5488  __cv_msg(
5489   "\n  Individual Modules Content Tables (Procedural Only Excluded)");
5490  first_time = TRUE;
5491  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5492   {
5493    first_time = TRUE;
5494    reset_cntabs(gftab, gstab, cgftab, mftab, mstab, num_mods, uftab, ustab,
5495     cuftab, num_udps);
5496    accum_usecnts(mdp, gftab, gstab, cgftab, mftab, mstab, uftab, ustab,
5497     cuftab, &mhasudps);
5498 
5499    /* first 1 line per mod inst - need sorted so must go through mods */
5500    for (imdp = __modhdr; imdp != NULL; imdp = imdp->mnxt)
5501     {
5502      if (mstab[imdp->lastinum] == 0) continue;
5503      if (first_time) { prt_modhdr(mdp); first_time = FALSE; }
5504      if (strlen(imdp->msym->synam) > 24)
5505       { strncpy(s1, imdp->msym->synam, 23); s1[23] = '-'; s1[24] = '\0'; }
5506      else strcpy(s1, imdp->msym->synam);
5507      if (imdp->m_iscell) strcpy(s2, "cell"); else strcpy(s2, "module");
5508      __cv_msg("%-24s  %-6s        %10d      %10d\n", s1, s2,
5509       mstab[imdp->lastinum], mftab[imdp->lastinum]);
5510     }
5511    if (mhasudps)
5512     {
5513      for (udpp = __udphead; udpp != NULL; udpp = udpp->udpnxt)
5514       {
5515        if (ustab[udpp->uidnum] == 0) continue;
5516 
5517        if (first_time) { prt_modhdr(mdp); first_time = FALSE; }
5518        if (strlen(udpp->usym->synam) > 24)
5519         { strncpy(s1, udpp->usym->synam, 23); s1[23] = '-'; s1[24] = '\0'; }
5520        else strcpy(s1, udpp->usym->synam);
5521        __cv_msg("%-24s  %-6s        %10d      %10d\n", s1, "udp",
5522         ustab[udpp->uidnum], uftab[udpp->uidnum]);
5523       }
5524     }
5525    if (mdp->mgates != NULL)
5526     {
5527      for (i = 0, primp = prims; i < NPRIMS; i++, primp++)
5528       {
5529        gid = primp->gateid;
5530        if (gstab[gid] == 0) continue;
5531        if (first_time) { prt_modhdr(mdp); first_time = FALSE; }
5532        __cv_msg("%-24s  gate          %10d      %10d\n", primp->gatnam,
5533         gstab[gid], gftab[gid]);
5534       }
5535     }
5536    num_contas = mdp->mcanum;
5537    if (num_contas != 0)
5538     {
5539      if (first_time) { prt_modhdr(mdp); first_time = FALSE; }
5540      __cv_msg("%-24s  %-12s  %10d      %10d\n", "wide-assign",
5541       "assign", num_contas, num_contas*(int32)mdp->flatinum);
5542     }
5543   }
5544  /* may somehow have no modules? */
5545  if (first_time) __cv_msg("\n");
5546 free_tabs:;
5547  /* if no alloca would need frees here */
5548 
5549  __my_free((char *) gftab, (LAST_GSYM + 1)*sizeof(int32));
5550  __my_free((char *) gstab, (LAST_GSYM + 1)*sizeof(int32));
5551  __my_free((char *) cgftab, (LAST_GSYM + 1)*sizeof(int32));
5552  __my_free((char *) mftab, num_mods*sizeof(int32));
5553  __my_free((char *) mstab, num_mods*sizeof(int32));
5554  if (uftab != NULL) __my_free((char *) uftab, num_udps*sizeof(int32));
5555  if (ustab != NULL) __my_free((char *) ustab, num_udps*sizeof(int32));
5556  if (cuftab != NULL) __my_free((char *) cuftab, num_udps*sizeof(int32));
5557 }
5558 
5559 /*
5560  * print the module table header - if contains declared elements
5561  */
prt_modhdr(struct mod_t * mdp)5562 static void prt_modhdr(struct mod_t *mdp)
5563 {
5564  char s1[RECLEN], s2[RECLEN];
5565 
5566  if (!mdp->m_iscell) strcpy(s1, "Module"); else strcpy(s1, "Cell");
5567  if (mdp->minstnum == 0) strcpy(s2, "(top)");
5568  else sprintf(s2, "(Instantiated %d Times)", mdp->flatinum);
5569  __cv_msg("\n  %s %s %s Type Usage Table:\n", s1, mdp->msym->synam, s2);
5570  __cv_msg(
5571   "Type                      Class      Static Number     Flat Number\n");
5572 }
5573 
5574 /*
5575  * reset all count tables
5576  */
reset_cntabs(int32 * gftab,int32 * gstab,int32 * cgftab,int32 * mftab,int32 * mstab,int32 nmods,int32 * uftab,int32 * ustab,int32 * cuftab,int32 nudps)5577 static void reset_cntabs(int32 *gftab, int32 *gstab, int32 *cgftab, int32 *mftab,
5578  int32 *mstab, int32 nmods, int32 *uftab, int32 *ustab, int32 *cuftab, int32 nudps)
5579 {
5580  if (gftab != NULL) memset(gftab, 0, (LAST_GSYM + 1)*sizeof(int32));
5581  if (gstab != NULL) memset(gstab, 0, (LAST_GSYM + 1)*sizeof(int32));
5582  if (cgftab != NULL) memset(cgftab, 0, (LAST_GSYM + 1)*sizeof(int32));
5583 
5584  if (mftab != NULL) memset(mftab, 0, nmods*sizeof(int32));
5585  if (mstab != NULL) memset(mstab, 0, nmods*sizeof(int32));
5586  if (uftab != NULL) memset(uftab, 0, nudps*sizeof(int32));
5587  if (ustab != NULL) memset(ustab, 0, nudps*sizeof(int32));
5588  if (cuftab != NULL) memset(cuftab, 0, nudps*sizeof(int32));
5589 }
5590 
5591 /*
5592  * accumulate usage statistics gates in one module
5593  * must be reset to 0 before here - values accumulated
5594  * if this module has udps sets has udp flag
5595  */
accum_usecnts(struct mod_t * mdp,int32 * gftab,int32 * gstab,int32 * cgftab,int32 * mftab,int32 * mstab,int32 * uftab,int32 * ustab,int32 * cuftab,int32 * mhasudps)5596 static void accum_usecnts(struct mod_t *mdp, int32 *gftab, int32 *gstab,
5597  int32 *cgftab, int32 *mftab, int32 *mstab, int32 *uftab, int32 *ustab, int32 *cuftab,
5598  int32 *mhasudps)
5599 {
5600  register int32 ii, gi;
5601  int32 gid;
5602  struct inst_t *ip;
5603  struct mod_t *imdp;
5604  struct gate_t *gp;
5605  struct udp_t *udpp;
5606 
5607  /* notice previous call always reset each mod use count */
5608  /* first time starts at 0 */
5609  /* update both in this module count and design wide use count */
5610  for (ii = 0; ii < mdp->minum; ii++)
5611   {
5612    ip = &(mdp->minsts[ii]);
5613    imdp = ip->imsym->el.emdp;
5614    /* notice lastinum is just sequence no. assigned here - fld reused here */
5615    mstab[imdp->lastinum] += 1;
5616    mftab[imdp->lastinum] += (int32) mdp->flatinum;
5617   }
5618  /* finally do the counting */
5619  *mhasudps = FALSE;
5620  for (gi = 0; gi < mdp->mgnum; gi++)
5621   {
5622    gp = &(mdp->mgates[gi]);
5623    if (gp->g_class == GC_UDP)
5624     {
5625      *mhasudps = TRUE;
5626      udpp = gp->gmsym->el.eudpp;
5627      /* DBG remove --- */
5628      if (ustab == NULL) __misc_terr(__FILE__, __LINE__);
5629      if (uftab == NULL) __misc_terr(__FILE__, __LINE__);
5630      /* --- */
5631      ustab[udpp->uidnum] += 1;
5632      uftab[udpp->uidnum] += (int32) mdp->flatinum;
5633      continue;
5634     }
5635    gid = gp->gmsym->el.eprimp->gateid;
5636    gstab[gid] += 1;
5637    gftab[gid] += (int32) mdp->flatinum;
5638   }
5639  if (!mdp->m_iscell) return;
5640 
5641  for (gi = 0; gi < mdp->mgnum; gi++)
5642   {
5643    gp = &(mdp->mgates[gi]);
5644    if (gp->g_class == GC_UDP)
5645     {
5646      udpp = gp->gmsym->el.eudpp;
5647      /* DBG remove --- */
5648      if (cuftab == NULL) __misc_terr(__FILE__, __LINE__);
5649      /* --- */
5650      cuftab[udpp->uidnum] += (int32) mdp->flatinum;
5651      continue;
5652     }
5653    gid = gp->gmsym->el.eprimp->gateid;
5654    cgftab[gid] += (int32) mdp->flatinum;
5655   }
5656 }
5657