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, ®s, ®bits, &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