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  * source reading of module items except for specify and udps
30  */
31 
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <stdlib.h>
36 
37 #ifdef __DBMALLOC__
38 #include "../malloc.h"
39 #endif
40 
41 #include "v.h"
42 #include "cvmacros.h"
43 
44 /* local prototypes */
45 static void decl_instconns(struct mod_t *);
46 static void dcl_iconn_wires(struct cell_t *, struct expr_t *);
47 static void freeze_mod_syms(struct symtab_t *, struct symtab_t *);
48 static void travfreeze_syms(register struct tnode_t *);
49 static void travfreeze_lowsymtab(register struct symtab_t *);
50 static void bld_mdpin_table(struct mod_t *);
51 static int32 rd_modhdr(struct mod_t *);
52 static int32 rd_hdrpnd_parmdecls(void);
53 static int32 rd_portref(void);
54 static void set_ioprtnets(struct expr_t *);
55 static int32 rd_list_of_ports_decl(struct mod_t *);
56 static int32 rd_modbody(void);
57 static int32 rd_iodecl(word32);
58 static void add_net_attr(struct net_t *, int32);
59 static int32 rd_vardecl(word32);
60 static void chk_capwdecl_strens(word32);
61 static void chk_drvstren(word32);
62 static int32 rd_oparamdels(struct paramlst_t **);
63 static int32 do_wdecl_assgn(struct sy_t *, struct paramlst_t *, int32);
64 static int32 rdbld_mod_varinitlst(struct sy_t *);
65 static int32 is_decl_err(struct sy_t *, word32, word32);
66 static void set_reg_widths(word32, struct expr_t **, struct expr_t **);
67 static int32 chkset_wdrng(struct net_t *, struct expr_t *, struct expr_t *);
68 static int32 cmp_rng(struct expr_t *, struct expr_t *, struct expr_t *,
69  struct expr_t *);
70 static int32 rd_verstrens(void);
71 static int32 rd_1verstren(int32 *);
72 static int32 is_tokstren(int32);
73 static int32 rd_opt_param_array_rng(struct expr_t **, struct expr_t **,
74  int32);
75 static struct net_t *chkadd_array_param(char *, int32, int32, int32,
76  struct expr_t *, struct expr_t *, struct expr_t *, struct expr_t *);
77 static void cnvt_to_pdecl(struct xstk_t *, struct expr_t *, struct net_t *,
78  char *);
79 static void unwind_param_array_constructor(struct expr_t *);
80 static void chk1_arrinit_expr(struct expr_t *, char *, int32);
81 static int32 rd_contassign(void);
82 static struct conta_t *add_conta(struct expr_t *, struct expr_t *, int32,
83  int32);
84 static int32 rd_eventdecl(int32);
85 static int32 rd_paramdecl(int32, int32);
86 static int32 rd_dfparam_stmt(void);
87 static struct dfparam_t *alloc_dfpval(void);
88 static int32 rd_task(void);
89 static word32 to_tasksytyp(int32);
90 static int32 rd_taskvardecl(word32, int32, char *);
91 static struct net_t *decl_taskvar(word32, struct expr_t *, struct expr_t *);
92 static struct task_pin_t *alloc_tskpin(void);
93 static int32 rd_func(void);
94 static void add_funcretdecl(char *, word32, struct expr_t *,
95  struct expr_t *, int32);
96 static int32 rd_inst(char *);
97 static void add_cell_attr(struct cell_t *);
98 static int32 rd_pull_stren(char *, int32 *);
99 static struct namparam_t *rd_npndparams(void);
100 static struct namparam_t *rd1_namedparam(void);
101 static struct namparam_t *copy_namparamlst(struct namparam_t *);
102 static int32 rd_iports(char *);
103 static int32 rd_cpin_conn(void);
104 static char *alloc_cpnam(char *);
105 static struct cell_pin_t *alloc_memcpins(void);
106 static struct cell_t *add_cell(char *);
107 static struct cell_t *alloc_memcell(void);
108 static void init_task(struct task_t *);
109 static int32 rd_tf_list_of_ports_decl(struct task_t *, char *);
110 
111 /* extern prototypes (maybe defined in this module) */
112 extern char *__pv_stralloc(char *);
113 extern char *__my_malloc(int32);
114 extern struct mod_t *__alloc_mod(struct sy_t *);
115 extern void __init_mod(struct mod_t *, struct sy_t *);
116 extern int32 __xpr_has_param(struct expr_t *);
117 extern struct ncomp_t *__alloc_arrncomp(void);
118 extern char *__prt_kywrd_vtok(void);
119 extern char *__prt_vtok(void);
120 extern void __freeze_1symtab(struct symtab_t *);
121 extern struct sy_t *__get_sym_env(char *);
122 extern struct sy_t *__get_sym(char *, struct symtab_t *);
123 extern struct sy_t *__decl_sym(char *, struct symtab_t *);
124 extern struct sy_t *__bld_loc_symbol(int32, struct symtab_t *, char *,
125  char *);
126 extern struct sy_t *__find_sym(char *);
127 extern struct net_t *__add_net(struct sy_t *);
128 extern struct net_t *__decl_wirereg(word32, struct expr_t *,
129  struct expr_t *, struct sy_t *);
130 extern struct sy_t *__add_modsym(char *);
131 extern char *__to_ptnam(char *, word32);
132 extern char *__to_wtnam(char *, struct net_t *);
133 extern char *__to_wtnam2(char *, word32);
134 extern char *__to_wrange(char *, struct net_t *);
135 extern char *__get_vkeynam(char *, int32);
136 extern char *__to_sytyp(char *, word32);
137 extern char *__msgtox_wrange(char *, struct expr_t *, struct expr_t *);
138 extern char *__msgexpr_tostr(char *, struct expr_t *);
139 extern char *__pregab_tostr(char *, word32 *, word32 *, struct net_t *);
140 extern char *__to_stren_nam(char *, int32, int32);
141 extern word32 __fr_stren_nam(int32);
142 extern struct symtab_t *__alloc_symtab(int32);
143 extern struct mod_pin_t *__alloc_modpin(void);
144 extern struct tnode_t *__vtfind(char *, struct symtab_t *);
145 extern struct namparam_t *__alloc_namparam(void);
146 extern struct paramlst_t *__copy_dellst(struct paramlst_t *);
147 extern struct expr_t *__bld_rng_numxpr(word32, word32, int32);
148 extern struct st_t *__alloc_stmt(int32);
149 extern struct st_t *__alloc2_stmt(int32, int32, int32);
150 extern struct delctrl_t *__alloc_dctrl(void);
151 extern char *__to_splt_nam(char *, int32);
152 extern struct st_t *__rd_stmt(void);
153 extern struct paramlst_t *__alloc_pval(void);
154 extern struct task_t *__alloc_task(struct sy_t *);
155 extern struct expr_t *__gen_wireid_expr(struct sy_t *);
156 extern char *__bld_lineloc(char *, word32, int32);
157 extern struct xstk_t *__eval2_xpr(struct expr_t *);
158 extern struct xstk_t *__src_rd_eval_xpr(struct expr_t *);
159 extern word32 __to_cap_size(int32);
160 extern struct expr_t *__copy_expr(struct expr_t *);
161 extern struct expr_t *__alloc_newxnd(void);
162 extern void __get_vtok(void);
163 extern int32 __rd_moddef(struct symtab_t *, int32);
164 extern struct gref_t *__alloc_grtab(struct gref_t *, int32);
165 extern int32 __rd_udpdef(struct symtab_t *);
166 extern int32 __vskipto_modend(int32);
167 extern int32 __vskipto_lofp_end(void);
168 extern int32 __vskipto2_lofp_end(void);
169 extern void __add_sym(char *, struct tnode_t *);
170 extern int32 __rd_decl_rng(struct expr_t **, struct expr_t **);
171 extern int32 __chk_redef_err(char *, struct sy_t *, char *, word32);
172 extern void __remove_undef_mod(struct sy_t *);
173 extern void __my_free(char *, int32);
174 extern int32 __vskipto2_any(int32, int32);
175 extern int32 __vskipto3_any(int32, int32, int32);
176 extern int32 __vskipto4_any(int32, int32, int32, int32);
177 extern void __unget_vtok(void);
178 extern int32 __col_parenexpr(int32);
179 extern int32 __col_connexpr(int32);
180 extern void __bld_xtree(int32);
181 extern int32 __rd_spfy(struct mod_t *);
182 extern int32 __fr_wtnam(int32);
183 extern int32 __vskipto_any(int32);
184 extern int32 __col_rangeexpr(void);
185 extern int32 __is_capstren(int32);
186 extern int32 __col_comsemi(int32);
187 extern void __set_numval(struct expr_t *, word32, word32, int32);
188 extern int32 __col_lval(void);
189 extern int32 __col_newparamrhsexpr(void);
190 extern int32 __col_lofp_paramrhsexpr(void);
191 extern int32 __bld_tsk(char *, int32);
192 extern int32 __rd_tfdecls(char *);
193 extern int32 __bld_expnode(void);
194 extern void __set_xtab_errval(void);
195 extern int32 __col_delexpr(void);
196 extern int32 __vskipto3_modend(int32, int32, int32);
197 extern void __set_opempty(int32);
198 extern void __free_xtree(struct expr_t *);
199 extern void __free2_xtree(struct expr_t *);
200 extern int32 __src_rd_chk_paramexpr(struct expr_t *, int32);
201 extern int32 __rd_opt_param_vec_rng(struct expr_t **, struct expr_t **,
202  int32);
203 extern int32 __chk_paramexpr(struct expr_t *, int32);
204 extern void __eval_param_rhs_tonum(struct expr_t *);
205 extern int32 __nd_ndxnum(struct expr_t *, char *, int32);
206 extern struct net_t *__add_param(char *, struct expr_t *, struct expr_t *,
207  int32);
208 extern void __init_stmt(struct st_t *, int32);
209 
210 extern int32 __expr_has_glb(struct expr_t *);
211 extern int32 __isleaf(struct expr_t *);
212 extern struct expr_t *__dup_concat(int32, struct expr_t *);
213 extern struct expr_t *__find_catend(struct expr_t *);
214 extern void __free_namedparams(struct namparam_t *);
215 extern struct cell_t *__alloc_cell(struct sy_t *);
216 extern struct cell_pin_t *__alloc_cpin(int32);
217 extern void __add_syp_to_undefs(struct sy_t *);
218 extern void __src_rd_cnv_stk_fromreg_toreal(struct xstk_t *, int32);
219 extern void __src_rd_cnv_stk_fromreal_toreg32(struct xstk_t *);
220 extern void __sizchgxs(struct xstk_t *, int32);
221 extern void __narrow_sizchg(register struct xstk_t *, int32);
222 extern void __sizchg_widen(register struct xstk_t *, int32);
223 extern void __sgn_xtnd_widen(struct xstk_t *, int32);
224 extern int32 __wide_vval_is0(register word32 *, int32);
225 extern int32 __allocfill_cval_new(word32 *, word32 *, int32);
226 extern int32 __alloc_shareable_cval(word32, word32, int32);
227 extern int32 __alloc_shareable_rlcval(double);
228 extern char *__to1_stren_nam(char *, int32, int32);
229 extern void __push_wrkitstk(struct mod_t *, int32);
230 extern void __pop_wrkitstk(void);
231 extern int32 __cmp_xpr(struct expr_t *, struct expr_t *);
232 extern struct attr_t *__rd_parse_attribute(struct attr_t *);
233 extern void __cnv_stk_fromreg_toreal(struct xstk_t *, int32);
234 extern void __cnv_stk_fromreal_toreg32(struct xstk_t *);
235 
236 
237 extern void __cv_msg(char *, ...);
238 extern void __crit_msg(char *, ...);
239 extern void __pv_ferr(int32, char *, ...);
240 extern void __pv_fwarn(int32, char *, ...);
241 extern void __gfinform(int32, word32, int32, char *, ...);
242 extern void __finform(int32, char *, ...);
243 extern void __dbg_msg(char *, ...);
244 extern void __pv_terr(int32, char *, ...);
245 extern void __arg_terr(char *, int32);
246 extern void __case_terr(char *, int32);
247 extern void __misc_terr(char *, int32);
248 extern void __misc_fterr(char *, int32);
249 
250 /*
251  * read one top level module or udp definition
252  * expects a keyword to have been read and reads end of module
253  *
254  * upon return current token must be endmodule/primitive or eof or
255  * one before module/primitive
256  */
__rd_ver_mod(void)257 extern void __rd_ver_mod(void)
258 {
259  switch ((byte) __toktyp) {
260   case TEOF: return;
261   case MACROMODULE:
262    __get_vtok();
263    __finform(423, "macromodules not expanded - %s translated as module",
264     __token);
265    goto rd_def;
266   case MODULE:
267    /* know these will either die with eof or have read end mod/prim */
268    /* or have skipped on error so next token read is mod/prim */
269    __get_vtok();
270 rd_def:
271    __rd_moddef(NULL, FALSE);
272    break;
273   case PRIMITIVE:
274    /* because library must check for unresolved, get name before call */
275    __get_vtok();
276    __rd_udpdef(NULL);
277    break;
278   case GENERATE:
279    __pv_ferr(3549, "generate feature not implemented in this version");
280    __vskipto_modend(ENDGENERATE);
281    break;
282   default:
283    __pv_ferr(975, "module or primitive keyword expected - %s read",
284     __prt_vtok());
285    /* for common extra ;, will move to module and back up 1 */
286    /* otherwise will skip to eof */
287    __vskipto_modend(ENDMODULE);
288  }
289 }
290 
291 /*
292  * cfg form of read ver mod
293  *
294  * SJM FIXME ??? - why is this different version needed
295  */
__rd_cfg_ver_mod(void)296 extern void __rd_cfg_ver_mod(void)
297 {
298  switch ((byte) __toktyp) {
299   case TEOF: return;
300   case MACROMODULE:
301    __get_vtok();
302    __finform(423, "macromodules not expanded - %s translated as module",
303     __token);
304    __get_vtok();
305    break;
306   case MODULE:
307    /* know these will either die with eof or have read end mod/prim */
308    /* or have skipped on error so next token read is mod/prim */
309    __get_vtok();
310    break;
311   case PRIMITIVE:
312    /* because library must check for unresolved, get name before call */
313    __get_vtok();
314    break;
315   default:
316    __pv_ferr(975, "module or primitive keyword expected - %s read",
317     __prt_vtok());
318    /* for common extra ;, will move to module and back up 1 */
319    /* otherwise will skip to eof */
320  }
321 }
322 
323 /*
324  * MODULE DEFINITION ROUTINES
325  */
326 
327 /*
328  * read a module definition
329  *
330  * if reading config, put module name in passed config lib el sym table
331  * upon return current token must be synced to file level token
332  * return F if parse errors, T even if other errors
333  */
__rd_moddef(struct symtab_t * cfg_sytab,int32 isconfig)334 extern int32 __rd_moddef(struct symtab_t *cfg_sytab, int32 isconfig)
335 {
336  struct sy_t *syp;
337  struct symtab_t *sp_sytp;
338  struct mod_t *mdp;
339  struct tnode_t *tnp;
340 
341  __lofp_port_decls = FALSE;
342  /* DBG remove --- */
343  if (__top_sti != 0) __misc_terr(__FILE__, __LINE__);
344  if (__inst_mod != NULL) __misc_terr(__FILE__, __LINE__);
345  /* --- */
346 
347  /* these are couner for use in building object names */
348  __cp_num = __conta_num = 1;
349 
350  /* notice that Verilog keywords are reserved words */
351  if (__toktyp != ID)
352   {
353 no_read:
354    __pv_ferr(976, "module name expected - %s read", __prt_kywrd_vtok());
355    __vskipto_modend(ENDMODULE);
356    return(FALSE);
357   }
358 
359  /* SJM 01/07/04 - if module in config library file, put into its mod sy tab */
360  if (cfg_sytab != NULL)
361   {
362    tnp = __vtfind(__token, cfg_sytab);
363    /* dups already checked for */
364    /* DBG remove -- */
365    if (!__sym_is_new) __misc_terr(__FILE__, __LINE__);
366    /* --- */
367    __add_sym(__token, tnp);
368    (cfg_sytab->numsyms)++;
369    syp = tnp->ndp;
370   }
371  else syp = __add_modsym(__token);
372 
373  if (syp == NULL) goto no_read;
374  syp->cfg_needed = FALSE;
375  syp->sytyp = SYM_M;
376 
377  mdp = __alloc_mod(syp);
378  syp->el.emdp = mdp;
379  /* AIV 05/24/04 - need to set flag to get rid of highest level mods */
380  /* that are scanned but never used in configs */
381  mdp->m_inconfig = isconfig;
382  /* this is where module definition actually resolved */
383  syp->sydecl = TRUE;
384  /* need place where udp declared */
385  syp->syfnam_ind = __cur_fnam_ind;
386  syp->sylin_cnt = __lin_cnt;
387 
388  /* if saw attribute before reading latest module keyword save */
389  /* as string - evaled during pass 2 fixup */
390  if (__wrk_attr.attr_seen)
391   {
392    /* here only one string possible - on serious error returns nil */
393    /* if returns non nil, at least some attr_specs good */
394    mdp->mattrs = __rd_parse_attribute(&__wrk_attr);
395    /* SJM 07/30/01 - this is work read value, but now done with it */
396    __my_free(__wrk_attr.attrnam, __attr_line_len + 1);
397    __wrk_attr.attr_seen = FALSE;
398   }
399  __push_wrkitstk(mdp, 0);
400 
401  /* must also allocate the new symbol table */
402  __inst_mod->msymtab = __alloc_symtab(TRUE);
403  /* module symbol table always outermost */
404  __inst_mod->msymtab->sytpar = NULL;
405  /* link symbol table back to module symbol */
406  __inst_mod->msymtab->sypofsyt = syp;
407 
408  /* set list ends for elements that must be kept in order */
409  __end_cp = NULL; __end_tbp = NULL;
410  __end_paramnp = __end_loc_paramnp = NULL;
411  __end_ca = NULL; __end_ialst = NULL; __end_dfp = NULL;
412  __end_impparamnp = NULL;
413  __end_mod_varinitlst = NULL;
414  __cur_declobj = MODULE;
415  __mod_specparams = 0;
416  /* initialize symbol table stack so module on bottom */
417  /* replaces previous module symbol table so no need to pop here */
418  /* system names now in separate symbol table and separated by $ prefix */
419  __top_sti = 0;
420  __venviron[0] = __inst_mod->msymtab;
421 
422  /* do not need to build type until entire module read */
423  /* if these return F, know needed to skip to file level mod/prim */
424  if (!rd_modhdr(__inst_mod)) goto bad_end;
425  if (!rd_modbody()) goto bad_end;
426 
427  /* if error will not get linked in - this quarentees source order */
428  if (__end_mdp == NULL) __modhdr = __inst_mod;
429  else __end_mdp->mnxt = __inst_mod;
430  __end_mdp = __inst_mod;
431 
432  /* current module now always one root of symbol table tree */
433  /* declare wire names used in inst. conns. as 1 bit wires */
434  decl_instconns(__inst_mod);
435  /* here may have no specparams but symbol because of syntax error */
436  /* in common attempt to use defparams as specparams error */
437  if (__inst_mod->mspfy != NULL && __inst_mod->mspfy->spfsyms != NULL)
438   sp_sytp = __inst_mod->mspfy->spfsyms;
439  else sp_sytp = NULL;
440  freeze_mod_syms(__inst_mod->msymtab, sp_sytp);
441  bld_mdpin_table(__inst_mod);
442 
443  /* copy wrk gr table to module's gr table */
444  if (__grwrknum > 0)
445   {
446    __inst_mod->mgrtab = __alloc_grtab(__grwrktab, __grwrknum);
447    __inst_mod->mgrnum = __grwrknum;
448    __grwrknum = 0;
449   }
450 
451  __last_libmdp = __inst_mod;
452  __pop_wrkitstk();
453  return(TRUE);
454 
455 bad_end:
456  /* need to free storage so no inst. will find this type */
457  /* assuming could not stay synced while reading */
458  if (__mod_specparams > 0) sp_sytp = __inst_mod->mspfy->spfsyms;
459  else sp_sytp = NULL;
460  freeze_mod_syms(__inst_mod->msymtab, sp_sytp);
461  /* make undeclared */
462  syp->sydecl = FALSE;
463  __pop_wrkitstk();
464  return(TRUE);
465 }
466 
467 /*
468  * add the module name symbol to symbol table
469  */
__add_modsym(char * nam)470 extern struct sy_t *__add_modsym(char *nam)
471 {
472  struct tnode_t *tnp;
473  struct sy_t *syp;
474 
475  tnp = __vtfind(nam, __modsyms);
476  /* this is define before use in source file case */
477  if (__sym_is_new)
478   {
479    __add_sym(nam, tnp);
480    (__modsyms->numsyms)++;
481    syp = tnp->ndp;
482   }
483  else
484   {
485    /* path impossible for copy mod splitting */
486    syp = tnp->ndp;
487    if (!__chk_redef_err(nam, syp, "module", SYM_M)) return(NULL);
488    /* chk fail means never in module undef list */
489    __remove_undef_mod(syp);
490   }
491  syp->sytyp = SYM_M;
492  return(syp);
493 }
494 
495 /*
496  * remove a module from the undef list and count
497  * module now resolved
498  */
__remove_undef_mod(struct sy_t * syp)499 extern void __remove_undef_mod(struct sy_t *syp)
500 {
501  struct undef_t *undefp;
502 
503  /* repeated use of "module [name]" with no definition will cause */
504  /* lots of syntax error but also will have no module to remove */
505  if (!syp->syundefmod) return;
506 
507  /* DBG remove -- */
508  if (syp->sydecl) __misc_terr(__FILE__, __LINE__);
509  /* --- */
510  undefp = syp->el.eundefp;
511  __undef_mods--;
512  /* case 1, removing head */
513  if (undefp == __undefhd)
514   {
515    if (undefp == __undeftail)
516     {
517      __undefhd = __undeftail = NULL;
518      if (__undef_mods != 0) __misc_terr(__FILE__, __LINE__);
519     }
520    else { __undefhd = undefp->undefnxt; __undefhd->undefprev = NULL; }
521   }
522  /* case 2, removing tail - know at least 2 elements */
523  else if (undefp == __undeftail)
524   {
525    /* SJM 06/03/2002 - added extra fields for 64 bit clean - no sharing */
526    __undeftail = undefp->undefprev;
527    __undeftail->undefnxt = NULL;
528   }
529  /* case 3, removing internal */
530  else
531   {
532    undefp->undefprev->undefnxt = undefp->undefnxt;
533    undefp->undefnxt->undefprev = undefp->undefprev;
534   }
535  syp->syundefmod = FALSE;
536  syp->el.eundefp = NULL;
537 }
538 
539 /*
540  * allocate a new module
541  */
__alloc_mod(struct sy_t * syp)542 extern struct mod_t *__alloc_mod(struct sy_t *syp)
543 {
544  struct mod_t *mdp;
545 
546  mdp = (struct mod_t *) __my_malloc(sizeof(struct mod_t));
547  __init_mod(mdp, syp);
548  return(mdp);
549 }
550 
551 /*
552  * allocate a new module
553  */
__init_mod(struct mod_t * mdp,struct sy_t * syp)554 extern void __init_mod(struct mod_t *mdp, struct sy_t *syp)
555 {
556  mdp->msym = syp;
557  mdp->mod_last_lini = -1;
558  mdp->mod_last_ifi = -1;
559  mdp->msymtab = NULL;
560  mdp->mod_cfglbp = NULL;
561  mdp->minstnum = 0;
562  mdp->mhassts = FALSE;
563  mdp->msplit = FALSE;
564  mdp->mpndsplit = FALSE;
565  mdp->mhassplit = FALSE;
566  mdp->mgone = FALSE;
567  mdp->msplitpth = FALSE;
568  mdp->mwiddetdone = FALSE;
569  mdp->mhas_widthdet = FALSE;
570  mdp->mhas_indir_widdet = FALSE;
571  mdp->mgiarngdone = FALSE;
572  mdp->mpndprm_ingirng = FALSE;
573  mdp->mpnd_girng_done = FALSE;
574  mdp->mhasisform = FALSE;
575  /* default is 1 ns.(time unit) with 0 digits percision */
576  mdp->mtime_units = __cur_units;
577  /* normally just round (0 frac. digits of precision) */
578  /* module precision is mtime units plus mtime units */
579  mdp->mtime_prec = __cur_prec;
580  mdp->mno_unitcnv = FALSE;
581  if (__in_cell_region) { mdp->m_iscell = TRUE; __design_has_cells = TRUE; }
582  else mdp->m_iscell = FALSE;
583  mdp->m_hascells = FALSE;
584  mdp->mod_hasdvars = FALSE;
585  mdp->mod_dvars_in_src = FALSE;
586  mdp->mod_dumiact = FALSE;
587  mdp->mod_rhs_param = FALSE;
588  mdp->mod_hasbidtran = FALSE;
589  mdp->mod_hastran = FALSE;
590  mdp->mod_gatetran = FALSE;
591  mdp->mod_1bcas = FALSE;
592  mdp->mod_has_mipds = FALSE;
593  mdp->mod_parms_gd = FALSE;
594  mdp->mod_lofp_decl = FALSE;
595  /* values not used by cver but set so vpi_ routines can return */
596  mdp->mod_dfltntyp = (word32) __dflt_ntyp;
597  mdp->mod_uncdrv =  (word32) __unconn_drive;
598  mdp->mhas_frcassgn = FALSE;
599  mdp->flatinum = 0;
600  mdp->mpnum = 0;
601  mdp->miarr = NULL;
602  mdp->mpins = NULL;
603  mdp->mgates = NULL;
604  mdp->mgarr = NULL;
605  mdp->minum = 0;
606  mdp->mgnum = 0;
607  mdp->mcas = NULL;
608  mdp->mcanum = 0;
609  mdp->minsts = NULL;
610  mdp->miarr = NULL;
611  mdp->mnets = NULL;
612  mdp->mnnum = 0;
613  mdp->mtotvarnum = 0;
614  mdp->mprms = NULL;
615  mdp->mlocprms = NULL;
616  mdp->mprmnum = 0;
617  mdp->mlocprmnum = 0;
618  mdp->moditps = NULL;
619  mdp->mnxt = NULL;
620 
621  mdp->mattrs = NULL;
622  mdp->mvarinits = NULL;
623  mdp->mgateout_cbs = NULL;
624 
625  mdp->ialst = NULL;
626  mdp->mtasks = NULL;
627 
628  mdp->mexprtab = NULL;
629  mdp->mexprnum = 0;
630 
631  mdp->msttab = NULL;
632  mdp->mstnum = 0;
633 
634  mdp->mgrtab = NULL;
635  mdp->mgrnum = 0;
636 
637  mdp->mspfy = NULL;
638  mdp->mndvcodtab = NULL;
639  /* LOOKATME - could convert to compile time only struct */
640  mdp->mversno = 0;
641  mdp->lastinum = 0;
642  mdp->mlpcnt = -1;
643  mdp->mlevnxt = NULL;
644  mdp->mspltmst = NULL;
645  mdp->mpndspltmst = NULL;
646  mdp->mcells = NULL;
647  mdp->smpins = NULL;
648  mdp->iploctab = NULL;
649  mdp->mdfps = NULL;
650 }
651 
652 /*
653  * NET LIST FIX UP ROUTINES CALLED DURING INPUT PROCESSING
654  */
655 
656 /*
657  * declare all undeclared wires connected to module insts and gates
658  */
decl_instconns(struct mod_t * mdp)659 static void decl_instconns(struct mod_t *mdp)
660 {
661  register struct cell_t *cp;
662  register struct cell_pin_t *cpp;
663 
664  /* at this point all mod. insts., and gates on cell list */
665  /* SJM 03/25/99 - all gate ports including control must be declared imp. */
666  for (cp = mdp->mcells; cp != NULL; cp = cp->cnxt)
667   {
668    if (cp->cmsym == NULL) continue;
669 
670    for (cpp = cp->cpins; cpp != NULL; cpp = cpp->cpnxt)
671     {
672      /* this should always be at least 'bx by here */
673      /* change to special unc. indicator and check/fix here */
674      /* cell port connections lost */
675      if (cpp->cpxnd == NULL) __misc_terr(__FILE__, __LINE__);
676 
677      dcl_iconn_wires(cp, cpp->cpxnd);
678     }
679   }
680 }
681 
682 /*
683  * declare all undeclared wires mentioned in inst. conns implicitly
684  * anything in inst. port expr. implictly declared if not declared
685  * even index of bit select and everything in concatenate
686  */
dcl_iconn_wires(struct cell_t * cp,struct expr_t * ndp)687 static void dcl_iconn_wires(struct cell_t *cp, struct expr_t *ndp)
688 {
689  switch ((byte) ndp->optyp) {
690   case NUMBER: case REALNUM: case OPEMPTY: break;
691   /* global are not declared in this module */
692   case GLBREF: break;
693   case ID:
694    {
695     struct net_t *np;
696     struct sy_t *syp;
697 
698     syp = ndp->lu.sy;
699     if (syp->sydecl || syp->sytyp != SYM_N) break;
700 
701     np = syp->el.enp;
702     /* must not implicitly declare I/O port */
703     if (np->iotyp != NON_IO) break;
704     syp->sydecl = TRUE;
705     syp->sy_impldecl = TRUE;
706     syp->syfnam_ind = cp->csym->syfnam_ind;
707     syp->sylin_cnt = cp->csym->sylin_cnt;
708     np->iotyp = NON_IO;
709     /* type for undeclared is default net types */
710     np->ntyp = __dflt_ntyp;
711     np->nu.ct->n_iotypknown = TRUE;
712     np->nu.ct->n_rngknown = FALSE;
713     np->nu.ct->n_impldecl = TRUE;
714     np->nu.ct->n_wirtypknown = TRUE;
715     __gfinform(419, syp->syfnam_ind, syp->sylin_cnt,
716      "%s %s implicitly declared here from use in instance or gate connection",
717       __to_wtnam(__xs, np), np->nsym->synam);
718    }
719    break;
720   default:
721    /* know will not get here unless operator */
722    if (ndp->lu.x != NULL) dcl_iconn_wires(cp, ndp->lu.x);
723    if (ndp->ru.x != NULL) dcl_iconn_wires(cp, ndp->ru.x);
724    break;
725  }
726 }
727 
728 /*
729  * freeze module symbols and all enclosed symbol tables
730  * treee form of tables free during fixup by freeing the tn blocks
731  * notice sp_sytp can be nil but not sytp
732  */
freeze_mod_syms(struct symtab_t * sytp,struct symtab_t * sp_sytp)733 static void freeze_mod_syms(struct symtab_t *sytp,
734  struct symtab_t *sp_sytp)
735 {
736  /* since only system tasks and interpretive level symbols in level 0 */
737  /* do not look for global there */
738  sytp->sytpar = NULL;
739 
740  if (sytp->numsyms == 0) sytp->stsyms = NULL;
741  else __freeze_1symtab(sytp);
742 
743  /* if needed also freeze specify specparam symbol table */
744  if (sp_sytp != NULL)
745   {
746    /* symbol table empty if spec params all numbers - works since */
747    /* back annotation is to slot not spec param */
748    if (sp_sytp->numsyms == 0) sp_sytp->stsyms = NULL;
749    else __freeze_1symtab(sp_sytp);
750   }
751  /* notice no top level symbol but contained symbols possible */
752  if (sytp->sytofs != NULL) travfreeze_lowsymtab(sytp->sytofs);
753 }
754 
755 /*
756  * freeze one non empty symbol table
757  */
__freeze_1symtab(struct symtab_t * sytp)758 extern void __freeze_1symtab(struct symtab_t *sytp)
759 {
760  int32 bytes;
761 
762  /* DBG remove */
763  if (!sytp->freezes) __misc_terr(__FILE__, __LINE__);
764  /* --- */
765 
766  bytes = sytp->numsyms*sizeof(struct sy_t *);
767  __wrkstab = (struct sy_t **) __my_malloc(bytes);
768  __last_sy = -1;
769  travfreeze_syms(sytp->n_head);
770  sytp->stsyms = __wrkstab;
771  sytp->n_head = NULL;
772  /* non mod symbol table size wrong */
773  if (__last_sy + 1 != sytp->numsyms) __misc_terr(__FILE__, __LINE__);
774 }
775 
776 /*
777  * traversal in sorted preorder
778  */
travfreeze_syms(register struct tnode_t * tnp)779 static void travfreeze_syms(register struct tnode_t *tnp)
780 {
781  if (tnp->lp != NULL) travfreeze_syms(tnp->lp);
782  __wrkstab[++__last_sy] = tnp->ndp;
783  if (tnp->rp != NULL) travfreeze_syms(tnp->rp);
784 }
785 
786 /*
787  * depth first symbol table tree traversal across offspring
788  */
travfreeze_lowsymtab(register struct symtab_t * sytp)789 static void travfreeze_lowsymtab(register struct symtab_t *sytp)
790 {
791  for (; sytp != NULL; sytp = sytp->sytsib)
792   {
793    if (sytp->numsyms == 0) sytp->stsyms = NULL;
794    else __freeze_1symtab(sytp);
795    if (sytp->sytofs != NULL) travfreeze_lowsymtab(sytp->sytofs);
796   }
797 }
798 
799 /*
800  * convert list of module ports to array of ptrs to module ports
801  * need so port can be accessed from its index
802  * port order is list order that came from header list of ports
803  */
bld_mdpin_table(struct mod_t * mdp)804 static void bld_mdpin_table(struct mod_t *mdp)
805 {
806  register int32 pi;
807  register struct mod_pin_t *mpp;
808  int32 pnum;
809  struct mod_pin_t *mphdr, *mpp2;
810 
811  if ((pnum = mdp->mpnum) == 0) return;
812  mphdr = (struct mod_pin_t *) __my_malloc(pnum*sizeof(struct mod_pin_t));
813  for (pi = 0, mpp = mdp->mpins; mpp != NULL; mpp = mpp->mpnxt, pi++)
814   {
815    mphdr[pi] = *mpp;
816    mphdr[pi].mpnxt = NULL;
817   }
818  /* now free all old ports - contents copied - and need to keep expr */
819  for (mpp = mdp->mpins; mpp != NULL;)
820   {
821    mpp2 = mpp->mpnxt;
822    __my_free((char *) mpp, sizeof(struct mod_pin_t));
823    mpp = mpp2;
824   }
825  mdp->mpins = mphdr;
826 }
827 
828 /*
829  * check for and emit a redefinition error
830  */
__chk_redef_err(char * nam,struct sy_t * syp,char * newtnam,word32 styp)831 extern int32 __chk_redef_err(char *nam, struct sy_t *syp,
832  char *newtnam, word32 styp)
833 {
834  if (!syp->sydecl)
835   {
836    /* when see mod or udp, assume mod - may turn out to be udp and no err */
837    if (syp->sytyp == SYM_M && styp == SYM_UDP) return(TRUE);
838   }
839 
840  if (syp->sytyp != styp)
841   {
842    __pv_ferr(977, "cannot redefine %s as a %s - previous type was %s at %s",
843     nam, newtnam, __to_sytyp(__xs, syp->sytyp), __bld_lineloc(__xs2,
844     syp->syfnam_ind, syp->sylin_cnt));
845    return(FALSE);
846   }
847  if (syp->sydecl)
848   {
849    __pv_ferr(978, "cannot redefine %s %s - previous definition %s",
850     newtnam, nam, __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
851    return(FALSE);
852   }
853  return(TRUE);
854 }
855 
856 /*
857  * process an the module header iolist
858  * must read leading ( or (empty ;) and reads trailing ;
859  *
860  * if return T, even if error parsing can continue in module
861  * sometimes guesses that continuing ok, error caught by next routine
862  */
rd_modhdr(struct mod_t * mp)863 static int32 rd_modhdr(struct mod_t *mp)
864 {
865  struct mod_pin_t *mpp, *last_mpp;
866 
867  /* empty I/O list legal */
868  __get_vtok();
869 
870  /* P1364 2001 allows #(list of normal parameter decls) here that allows */
871  /* param decls in addition to body param decls */
872  if (__toktyp == SHARP)
873   {
874    /* if error and sync failed, know synced to module level item */
875    if (!rd_hdrpnd_parmdecls()) goto ret_end;
876   }
877 
878  if (__toktyp == SEMI) return(TRUE);
879  /* norma end reads ending rpar but on error mayhave synced to lpar */
880  if (__toktyp != LPAR) __get_vtok();
881 
882  if (__toktyp != LPAR)
883   {
884    __pv_ferr(979,
885     "module header list of ports initial left parenthesis expected - %s read",
886     __prt_vtok());
887    if (__vskipto2_any(RPAR, SEMI))
888     {
889      if (__toktyp == RPAR) __get_vtok();
890      /* if not semi, assume semi left out - if bad, next rout. will catch */
891      if (__toktyp != SEMI) __unget_vtok();
892      return(TRUE);
893     }
894 ret_end:
895    switch ((byte) __syncto_class) {
896     case SYNC_FLEVEL: return(FALSE);
897     case SYNC_MODLEVEL: return(TRUE);
898     /* should never sync to statement up here */
899     case SYNC_STMT:
900      __vskipto_modend(ENDMODULE);
901      return(FALSE);
902     default: __case_terr(__FILE__, __LINE__);
903    }
904   }
905  __get_vtok();
906  if (__toktyp == RPAR)
907   {
908 do_end:
909    __get_vtok();
910 do_end2:
911    if (__toktyp == SEMI) return(TRUE);
912 
913    __pv_ferr(980,
914     "module header list of ports end semicolon expected - %s read",
915     __prt_vtok());
916    __unget_vtok();
917    return(TRUE);
918   }
919 
920  /* SJM 05/23/04 - branch point for separate list of port decl header form */
921  if (__toktyp == INPUT || __toktyp == OUTPUT || __toktyp == INOUT)
922   {
923    /* reads ending ; after ) - also sets flags that prevents further */
924    /* port decls that would be legal for port name (explicit too) forms */
925    if (!rd_list_of_ports_decl(mp)) goto ret_end;
926    if (__toktyp == RPAR) __get_vtok();
927    goto do_end2;
928   }
929 
930  for (last_mpp = NULL;;)
931   {
932    /* this declares the symbols in the header */
933 
934    /* SJM 08/30/00 - need to ignore ,, and not count as a port in hdr def. */
935    if (__toktyp == COMMA)
936     {
937      __pv_fwarn(3103,
938       "empty ,, in module header port definition list ignored - not used in ordered instance connection list");
939      goto nxt_port;
940     }
941    if (__toktyp == RPAR)
942     {
943      __pv_fwarn(3103,
944       "empty ,) in module header port definition list ignored");
945      goto do_end;
946     }
947 
948    if (!rd_portref())
949     {
950      /* on error ignore this port and move on to next */
951 do_resync:
952      if (__vskipto3_any(COMMA, SEMI, RPAR))
953       {
954        /* port effectively not seen - error emitted already */
955        if (__toktyp == COMMA) goto nxt_port;
956        if (__toktyp == RPAR) goto do_end;
957        break;
958       }
959      goto ret_end;
960     }
961 
962    /* assume unvectored 1 bit port */
963    mpp = __alloc_modpin();
964    /* think possiblity unnamed ports can appear here */
965    if (strcmp(__portnam, "") == 0) mpp->mpsnam = NULL;
966    else mpp->mpsnam = __pv_stralloc(__portnam);
967    mpp->mp_explicit = (__mpref_explicit) ? TRUE : FALSE;
968 
969    if (last_mpp == NULL) mp->mpins = mpp; else last_mpp->mpnxt = mpp;
970    last_mpp = mpp;
971    mpp->mpref = __root_ndp;
972    /* count number of ports */
973    (mp->mpnum)++;
974    if (mp->mpnum >= MAXNUMPORTS)
975     {
976      __pv_ferr(314, "INTERNAL FATAL - module has more than %d ports - contact Pragmatic C",
977       MAXNUMPORTS);
978      (mp->mpnum)--;
979     }
980 
981    if (__toktyp == RPAR) goto do_end;
982    if (__toktyp != COMMA)
983     {
984      __pv_ferr(984,
985       "module header comma expected - %s read", __prt_vtok());
986      goto do_resync;
987     }
988 nxt_port:
989    __get_vtok();
990   }
991  return(TRUE);
992 }
993 
994 /*
995  * read the module define #(param decl list) parameter delcarations
996  * know the leading # read and reads one past ending ')' (probably '(')
997  *
998  * format is: module xx #([parameter decl list], ...) (port list) ...
999  * notice that only legal for module definitions
1000  */
rd_hdrpnd_parmdecls(void)1001 static int32 rd_hdrpnd_parmdecls(void)
1002 {
1003  __get_vtok();
1004  if (__toktyp != LPAR)
1005   {
1006    __pv_ferr(984,
1007     "module header #([parameter decl], ..) form starting left paren expected - %s read",
1008     __prt_vtok());
1009    if (!__vskipto3_any(RPAR, LPAR, SEMI)) return(FALSE);
1010    return(TRUE);
1011   }
1012  __get_vtok();
1013  for (;;)
1014   {
1015    if (__toktyp == RPAR) return(TRUE);
1016    if (__toktyp != PARAMETER)
1017     {
1018      if (!__vskipto4_any(PARAMETER, COMMA, RPAR, SEMI)) return(FALSE);
1019      if (__toktyp == PARAMETER) continue;
1020      if (__toktyp == COMMA) { __get_vtok(); continue; }
1021      if (__toktyp == RPAR || __toktyp == SEMI) return(TRUE);
1022     }
1023 
1024    /* AIV 09/27/06 - can never be a local param here */
1025    if (!rd_paramdecl(TRUE, FALSE)) return(FALSE);
1026   }
1027 }
1028 
1029 /*
1030  * read module header port .[port name]([port expr.]) or [port expr.] form
1031  * know 1st token name read and reads one past end , or ) if no error
1032  * if no error, expression in root_ndp
1033  *
1034  * medium level - caller syncs if returns error F
1035  */
rd_portref(void)1036 static int32 rd_portref(void)
1037 {
1038  int32 nd_rpar;
1039 
1040  if (__toktyp == DOT)
1041   {
1042    __mpref_explicit = TRUE;
1043    __get_vtok();
1044    if (__toktyp != ID)
1045     {
1046      __pv_ferr(985, "module definition header name of port expected - %s read",
1047       __prt_kywrd_vtok());
1048      return(FALSE);
1049     }
1050    strcpy(__portnam, __token);
1051    __get_vtok();
1052    if (__toktyp != LPAR)
1053     {
1054      __pv_ferr(986,
1055      "module definition header .[port]([port expr.]) form left parenthesis expected - %s read",
1056       __prt_vtok());
1057      return(FALSE);
1058     }
1059    nd_rpar = TRUE;
1060    /* read collect the expression that must end with ) only */
1061    __get_vtok();
1062    /* this cannot be empty */
1063    if (__toktyp == RPAR)
1064     {
1065      __finform(3004,
1066       "empty module definition header explicit form () port expression no effect");
1067      __last_xtk = 0;
1068      __set_opempty(0);
1069     }
1070    else
1071     {
1072      if (!__col_parenexpr(-1)) return(FALSE);
1073     }
1074   }
1075  else
1076   {
1077    __mpref_explicit = FALSE;
1078    nd_rpar = FALSE;
1079    strcpy(__portnam, "");
1080    /* read/collect expression that must end with ) or , */
1081    /* know 1st token of expression read */
1082    if (!__col_connexpr(-1)) return(FALSE);
1083   }
1084  /* build the tree, copy/allocate nodes, sets root_ndp to its root */
1085  __bld_xtree(0);
1086  /* must set all net like things as IO ports */
1087  set_ioprtnets(__root_ndp);
1088 
1089  if (!nd_rpar)
1090   {
1091    struct expr_t *idx;
1092 
1093    /* for unnamed port is simple id, that is port name */
1094    if (__root_ndp->optyp == ID) idx = __root_ndp;
1095    else if (__root_ndp->optyp == LSB || __root_ndp->optyp == PARTSEL)
1096     idx = __root_ndp->lu.x;
1097    else idx = NULL;
1098    if (idx != NULL) strcpy(__portnam, idx->lu.sy->synam);
1099   }
1100  else
1101   {
1102    if (__toktyp != RPAR)
1103     {
1104      __pv_ferr(988,
1105      "module definition header named port form right parenthesis expected - %s read",
1106       __prt_vtok());
1107      return(FALSE);
1108     }
1109    __get_vtok();
1110   }
1111  return(TRUE);
1112 }
1113 
1114 /*
1115  * mark all nets in I/O port expression as I/O of unknown direction
1116  * can be arbitrary expressions here because not yet checked
1117  */
set_ioprtnets(struct expr_t * ndp)1118 static void set_ioprtnets(struct expr_t *ndp)
1119 {
1120  struct sy_t *syp;
1121 
1122  if (__isleaf(ndp))
1123   {
1124    if (ndp->optyp == ID)
1125     {
1126      syp = ndp->lu.sy;
1127      /* module header wire %s declaration inconsistent */
1128      /* DBG remove -- */
1129      if (syp->sytyp != SYM_N)
1130       {
1131        __pv_ferr(684,
1132         "I/O port definition %s name %s type %s illegal - must be a net",
1133         __msgexpr_tostr(__xs, ndp), syp->synam, __to_sytyp(__xs2, syp->sytyp));
1134        syp->sytyp = SYM_N;
1135       }
1136      /* --- */
1137      syp->el.enp->iotyp = IO_UNKN;
1138     }
1139    return;
1140   }
1141  if (ndp->lu.x != NULL) set_ioprtnets(ndp->lu.x);
1142  if (ndp->ru.x != NULL) set_ioprtnets(ndp->ru.x);
1143 }
1144 
1145 /*
1146  * allocate a module pin (port) element
1147  */
__alloc_modpin(void)1148 extern struct mod_pin_t *__alloc_modpin(void)
1149 {
1150  struct mod_pin_t *mpp;
1151 
1152  mpp = (struct mod_pin_t *) __my_malloc(sizeof(struct mod_pin_t));
1153  mpp->mpsnam = NULL;
1154  mpp->mptyp = IO_UNKN;
1155  /* gets set and used only for bidirects */
1156  mpp->mp_explicit = FALSE;
1157  mpp->mp_jmpered = FALSE;
1158  mpp->inout_unc = FALSE;
1159  mpp->assgnfunc_set = FALSE;
1160  mpp->has_mipd = FALSE;
1161  mpp->has_scalar_mpps = FALSE;
1162 
1163  /* assume 1 for prim */
1164  mpp->mpwide = 1;
1165  /* expression for .[name]({...}) form but usually same internal net */
1166  mpp->mpref = NULL;
1167  mpp->mpattrs = NULL;
1168  mpp->mpfnam_ind = __cur_fnam_ind;
1169  mpp->mplin_cnt = __lin_cnt;
1170  mpp->mpaf.mpp_upassgnfunc = NULL;
1171  mpp->pbmpps = NULL;
1172  mpp->mpnxt = NULL;
1173  return(mpp);
1174 }
1175 
1176 /*
1177  * ROUTINES TO READ AND ADD LIST OF PORTS STYLE HEADER PORT DECLATIONS
1178  */
1179 
1180 /*
1181  * read list of header port declarations
1182  * new alternative ANSII style port header decl form added to 2001 LRM
1183  *
1184  * first port type keyword read and reads ending );
1185  *
1186  * if return T, even if error parsing can continue in module
1187  * on error must sync to semi and back up one - mod item which just returns
1188  */
rd_list_of_ports_decl(struct mod_t * mp)1189 static int32 rd_list_of_ports_decl(struct mod_t *mp)
1190 {
1191  int32 first_time, wtyp, ptyp, attr_ttyp, has_attr, decl_signed;
1192  struct sy_t *syp;
1193  struct net_t *np;
1194  struct expr_t *x1, *x2, *ox1, *ox2;
1195  struct mod_pin_t *mpp, *last_mpp;
1196  char s1[RECLEN];
1197 
1198  ptyp = -1;
1199  /* even if syntax error, T once a port type keyword appears in hdr */
1200  mp->mod_lofp_decl = TRUE;
1201  __lofp_port_decls = TRUE;
1202 
1203  last_mpp = NULL;
1204  for (;;)
1205   {
1206    /* attribute collected by scanner - but need to save so associates with */
1207    /* right port */
1208    if (__attr_prefix)
1209     {
1210      __wrk_attr.attr_tok = __toktyp;
1211      __wrk_attr.attr_seen = TRUE;
1212      /* for now this is unparsed entire attr. string */
1213      __wrk_attr.attrnam = __pv_stralloc(__attrwrkstr);
1214      __wrk_attr.attr_fnind = __attr_fnam_ind;
1215      __wrk_attr.attrlin_cnt = __attr_lin_cnt;
1216     }
1217    else __wrk_attr.attr_seen = FALSE;
1218 
1219    attr_ttyp = __toktyp;
1220    if (__toktyp == INPUT) ptyp = IO_IN;
1221    else if (__toktyp == OUTPUT) ptyp = IO_OUT;
1222    else if (__toktyp == INOUT) ptyp = IO_BID;
1223    else __case_terr(__FILE__, __LINE__);
1224 
1225    __get_vtok();
1226 
1227    /* defaults to wire if net type omitted - can be var/reg type */
1228    if ((wtyp = __fr_wtnam(__toktyp)) != -1) __get_vtok();
1229    else wtyp = N_WIRE;
1230 
1231    if (wtyp == N_INT || wtyp == N_REAL) decl_signed = TRUE;
1232    else decl_signed = FALSE;
1233 
1234    /* vectored or scalared keywords never appear in port decls */
1235    if (__toktyp == SIGNED)
1236     {
1237      decl_signed = TRUE;
1238      if (wtyp == N_TIME || wtyp == N_INT || wtyp == N_REAL || wtyp == N_EVENT)
1239       {
1240        __pv_ferr(3423,
1241         "signed keyword illegal when task or function variable type %s",
1242         __to_wtnam2(s1, wtyp));
1243       }
1244      __get_vtok();
1245     }
1246 
1247    /* even if error if 1 past ending ] continue */
1248    if (!__rd_decl_rng(&ox1, &ox2))
1249     {
1250      /* bad decl - but if sync to new I/O port direction, caller will cont */
1251      if (!__vskipto_lofp_end()) return(FALSE);
1252      if (__toktyp == RPAR) { __get_vtok(); return(TRUE); }
1253      /* semi read */
1254      return(TRUE);
1255     }
1256 
1257    /* use local has attr flag so can turn glb seen off before return */
1258    if (__wrk_attr.attr_seen)
1259     { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
1260    else has_attr = FALSE;
1261 
1262    x1 = x2 = NULL;
1263    for (first_time = TRUE;;)
1264     {
1265      if (__toktyp != ID)
1266       {
1267        __pv_ferr(992, "list of port form %s port name expected - %s read",
1268         __to_ptnam(s1, ptyp), __prt_kywrd_vtok());
1269 
1270        if (__vskipto2_lofp_end())
1271         {
1272          if (__toktyp == SEMI) return(TRUE);
1273          if (__toktyp == RPAR) { __get_vtok(); return(TRUE); }
1274          /* only other possibility is the port name separating comma */
1275          continue;
1276         }
1277        /* can't recover (resync) from error - synced to module item */
1278        return(FALSE);
1279       }
1280 
1281      if ((syp = __get_sym_env(__token)) != NULL)
1282       {
1283        __pv_ferr(3418, "list of port form %s port name %s redeclared",
1284         __to_ptnam(s1, ptyp), __token);
1285        goto nxt_port;
1286       }
1287 
1288      if (first_time) { x1 = ox1; x2 = ox2; first_time = FALSE; }
1289      else
1290       {
1291        if (x1 == NULL) x1 = x2 = NULL;
1292        else { x1 = __copy_expr(ox1); x2 = __copy_expr(ox2); }
1293       }
1294 
1295      /* first declare the port's wire/reg */
1296      if ((np = __decl_wirereg(wtyp, x1, x2, NULL)) == NULL) goto nxt_port;
1297 
1298      /* if previously used will be treated as reg - must set to compatible */
1299      /* wire type if declared as time or int32 */
1300      np->ntyp = wtyp;
1301      syp = np->nsym;
1302 
1303      /* if saw an (* *) attribute for module item token, seen on */
1304      if (has_attr)
1305       {
1306        /* this add to net's attr list on end if also net decl first */
1307        add_net_attr(np, attr_ttyp);
1308       }
1309 
1310      /* SJM 10/02/03 - signed can be turned on either in port or wire decl */
1311      if (decl_signed) np->n_signed = TRUE;
1312 
1313      np->iotyp = ptyp;
1314      /* for list of ports mod header decl form, all info in hdr decl */
1315      np->nu.ct->n_iotypknown = TRUE;
1316 
1317      syp->sydecl = TRUE;
1318      /* need I/O decl. place not header or wire decl. */
1319      syp->syfnam_ind = __cur_fnam_ind;
1320      syp->sylin_cnt = __lin_cnt;
1321 
1322      /* then add the port to the port list - know port and net name same */
1323      mpp = __alloc_modpin();
1324      mpp->mpsnam = __pv_stralloc(np->nsym->synam);
1325      mpp->mp_explicit = FALSE;
1326 
1327      if (last_mpp == NULL) mp->mpins = mpp; else last_mpp->mpnxt = mpp;
1328      last_mpp = mpp;
1329 
1330      /* name of port still in token - expr here always ID */
1331      __last_xtk = -1;
1332      if (!__bld_expnode()) __set_xtab_errval();
1333      __bld_xtree(0);
1334      mpp->mpref = __root_ndp;
1335 
1336      /* count number of ports */
1337      (mp->mpnum)++;
1338      if (mp->mpnum >= MAXNUMPORTS)
1339       {
1340        __pv_ferr(314,
1341         "INTERNAL FATAL - module has more than %d ports - contact Pragmatic C",
1342         MAXNUMPORTS);
1343        (mp->mpnum)--;
1344       }
1345 
1346 nxt_port:
1347      __get_vtok();
1348      if (__toktyp == RPAR) return(TRUE);
1349 
1350      if (__toktyp != COMMA)
1351       {
1352        __pv_ferr(995,
1353         "list of ports form declaration list comma or right paren expected - %s read",
1354         __prt_vtok());
1355        /* try to resync */
1356        if (!__vskipto_lofp_end()) return(FALSE);
1357        if (__toktyp == COMMA) goto nxt_net;
1358        /* misplaced semi or sync to rpar */
1359        return(TRUE);
1360       }
1361 nxt_net:
1362      __get_vtok();
1363      if (__toktyp == INPUT || __toktyp == OUTPUT || __toktyp == INOUT)
1364       break;
1365     }
1366   }
1367  __misc_terr(__FILE__, __LINE__);
1368  return(TRUE);
1369 }
1370 
1371 /*
1372  * MODULE ITEM ROUTINES
1373  */
1374 
1375 /*
1376  * read module body and process the various module items
1377  * know __inst_mod points to current module structure
1378  * know module port list end ; read
1379  *
1380  * if returns T must be synced on end mod
1381  */
rd_modbody(void)1382 static int32 rd_modbody(void)
1383 {
1384  int32 rv, iattyp, ialcnt, iafnind, wtyp;
1385  struct st_t *stp;
1386  struct ialst_t *ialp;
1387  char typnam[IDLEN];
1388 
1389  for (;;)
1390   {
1391    /* routines called in switch expected to read ending ; or token */
1392    __get_vtok();
1393    /* SJM 03/20/00 - save attribute info for mod items */
1394    if (__attr_prefix)
1395     {
1396      __wrk_attr.attr_tok = __toktyp;
1397      __wrk_attr.attr_seen = TRUE;
1398      /* for now this is unparsed entire attr. string */
1399      __wrk_attr.attrnam = __pv_stralloc(__attrwrkstr);
1400      __wrk_attr.attr_fnind = __attr_fnam_ind;
1401      __wrk_attr.attrlin_cnt = __attr_lin_cnt;
1402     }
1403    else __wrk_attr.attr_seen = FALSE;
1404 
1405    switch((byte) __toktyp) {
1406     case TEOF:
1407      __pv_ferr(989, "endmodule missing");
1408      return(FALSE);
1409     case INPUT:
1410      if (!rd_iodecl(IO_IN))
1411       {
1412 moditem_resync:
1413        /* on error - reset attribute prefix state */
1414        __wrk_attr.attr_seen = FALSE;
1415        switch ((byte) __syncto_class) {
1416         case SYNC_FLEVEL: return(FALSE);
1417         case SYNC_MODLEVEL: break;
1418 	/* if sync. to statement assume initial left out */
1419         case SYNC_STMT:
1420          /* here must clear any pushed back */
1421          if (__lasttoktyp != UNDEF) __get_vtok();
1422 	 /*FALLTHRU */
1423         case SYNC_TARG:
1424 	 iattyp = INITial;
1425          iafnind= __cur_fnam_ind;
1426          ialcnt = __lin_cnt;
1427 	 goto moditem_stmt;
1428         default: __case_terr(__FILE__, __LINE__);
1429        }
1430       }
1431      continue;
1432     case OUTPUT:
1433      if (!rd_iodecl(IO_OUT)) goto moditem_resync;
1434      continue;
1435     case INOUT:
1436      if (!rd_iodecl(IO_BID)) goto moditem_resync;
1437      continue;
1438     case EVENT:
1439      if (!rd_eventdecl(FALSE)) goto moditem_resync;
1440      continue;
1441     case INITial:
1442     case ALWAYS:
1443      iafnind = __cur_fnam_ind;
1444      ialcnt = __lin_cnt;
1445      iattyp = __toktyp;
1446      __get_vtok();
1447      /* statement must synchronize */
1448 moditem_stmt:
1449      if ((stp = __rd_stmt()) != NULL)
1450       {
1451        ialp = (struct ialst_t *) __my_malloc(sizeof(struct ialst_t));
1452        ialp->iatyp = iattyp;
1453        ialp->iastp = stp;
1454        ialp->ia_first_ifi = iafnind;
1455        ialp->ia_first_lini = ialcnt;
1456        ialp->ia_last_ifi = __cur_fnam_ind;
1457        ialp->ia_last_lini = __lin_cnt;
1458        ialp->ialnxt = NULL;
1459 
1460        if (__end_ialst == NULL) __inst_mod->ialst = ialp;
1461        else __end_ialst->ialnxt = ialp;
1462        __end_ialst = ialp;
1463       }
1464      else goto moditem_resync;
1465      continue;
1466     case ASSIGN:
1467      if (!rd_contassign()) goto moditem_resync;
1468      continue;
1469     case PARAMETER:
1470      if (!rd_paramdecl(FALSE, FALSE)) goto moditem_resync;
1471      continue;
1472     case LOCALPARAM:
1473      if (!rd_paramdecl(FALSE, TRUE)) goto moditem_resync;
1474      continue;
1475     case DEFPARAM:
1476      if (!rd_dfparam_stmt()) goto moditem_resync;
1477      continue;
1478     case SPECIFY:
1479      if (!__rd_spfy(__inst_mod)) goto moditem_resync;
1480      continue;
1481     case TASK:
1482      __cur_declobj = TASK;
1483      rv = rd_task();
1484      __cur_declobj = MODULE;
1485      if (!rv) goto moditem_resync;
1486      continue;
1487     case FUNCTION:
1488      __cur_declobj = TASK;
1489      rv = rd_func();
1490      __cur_declobj = MODULE;
1491      if (!rv) goto moditem_resync;
1492      continue;
1493     case ENDMODULE:
1494      /* save end so can put in module's end souce range fields */
1495      __inst_mod->mod_last_lini = __lin_cnt;
1496      __inst_mod->mod_last_ifi = __cur_fnam_ind;
1497 
1498      /* catch common extra ; error here */
1499      __get_vtok();
1500      if (__toktyp == SEMI)
1501       __pv_ferr(999, "semicolon following endmodule illegal");
1502      else __unget_vtok();
1503      break;
1504     case ENDPRIMITIVE:
1505      /* but assume still in sync */
1506      __pv_ferr(990, "module definitition cannot end with endprimitive");
1507      break;
1508     case GENERATE:
1509      /* AIV 06/27/05 - catch generate */
1510      __pv_ferr(3549, "generate feature not implemented in this version");
1511      if (!__vskipto_modend(ENDGENERATE)) break;
1512      continue;
1513     default:
1514      if ((wtyp = __fr_wtnam(__toktyp)) != -1)
1515       {
1516        /* false here means out of sync - must skip rest of module */
1517        /* if T will have skipped to semi */
1518        if (!rd_vardecl((word32) wtyp)) goto moditem_resync;
1519        /* needed to add attribute to every net in list - can now reset */
1520        __wrk_attr.attr_seen = FALSE;
1521        continue;
1522       }
1523      /* must be instance (udp, gate, module instantiation) */
1524      if (__toktyp != ID)
1525       {
1526        __pv_ferr(991, "module type, gate or udp name expected - %s read",
1527         __prt_kywrd_vtok());
1528        /* can only sync to ; here - else need names to decl. */
1529        if (!__vskipto_any(SEMI)) goto moditem_resync;
1530        break;
1531       }
1532      strcpy(typnam, __token);
1533      if (!rd_inst(typnam)) goto moditem_resync;
1534      /* needed to add attr to every instance, now can reset attr seen */
1535      __wrk_attr.attr_seen = FALSE;
1536      continue;
1537    }
1538    break;
1539   }
1540  return(TRUE);
1541 }
1542 
1543 /*
1544  * MODULE DECLARATION ROUTINES
1545  */
1546 
1547 /*
1548  * process an I/O or wire declaration
1549  * mostly sets the iotyp field
1550  * I/O decl. does not declare symbol even though wire decl. not required
1551  */
rd_iodecl(word32 typ)1552 static int32 rd_iodecl(word32 typ)
1553 {
1554  int32 first_time, ttyp, has_attr, decl_signed, is_complete, wtyp;
1555  struct sy_t *syp;
1556  struct net_t *np;
1557  struct expr_t *x1, *x2, *ox1, *ox2;
1558  char s1[RECLEN];
1559 
1560  wtyp = -1;
1561  decl_signed = FALSE;
1562  is_complete = FALSE;
1563  /* vectored or scalared keywords only appear on wire decls */
1564  __get_vtok();
1565  if (__toktyp == SIGNED)
1566   {
1567    decl_signed = TRUE;
1568    __get_vtok();
1569   }
1570  /* AIV 07/20/04 port decl can now contain net type making it complete  */
1571  else if ((wtyp = __fr_wtnam(__toktyp)) != -1)
1572   {
1573     /* if complete set the flag set the type */
1574     is_complete = TRUE;
1575     __get_vtok();
1576     /* must check for sign again */
1577     if (__toktyp == SIGNED)
1578      {
1579       decl_signed = TRUE;
1580       __get_vtok();
1581      }
1582    }
1583   /* type defaults to reg if undefined */
1584   else wtyp = N_REG;
1585 
1586  /* even if error if 1 past ending ] continue */
1587  if (!__rd_decl_rng(&ox1, &ox2))
1588   {
1589    /* ignore decl but continue with mod. item */
1590    if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
1591    if (__toktyp == SEMI) return(TRUE);
1592    __get_vtok();
1593   }
1594  /* use local has attr flag so can turn glb seen of before return */
1595  if (__wrk_attr.attr_seen) { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
1596  else has_attr = FALSE;
1597  x1 = x2 = NULL;
1598  for (first_time = TRUE;;)
1599   {
1600    if (__toktyp != ID)
1601     {
1602      __pv_ferr(992, "%s port name expected - %s read", __to_ptnam(s1, typ),
1603       __prt_kywrd_vtok());
1604      /* need token and symbol and cannot parse */
1605      return(__vskipto_any(SEMI));
1606     }
1607 
1608    /* any port decl illegal if hdr list of port form used */
1609    if (__lofp_port_decls)
1610     {
1611      __pv_ferr(3421,
1612       "%s declaration of \"%s\" illegal - module uses list of ports declaration form",
1613      __to_ptnam(s1, typ), __prt_kywrd_vtok());
1614      goto nxt_port;
1615     }
1616 
1617    /* 3 ways to not be in I/O port header list */
1618    /* know only one symbol level here */
1619    /* also know must be defined since added when header read */
1620    if ((syp = __get_sym_env(__token)) == NULL)
1621     {
1622 not_a_port:
1623      __pv_ferr(993,
1624      "%s declaration of \"%s\" illegal - not in module header list of ports",
1625       __to_ptnam(s1, typ), __token);
1626      goto nxt_port;
1627     }
1628    if (syp->sytyp != SYM_N) goto not_a_port;
1629    np = syp->el.enp;
1630 
1631    /* SJM 10/02/03 - signed can be turned on either in port or wire decl */
1632    if (decl_signed) np->n_signed = TRUE;
1633 
1634    /* when module header list of ports read, port set to IO_UNKN */
1635    if (np->iotyp == NON_IO) goto not_a_port;
1636 
1637    /* header port changed when I/O port decl. seen */
1638    if (np->nu.ct->n_iotypknown)
1639     {
1640      __pv_ferr(994, "I/O port %s previously declared as %s", __token,
1641       __to_ptnam(s1, np->iotyp));
1642     }
1643    else
1644     {
1645      np->iotyp = typ;
1646      np->nu.ct->n_iotypknown = TRUE;
1647     }
1648 
1649    /* if saw an (* *) attribute for module item token, seen on */
1650    if (has_attr)
1651     {
1652      if (typ == IO_IN) ttyp = INPUT; else if (typ == IO_OUT) ttyp = OUTPUT;
1653      else ttyp = INOUT;
1654 
1655      /* this add to net's attr list on end if also net decl first */
1656      add_net_attr(np, ttyp);
1657     }
1658 
1659    if (first_time) { x1 = ox1; x2 = ox2; first_time = FALSE; }
1660    else
1661     {
1662      if (x1 == NULL) x1 = x2 = NULL;
1663      else { x1 = __copy_expr(ox1); x2 = __copy_expr(ox2); }
1664     }
1665    if (!chkset_wdrng(np, x1, x2)) goto nxt_port;
1666 
1667    /* 2 cases, if so far only appeared in port header wirtypknown F */
1668    /* and need to set as wire not reg (default for ports), else already set */
1669    /* but notice if set, type still not known just implicitly wire */
1670    if (is_complete)
1671     {
1672      np->ntyp = wtyp;
1673      /* must make as  */
1674      np->nu.ct->n_iscompleted = TRUE;
1675     }
1676    else if (!np->nu.ct->n_wirtypknown) np->ntyp = N_WIRE;
1677 
1678    syp->sydecl = TRUE;
1679    /* need I/O decl. place not header or wire decl. */
1680    syp->syfnam_ind = __cur_fnam_ind;
1681    syp->sylin_cnt = __lin_cnt;
1682 
1683 nxt_port:
1684    __get_vtok();
1685    if (__toktyp == SEMI) break;
1686    if (__toktyp != COMMA)
1687     {
1688      __pv_ferr(995,
1689       "I/O port declaration list comma or semicolon expected - %s read",
1690       __prt_vtok());
1691      /* try to resync */
1692      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
1693      if (__toktyp == COMMA) goto nxt_var;
1694      break;
1695     }
1696 nxt_var:
1697    __get_vtok();
1698   }
1699  return(TRUE);
1700 }
1701 
1702 /*
1703  * read a decl range (either reg, wire, array, or gate/inst)
1704  * know possible for range present [ read and reads one past end ]
1705  * this fills exprs that are evaluated later
1706  *
1707  * on error caller handles skipping
1708  * x1 and x2 only point to non nil if succeeds
1709  */
__rd_decl_rng(struct expr_t ** x1,struct expr_t ** x2)1710 extern int32 __rd_decl_rng(struct expr_t **x1, struct expr_t **x2)
1711 {
1712  *x1 = *x2 = NULL;
1713 
1714  if (__toktyp == LSB)
1715   {
1716    if (!__col_rangeexpr())
1717     {
1718      /* error, but structure right */
1719      if (__toktyp == RSB) { __get_vtok(); return(TRUE); }
1720      return(FALSE);
1721     }
1722    __bld_xtree(0);
1723    __get_vtok();
1724    /* this really is number range */
1725    if (__root_ndp->optyp != PARTSEL)
1726     __pv_ferr(998, "illegal declaration range expression");
1727    else { *x1 = __root_ndp->ru.x->lu.x; *x2 = __root_ndp->ru.x->ru.x; }
1728   }
1729  return(TRUE);
1730 }
1731 
1732 /*
1733  * add a net attribute
1734  * SJM - 03/20/00 - if I/O decl attrs really net attrs for port net
1735  */
add_net_attr(struct net_t * np,int32 ttyp)1736 static void add_net_attr(struct net_t *np, int32 ttyp)
1737 {
1738  register struct attr_t *attrp, *new_attrp, *last_attrp;
1739 
1740  /* need to set token type so each parsed attr_spec has right tok type */
1741  __wrk_attr.attr_tok = ttyp;
1742 
1743  /* return nil on error */
1744  if ((new_attrp = __rd_parse_attribute(&__wrk_attr)) != NULL)
1745   {
1746    if (np->nattrs == NULL) np->nattrs = new_attrp;
1747    else
1748     {
1749      /* linear search not problem because only 2 decls possible */
1750      last_attrp = NULL;
1751      /* move to tail of list */
1752      for (attrp = np->nattrs; attrp != NULL; attrp = attrp->attrnxt)
1753       { last_attrp = attrp; }
1754      /* SJM 08/02/01 - add if to keep lint happy */
1755      if (last_attrp != NULL) last_attrp->attrnxt = new_attrp;
1756     }
1757   }
1758  __my_free(__wrk_attr.attrnam, __attr_line_len + 1);
1759  __wrk_attr.attr_seen = FALSE;
1760 }
1761 
1762 /*
1763  * [wire type] [charge or drive stren] [range] [delay] [list of variables]
1764  * [charge strength] is ([cap. size])
1765  */
1766 
1767 /*
1768  * read and process a wire/reg/time/int/real variable declaration
1769  * know wire type read and reads final semi
1770  * semantic routines detect errors later
1771  * tricky because wires can also be continuous assignments
1772  * capacitor strength indicated by v_stren1 = NO_STREN
1773  *
1774  * if returns F synced to next module, else synced to SEMI
1775  */
rd_vardecl(word32 wtyp)1776 static int32 rd_vardecl(word32 wtyp)
1777 {
1778  int32 first_time, split_state, decl_signed, has_attr;
1779  struct expr_t *x1, *x2, *ox1, *ox2, *xm1, *xm2;
1780  struct sy_t *syp;
1781  struct net_t *np;
1782  struct paramlst_t *pmphdr;
1783  char s1[RECLEN];
1784 
1785  pmphdr = NULL;
1786  __v0stren = __v1stren = NO_STREN;
1787  if (wtyp == N_INT || wtyp == N_REAL) decl_signed = TRUE;
1788  else decl_signed = FALSE;
1789 
1790  __get_vtok();
1791  if (__toktyp == LPAR)
1792   {
1793    __get_vtok();
1794    /* normal use of strengths if for wire assign net decl form */
1795    if (!rd_verstrens())
1796     {
1797      if (!__vskipto2_any(RPAR, SEMI)) return(FALSE);
1798      if (__toktyp == RPAR) { __get_vtok(); goto rd_rng; }
1799      return(TRUE);
1800     }
1801    /* if error strength turned off */
1802    chk_capwdecl_strens(wtyp);
1803   }
1804 
1805 rd_rng:
1806  split_state = SPLT_DFLT;
1807  if (__toktyp == VECTORED) { __get_vtok(); split_state = SPLT_VECT; }
1808  else if (__toktyp == SCALARED) { split_state = SPLT_SCAL; __get_vtok(); }
1809 
1810  if (__toktyp == SIGNED)
1811   {
1812    decl_signed = TRUE;
1813    if (wtyp == N_TIME || wtyp == N_INT || wtyp == N_REAL || wtyp == N_EVENT)
1814     {
1815      __pv_ferr(3423,
1816       "signed keyword illegal when variable type %s", __to_wtnam2(s1, wtyp));
1817     }
1818    __get_vtok();
1819   }
1820  if (!__rd_decl_rng(&ox1, &ox2))
1821   {
1822    if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
1823    if (__toktyp == SEMI) return(TRUE);
1824    /* on success this reads one past ] */
1825    __get_vtok();
1826   }
1827  if (split_state != SPLT_DFLT)
1828   {
1829    char s2[RECLEN];
1830 
1831    /* SJM 07/19/02 - notice only one of these errors can be emitted */
1832    if (wtyp >= NONWIRE_ST)
1833     {
1834      __pv_ferr(997,
1835       "%s keyword illegal for type \"%s\"", __to_splt_nam(s1, split_state),
1836       __to_wtnam2(s2, wtyp));
1837      split_state = SPLT_DFLT;
1838      ox1 = ox2 = NULL;
1839     }
1840    else if (ox1 == NULL)
1841     {
1842      __pv_ferr(996, "%s keyword required following range missing",
1843       __to_splt_nam(s1, split_state));
1844      split_state = SPLT_DFLT;
1845     }
1846   }
1847  if (ox1 != NULL)
1848   {
1849    if (wtyp == N_INT || wtyp == N_TIME || wtyp == N_REAL || wtyp == N_EVENT)
1850     {
1851      __pv_ferr(1002, "%s %s vector range illegal", __to_wtnam2(s1, wtyp),
1852       __token);
1853      ox1 = ox2 = NULL;
1854     }
1855   }
1856  /* leave scalar with SPLT_DFLT state */
1857  /* returning F means must try to skip to semi */
1858  if (__toktyp == SHARP)
1859   {
1860    if (!rd_oparamdels(&pmphdr))
1861     {
1862 bad_end:
1863      return(__vskipto_any(SEMI));
1864     }
1865   }
1866 
1867  /* use local has attr flag so can turn glb seen of before return */
1868  if (__wrk_attr.attr_seen) { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
1869  else has_attr = FALSE;
1870  /* know ox1 and ox2 contain statement decl range */
1871  for (first_time = TRUE;;)
1872   {
1873    /* save line count since for conta form need lhs var location */
1874    if (__toktyp != ID)
1875     {
1876      __pv_ferr(1001, "wire or reg declaration wire name expected - %s read",
1877       __prt_kywrd_vtok());
1878      /* must move over this token in case it is vendor 1 keyword */
1879      __get_vtok();
1880      goto bad_end;
1881     }
1882 
1883   /* if hdr list of port form used, decls giving additional info illegal */
1884   if ((syp = __get_sym_env(__token)) != NULL && syp->sytyp == SYM_N
1885    && syp->el.enp->iotyp != NON_IO)
1886    {
1887     if (__lofp_port_decls || syp->el.enp->nu.ct->n_iscompleted)
1888      {
1889       if (__lofp_port_decls)
1890        {
1891         __pv_ferr(3421,
1892          "%s declaration of port \"%s\" illegal - module uses list of ports declarations form",
1893          __to_wtnam2(s1, wtyp), __prt_kywrd_vtok());
1894        }
1895       else
1896        {
1897         __pv_ferr(3424,
1898          "%s declaration of port \"%s\" illegal - net type is previously defined",
1899          __to_wtnam2(s1, wtyp), __prt_kywrd_vtok());
1900        }
1901 
1902       /* ignore rest of declaration - should resync if no syntax error */
1903       if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
1904       if (__toktyp == SEMI) return(TRUE);
1905       goto nxt_wire;
1906      }
1907    }
1908 
1909    /* set implied range for time and integer */
1910    /* each time through need to call this to make copy */
1911    if (ox1 == NULL) set_reg_widths(wtyp, &x1, &x2);
1912    else if (first_time) { x1 = ox1; x2 = ox2; }
1913    else { x1 = __copy_expr(ox1); x2 = __copy_expr(ox2); }
1914 
1915    /* must skip to ending ; here since cannot decl. any of list */
1916    /* and lack information to read rest of this decl. */
1917    if ((np = __decl_wirereg(wtyp, x1, x2, NULL)) == NULL)
1918     {
1919      /* resync at , or ; - should succeed */
1920 try_resync:
1921      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
1922      if (__toktyp == SEMI) return(TRUE);
1923      goto nxt_wire;
1924     }
1925    /* if previously used will be treated as reg - must set to compatible */
1926    /* wire type if declared as time or int32 */
1927    np->ntyp = wtyp;
1928    syp = np->nsym;
1929 
1930    /* SJM - 03/20/00 - save wire decl attrs */
1931    /* if saw an (* *) attribute for module item token, seen on */
1932    if (has_attr)
1933     {
1934      /* add to end if I/O decl seen first for ports - still on net not port */
1935      add_net_attr(np, WIRE);
1936     }
1937 
1938    /* different array range expr. for every array */
1939    __get_vtok();
1940    if (!__rd_decl_rng(&xm1, &xm2))
1941     {
1942      if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
1943      if (__toktyp == SEMI) return(TRUE);
1944      __get_vtok();
1945     }
1946    if (xm1 != NULL && (wtyp < NONWIRE_ST || wtyp == N_EVENT))
1947     {
1948      __pv_ferr(1003, "%s %s cannot be an array", __to_wtnam2(s1, wtyp),
1949       syp->synam);
1950      xm1 = xm2 = NULL;
1951     }
1952    if (pmphdr != NULL && wtyp >= NONWIRE_ST)
1953     {
1954      __pv_ferr(1004,
1955       "%s %s not a wire - cannot have delay(s)", __to_wtnam2(s1, wtyp),
1956       syp->synam);
1957      pmphdr = NULL;
1958     }
1959    if (xm1 != NULL)
1960     { np->n_isarr = TRUE; np->nu.ct->ax1 = xm1; np->nu.ct->ax2 = xm2; }
1961    np->nu.ct->n_spltstate = split_state;
1962 
1963    /* SJM 10/02/03 - now signed keyword or int real implies signed */
1964    /* must not turn off since if port and turned on there, stays on */
1965    if (decl_signed) np->n_signed = TRUE;
1966 
1967    /* AIV 09/29/04 - now if there is an = not necessarily a cont assgn */
1968    /* could be a variable initialization i.e. integer i = 12; */
1969    if (__toktyp == EQ)
1970     {
1971      if (np->ntyp >= NONWIRE_ST)
1972       {
1973        /* cannot init an array - illegal syntax */
1974        if (np->n_isarr)
1975         {
1976          __pv_ferr(3429,
1977           "variable assign initialize form illegal for %s - arrays cannot be initialized",
1978           syp->synam);
1979          goto try_resync;
1980         }
1981        if (!rdbld_mod_varinitlst(syp)) goto try_resync;
1982       }
1983      else if (!do_wdecl_assgn(syp, pmphdr, first_time)) goto try_resync;
1984     }
1985    else
1986     {
1987      /* copying delay list here since gets freed and converted later */
1988      if (first_time) np->nu.ct->n_dels_u.pdels = pmphdr;
1989      else np->nu.ct->n_dels_u.pdels = __copy_dellst(pmphdr);
1990      /* know strength good or will be turned off by here */
1991      if (__v0stren != NO_STREN)
1992       {
1993        if (wtyp == N_TRIREG)
1994         {
1995          /* know capacitor strength already checked */
1996          np->n_capsiz = __to_cap_size(__v0stren);
1997         }
1998        else chk_drvstren(wtyp);
1999       }
2000      /* set trireg default to medium (always needed) */
2001      else if (wtyp == N_TRIREG) np->n_capsiz = CAP_MED;
2002     }
2003 
2004 nxt_wire:
2005    if (first_time) first_time = FALSE;
2006    if (__toktyp == SEMI) break;
2007    if (__toktyp != COMMA)
2008     {
2009      __pv_ferr(1005,
2010       "wire declaration comma separator or semicolon expected - %s read",
2011       __prt_vtok());
2012      /* try to resync */
2013      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
2014      if (__toktyp == SEMI) break;
2015     }
2016    __get_vtok();
2017    first_time = FALSE;
2018   }
2019  return(TRUE);
2020 }
2021 
2022 /*
2023  * check cap. wire declaration strength - no strength appeared
2024  */
chk_capwdecl_strens(word32 wtyp)2025 static void chk_capwdecl_strens(word32 wtyp)
2026 {
2027  char s1[RECLEN], s2[RECLEN];
2028 
2029  if (!__is_capstren(__v0stren))
2030   {
2031    if (wtyp == N_TRIREG)
2032     {
2033      __pv_ferr(1006,
2034       "trireg wire declaration non capacitor size strength %s illegal",
2035       __to_stren_nam(s1, __v0stren, __v1stren));
2036      __v0stren = __v1stren = NO_STREN;
2037     }
2038    return;
2039   }
2040  /* know this is cap. strenght */
2041  if (wtyp != N_TRIREG)
2042   {
2043    __pv_ferr(1007,
2044    "non trireg wire type %s declaration has illegal capacitor size strength \"%s\"",
2045     __to_wtnam2(s1, wtyp), __to_stren_nam(s2, __v0stren, __v1stren));
2046    __v0stren = __v1stren = NO_STREN;
2047   }
2048 }
2049 
2050 /*
2051  * know non assign wire decl. has strength - emit error
2052  */
chk_drvstren(word32 wtyp)2053 static void chk_drvstren(word32 wtyp)
2054 {
2055  char s1[RECLEN], s2[RECLEN];
2056 
2057  /* SJM 04/17/03 - must not use stren to string routine if not set in src */
2058  if (__v0stren == 0 || __v1stren == 0)
2059   {
2060    __pv_ferr(1008,
2061     "%s declaration required tow driving strengths not present in non wire assign form",
2062     __to_wtnam2(s1, wtyp));
2063   }
2064  else
2065   {
2066    __pv_ferr(1008,
2067     "%s declaration driving strength \"%s\" illegal in non wire assign form",
2068      __to_wtnam2(s1, wtyp), __to_stren_nam(s2, __v0stren, __v1stren));
2069   }
2070  __v0stren = __v1stren = NO_STREN;
2071 }
2072 
2073 
2074 /*
2075  * get old style only implicit # type parameters i.e. delay expr. list
2076  *
2077  * know # read (if needs to be present) and reads one past end
2078  * builds a parameter/delay list and returns pointer to header
2079  * this routine for # form and path delay () list (no #) only
2080  * specparam and deparam rhs no # or ( ok
2081  * error if #()
2082  *
2083  * this routine returns F on sync error - caller must resync
2084  * but in places with known delimiter attempt to resync to delim
2085  */
rd_oparamdels(struct paramlst_t ** pmphdr)2086 static int32 rd_oparamdels(struct paramlst_t **pmphdr)
2087 {
2088  struct paramlst_t *pmp, *last_pmp;
2089 
2090  *pmphdr = NULL;
2091  /* this is #[number] or #id - not (..) form - min:typ:max requires () */
2092  /* for path delay will never see this form */
2093  __get_vtok();
2094  if (__toktyp != LPAR)
2095   {
2096    /* notice must surround m:t:m with () */
2097    if (__toktyp != ID && __toktyp != NUMBER && __toktyp != REALNUM)
2098     {
2099      __pv_ferr(1049,
2100      "non parenthesized delay parameter name or number expected - %s read",
2101       __prt_kywrd_vtok());
2102      return(FALSE);
2103     }
2104    __last_xtk = -1;
2105    /* on error, set as error expr. - maybe since param should be 0 */
2106    if (!__bld_expnode()) __set_xtab_errval();
2107    /* here does the allocating */
2108    __bld_xtree(0);
2109    pmp = __alloc_pval();
2110    pmp->plxndp = __root_ndp;
2111    pmp->pmlnxt = NULL;
2112    *pmphdr = pmp;
2113   }
2114  else
2115   {
2116    /* #(...) form */
2117    for (last_pmp = NULL;;)
2118     {
2119      __get_vtok();
2120      if (!__col_delexpr())
2121       {
2122        if (!__vskipto3_modend(COMMA, RPAR, SEMI)) return(FALSE);
2123        if (__toktyp == SEMI) return(FALSE);
2124       }
2125      __bld_xtree(0);
2126      pmp = __alloc_pval();
2127      pmp->plxndp = __root_ndp;
2128 
2129      /* link on front */
2130      if (last_pmp == NULL) *pmphdr = pmp; else last_pmp->pmlnxt = pmp;
2131      last_pmp = pmp;
2132 
2133      if (__toktyp == COMMA) continue;
2134      if (__toktyp == RPAR) break;
2135      /* should never happen - sync on err above, if does give up */
2136      __pv_ferr(1050,
2137       "delay parameter list comma or right parenthesis expected - %s read",
2138       __prt_vtok());
2139      return(FALSE);
2140     }
2141   }
2142  __get_vtok();
2143  return(TRUE);
2144 }
2145 
2146 /*
2147  * allocate a # style parameter value (also for specify delays)
2148  */
__alloc_pval(void)2149 extern struct paramlst_t *__alloc_pval(void)
2150 {
2151  struct paramlst_t *pmp;
2152 
2153  pmp = (struct paramlst_t *) __my_malloc(sizeof(struct paramlst_t));
2154  pmp->plxndp = NULL;
2155  pmp->pmlnxt = NULL;
2156  return(pmp);
2157 }
2158 
2159 /*
2160  * process a wire decl. assign
2161  * notice # delays and strengths are put into globals
2162  * also notice wire values in this case moved here no wire delay
2163  */
do_wdecl_assgn(struct sy_t * syp,struct paramlst_t * pmphdr,int32 first_time)2164 static int32 do_wdecl_assgn(struct sy_t *syp, struct paramlst_t *pmphdr,
2165  int32 first_time)
2166 {
2167  struct conta_t *cap;
2168  struct expr_t *lhs_ndp;
2169  int32 sfnind, slcnt;
2170 
2171  /* need lhs wire as location of conta */
2172  sfnind = syp->syfnam_ind;
2173  slcnt = __lin_cnt;
2174  /* wire decl. form continuous assignment */
2175  /* generate expression from node that is simply wire name */
2176  lhs_ndp = __gen_wireid_expr(syp);
2177  /* collect rhs and build expression tree */
2178  __get_vtok();
2179  if (!__col_comsemi(-1)) return(FALSE);
2180  __bld_xtree(0);
2181  cap = add_conta(lhs_ndp, __root_ndp, sfnind, slcnt);
2182  /* uses wire decl delay and strength */
2183  if (first_time) cap->ca_du.pdels = pmphdr;
2184  else cap->ca_du.pdels = __copy_dellst(pmphdr);
2185  if (__v0stren != NO_STREN)
2186   {
2187    cap->ca_hasst = TRUE;
2188    cap->ca_stval = ((__v0stren << 3) | __v1stren) & 0x3f;
2189   }
2190  return(TRUE);
2191 }
2192 
2193 /*
2194  * read the initialize to expr and add to mod's var init list
2195  * format example: reg r = 12;
2196  *
2197  * build the net and expr pair lists here - check to make sure constant
2198  * expr during fixup and initialize as first sim step in pv_sim
2199  *
2200  * notice can't check the constant expr here since parameter decl may
2201  * follow in source order
2202  */
rdbld_mod_varinitlst(struct sy_t * syp)2203 static int32 rdbld_mod_varinitlst(struct sy_t *syp)
2204 {
2205  struct varinitlst_t *initp;
2206 
2207  /* collect rhs and build expression tree */
2208  __get_vtok();
2209  if (!__col_comsemi(-1)) return(FALSE);
2210  __bld_xtree(0);
2211 
2212  initp = (struct varinitlst_t *) __my_malloc(sizeof(struct varinitlst_t));
2213  initp->init_syp = syp;
2214  initp->init_xp = __root_ndp;
2215  initp->varinitnxt = NULL;
2216 
2217  if (__end_mod_varinitlst == NULL) __inst_mod->mvarinits = initp;
2218  else __end_mod_varinitlst->varinitnxt = initp;
2219  __end_mod_varinitlst = initp;
2220 
2221  return(TRUE);
2222 }
2223 
2224 /*
2225  * add the wire type decl. symbol and associated wire/reg
2226  *
2227  * caller must set wire type after checking for duplicates
2228  * for declares only at top level
2229  * need null ranges for real, width set later or special case
2230  * returns null on error
2231  * x1 and x2 passed must be copies for multiple decls in one stmt case
2232  *
2233  * for non vendor 1 specific dsyp will always be nil
2234  */
__decl_wirereg(word32 wtyp,struct expr_t * x1,struct expr_t * x2,struct sy_t * dsyp)2235 extern struct net_t *__decl_wirereg(word32 wtyp, struct expr_t *x1,
2236  struct expr_t *x2, struct sy_t *dsyp)
2237 {
2238  struct net_t *np;
2239  struct sy_t *syp;
2240  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
2241 
2242  /* this find and sets type for already read and processed I/O port decl. */
2243  syp = __decl_sym(__token, __venviron[0]);
2244  if (__sym_is_new)
2245   {
2246    np = __add_net(syp);
2247    np->iotyp = NON_IO;
2248    np->ntyp = wtyp;
2249    if (x1 != NULL)
2250     { np->n_isavec = TRUE; np->nu.ct->nx1 = x1; np->nu.ct->nx2 = x2; }
2251   }
2252  else
2253   {
2254    if (syp->sytyp != SYM_N)
2255     {
2256      __pv_ferr(1028,
2257       "cannot declare %s as %s - previously declared as %s at %s",
2258       syp->synam, __to_wtnam2(s2, wtyp), __to_wtnam2(s1, syp->sytyp),
2259       __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
2260      return(NULL);
2261     }
2262 
2263    /* wire/reg decl. after I/O decl. may set range */
2264    np = syp->el.enp;
2265    /* need special handling for module I/O ports - declared in header, */
2266    /* I/O direction and maybe wire */
2267    if (np->iotyp != NON_IO)
2268     {
2269      /* if wire decl. for I/O port use it */
2270      /* any wire type, reg, int32, and time ok here, but not real or event */
2271      if (wtyp == N_REAL || wtyp == N_EVENT)
2272       {
2273        __pv_ferr(1009,
2274         "%s port %s %s illegal", __to_ptnam(s1, np->iotyp), syp->synam,
2275         __to_wtnam2(s2, wtyp));
2276        return(NULL);
2277       }
2278      /* this only has meaning for I/O port redecls */
2279      if (np->nu.ct->n_wirtypknown)
2280       {
2281        if (dsyp == NULL)
2282         {
2283          __pv_ferr(1010,
2284           "%s port %s previously declared as %s cannot be %s",
2285 	  __to_ptnam(s1, np->iotyp), syp->synam, __to_wtnam(s2, np),
2286 	  __to_wtnam2(s3, wtyp));
2287         }
2288        else
2289         {
2290          __pv_ferr(1010,
2291           "%s port %s previously declared as %s - unknown: %s",
2292 	  __to_ptnam(s1, np->iotyp), syp->synam, __to_wtnam(s2, np),
2293           dsyp->synam);
2294         }
2295        return(NULL);
2296       }
2297      np->ntyp = wtyp;
2298     }
2299    else
2300     {
2301      if (is_decl_err(syp, SYM_N, wtyp)) return(NULL);
2302      /* must set wire type - may override guessed wire type from use */
2303      np->ntyp = wtyp;
2304     }
2305    if (!chkset_wdrng(np, x1, x2)) return(NULL);
2306    np->nu.ct->n_wirtypknown = TRUE;
2307   }
2308  /* port header wire, require I/O port dir. decl., else this is decl. */
2309  if (np->iotyp == NON_IO)
2310   {
2311    syp->sydecl = TRUE;
2312    /* even if used before, must set to declaration place */
2313    syp->syfnam_ind = __cur_fnam_ind;
2314    syp->sylin_cnt = __lin_cnt;
2315   }
2316  return(np);
2317 }
2318 
2319 /*
2320  * allocate a new net for a symbol that is just seen for first time
2321  */
__add_net(struct sy_t * syp)2322 extern struct net_t *__add_net(struct sy_t *syp)
2323 {
2324  struct net_t *np;
2325 
2326  np = (struct net_t *) __my_malloc(sizeof(struct net_t));
2327  np->nsym = syp;
2328  /* allocate during compilation part - free and change to storage later */
2329  np->nrngrep = NX_CT;
2330  np->nu.ct = (struct ncomp_t *) __alloc_arrncomp();
2331  /* also initialize */
2332  np->nu.ct->nx1 = np->nu.ct->nx2 = NULL;
2333  np->nu.ct->ax1 = np->nu.ct->ax2 = NULL;
2334  np->nu.ct->n_pb_drvtyp = NULL;
2335  np->nu.ct->n_drvtyp = DRVR_NONE;
2336  np->nu.ct->n_dels_u.pdels = NULL;
2337  np->nu.ct->n_iotypknown = FALSE;
2338  np->nu.ct->n_wirtypknown = FALSE;
2339  np->nu.ct->n_rngknown = FALSE;
2340  np->nu.ct->n_impldecl = FALSE;
2341  np->nu.ct->n_in_giarr_rng = FALSE;
2342  np->nu.ct->n_onrhs = FALSE;
2343  np->nu.ct->n_onlhs = FALSE;
2344  np->nu.ct->n_2ndonlhs = FALSE;
2345  np->nu.ct->num_prtconns = 0;
2346  /* this is default implies word32 a/b type also for reals */
2347  np->srep = SR_VEC;
2348 
2349  /* fields for parameters only */
2350  np->nu.ct->n_widthdet = FALSE;
2351  np->nu.ct->n_indir_widthdet = FALSE;
2352  np->nu.ct->p_specparam = FALSE;
2353  np->nu.ct->p_rhs_has_param = FALSE;
2354  np->nu.ct->p_locparam = FALSE;
2355  np->nu.ct->p_setby_defpnd = FALSE;
2356  np->nu.ct->prngdecl = FALSE;
2357  np->nu.ct->ptypdecl = FALSE;
2358  np->nu.ct->psigndecl = FALSE;
2359  np->nu.ct->parm_srep = SR_VEC;
2360  np->nu.ct->pbase = BNONE;
2361  np->nu.ct->pstring = FALSE;
2362 
2363  /* init fields for comiled sim */
2364  np->nu.ct->frc_assgn_in_src = FALSE;
2365  np->nu.ct->monit_in_src = FALSE;
2366  np->nu.ct->dmpv_in_src = FALSE;
2367 
2368  /* assumes normal wire e when in header these will be changed */
2369  np->iotyp = NON_IO;
2370  np->n_isaparam = FALSE;
2371  np->n_isavec = FALSE;
2372  np->nwid = 0;
2373  np->n_isarr = FALSE;
2374  /* cap. strength of non cap. strength strong is no cap. strength */
2375  np->n_capsiz = CAP_NONE;
2376  np->n_signed = FALSE;
2377  np->nu.ct->n_iscompleted = FALSE;
2378  np->nu.ct->n_spltstate = SPLT_DFLT;
2379  /* this gets sets in v_prep if vector - vectored is scalared */
2380  np->vec_scalared = TRUE;
2381  np->n_stren = FALSE;
2382  np->n_mark = FALSE;
2383  np->n_multfi = FALSE;
2384  np->n_isapthsrc = FALSE;
2385  np->n_isapthdst = FALSE;
2386  np->n_hasdvars = FALSE;
2387  np->n_onprocrhs = FALSE;
2388  np->n_gone = FALSE;
2389  np->nchg_nd_chgstore = FALSE;
2390  np->nchg_has_dces = FALSE;
2391  np->nchg_has_lds = FALSE;
2392  /* 03/21/01 - these are fields from removed separate optim table */
2393  np->frc_assgn_allocated = FALSE;
2394  np->dmpv_in_src = FALSE;
2395  np->monit_in_src = FALSE;
2396  np->n_onrhs = FALSE;
2397  np->n_onlhs = FALSE;
2398  np->n_drvtyp = DRVR_NONE;
2399  np->dcelst = NULL;
2400  np->ndrvs = NULL;
2401  np->nlds = NULL;
2402  np->ntraux = NULL;
2403  np->nchgaction = NULL;
2404  np->vpi_ndrvs = NULL;
2405  np->regwir_putv_tedlst = NULL;
2406  np->nva.wp = NULL;
2407  np->nu2.nnxt = NULL;
2408  np->nattrs = NULL;
2409  syp->sytyp = SYM_N;
2410  syp->el.enp = np;
2411  /* assume reg */
2412  np->ntyp = N_REG;
2413  return(np);
2414 }
2415 
2416 /*
2417  * allocate a ncomp element from a preallocated block for fast freeing
2418  */
__alloc_arrncomp(void)2419 extern struct ncomp_t *__alloc_arrncomp(void)
2420 {
2421  struct ncablk_t *ncabp;
2422  struct ncomp_t *ncmp;
2423 
2424  if (__ncablk_nxti == -1)
2425   {
2426    ncabp = (struct ncablk_t *) __my_malloc(sizeof(struct ncablk_t));
2427    ncabp->ancmps = (struct ncomp_t *) __my_malloc(BIG_ALLOC_SIZE);
2428    ncabp->ncablknxt = __hdr_ncablks;
2429    __hdr_ncablks = ncabp;
2430    __ncablk_nxti = 0;
2431   }
2432  ncmp = (struct ncomp_t *) &(__hdr_ncablks->ancmps[__ncablk_nxti]);
2433  if (++__ncablk_nxti > ((BIG_ALLOC_SIZE/sizeof(struct ncomp_t)) - 1))
2434   __ncablk_nxti = -1;
2435  return(ncmp);
2436 }
2437 
2438 /*
2439  * print message and return true if declaration error
2440  * called for declaration when symbol is not new
2441  * for symbols that are like variables
2442  */
is_decl_err(struct sy_t * syp,word32 dclsytyp,word32 dclwtyp)2443 static int32 is_decl_err(struct sy_t *syp, word32 dclsytyp,
2444  word32 dclwtyp)
2445 {
2446  struct net_t *np;
2447  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
2448 
2449  if (syp->sytyp == SYM_N) np = syp->el.enp; else np = NULL;
2450  /* symbol already declared */
2451  /* see if declaration repeated */
2452  if (syp->sydecl || syp->sytyp != dclsytyp)
2453   {
2454    /* current symbol */
2455    if (np != NULL) __to_wtnam(s1, np); else __to_sytyp(s1, syp->sytyp);
2456    /* declared type */
2457    if (dclsytyp == SYM_N) __to_wtnam2(s2, dclwtyp);
2458    else __to_sytyp(s2, dclsytyp);
2459 
2460    if (syp->sydecl) strcpy(s3, "declared"); else strcpy(s3, "used");
2461    __pv_ferr(1014, "%s %s previously %s as %s at %s", s2, syp->synam,
2462     s3, s1, __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
2463    return(TRUE);
2464   }
2465  return(FALSE);
2466 }
2467 
2468 /*
2469  * set a register width
2470  */
set_reg_widths(word32 wtyp,struct expr_t ** x1,struct expr_t ** x2)2471 static void set_reg_widths(word32 wtyp, struct expr_t **x1,
2472  struct expr_t **x2)
2473 {
2474  word32 rhigh;
2475 
2476  if (wtyp == N_INT) rhigh = WBITS - 1;
2477  else if (wtyp == N_TIME) rhigh = TIMEBITS - 1;
2478  else if (wtyp == N_REAL) rhigh = REALBITS - 1;
2479  else { *x1 = NULL; *x2 = NULL; return; }
2480  *x1 = __bld_rng_numxpr(rhigh, 0L, WBITS);
2481  *x2 = __bld_rng_numxpr(0L, 0L, WBITS);
2482 }
2483 
2484 /*
2485  * for constant predefined ranges need to build a number expr.
2486  * so param substitution and folding will work but do nothing
2487  *
2488  * LOOKATME - siz must be <= WBITS so why pass it
2489  */
__bld_rng_numxpr(word32 av,word32 bv,int32 siz)2490 extern struct expr_t *__bld_rng_numxpr(word32 av, word32 bv, int32 siz)
2491 {
2492  struct expr_t *ndp;
2493 
2494  /* this also initializes node */
2495  ndp = __alloc_newxnd();
2496  __set_numval(ndp, av, bv, siz);
2497  return(ndp);
2498 }
2499 
2500 /*
2501  * check and possibly set wire range
2502  */
chkset_wdrng(struct net_t * np,struct expr_t * x1,struct expr_t * x2)2503 static int32 chkset_wdrng(struct net_t *np, struct expr_t *x1,
2504  struct expr_t *x2)
2505 {
2506  int32 cval;
2507  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
2508 
2509  /* know range - either previous I/O or wire decl. with range */
2510  if (np->nu.ct->n_rngknown)
2511   {
2512    if (x1 == NULL) return(TRUE);
2513    if (np->nu.ct->nx1 != NULL)
2514     cval = cmp_rng(x1, x2, np->nu.ct->nx1, np->nu.ct->nx2);
2515    else cval = 1;
2516    if (cval != 0)
2517     {
2518      __to_wrange(s2, np);
2519      __pv_fwarn(568,
2520      "%s port %s declaration range %s mismatch with port range %s",
2521       __to_wtnam(s1, np), np->nsym->synam,
2522       __msgtox_wrange(s3, x1, x2), s2);
2523     }
2524    return(TRUE);
2525   }
2526  if (x1 != NULL)
2527   {
2528    np->nu.ct->n_rngknown = TRUE;
2529    np->n_isavec = TRUE;
2530    np->nu.ct->nx1 = x1;
2531    np->nu.ct->nx2 = x2;
2532   }
2533  return(TRUE);
2534 }
2535 
2536 /*
2537  * compare 2 range exprs during compilation - before params known
2538  * equal if same known numbers (or numeric expr.) or if exprs the same
2539  */
cmp_rng(struct expr_t * x1,struct expr_t * x2,struct expr_t * nx1,struct expr_t * nx2)2540 static int32 cmp_rng(struct expr_t *x1, struct expr_t *x2,
2541  struct expr_t *nx1, struct expr_t *nx2)
2542 {
2543  if (!__cmp_xpr(x1, nx1)) return(1);
2544  if (!__cmp_xpr(x2, nx2)) return(1);
2545  return(0);
2546 }
2547 
2548 /*
2549  * compare 2 expressions for identicalness
2550  * if incorrect real, same and error caught later
2551  */
__cmp_xpr(struct expr_t * nx,struct expr_t * ox)2552 extern int32 __cmp_xpr(struct expr_t *nx, struct expr_t *ox)
2553 {
2554  int32 retval, owlen, nwlen;
2555  word32 *owp, *nwp;
2556 
2557  switch ((byte) nx->optyp) {
2558   case NUMBER:
2559    if (ox->optyp != NUMBER) return(FALSE);
2560    owlen = wlen_(ox->szu.xclen);
2561    nwlen = wlen_(nx->szu.xclen);
2562    /* since implied assignment to 32 bit value - just use low words */
2563    owp = &(__contab[ox->ru.xvi]);
2564    nwp = &(__contab[nx->ru.xvi]);
2565    if (owp[0] != nwp[0]) return(FALSE);
2566    if (owp[owlen] != nwp[nwlen]) return(FALSE);
2567    break;
2568   case ID:
2569    /*FALLTHRU */
2570   case GLBREF:
2571    if (ox->lu.sy != nx->lu.sy) return(FALSE);
2572    break;
2573   default:
2574    if (ox->optyp != nx->optyp) return(FALSE);
2575    retval = TRUE;
2576    if (ox->lu.x != NULL) retval = __cmp_xpr(nx->lu.x, ox->lu.x);
2577    if (!retval) return(FALSE);
2578    if (ox->ru.x != NULL) retval = __cmp_xpr(nx->ru.x, ox->ru.x);
2579    return(retval);
2580  }
2581  return(TRUE);
2582 }
2583 
2584 /*
2585  * get optional strengths
2586  * know first strength read and reads one past ending )
2587  * can be cap size or strength pair - because of cont. assignments gets
2588  * checked later
2589  * set globals __v0stren and __v1stren
2590  */
rd_verstrens(void)2591 static int32 rd_verstrens(void)
2592 {
2593  int32 strentyp;
2594 
2595  __v0stren = __v1stren = NO_STREN;
2596  /* this sets __v0stren and __v1stren F means structural problem */
2597  if (!rd_1verstren(&strentyp)) return(FALSE);
2598  /* returned T and 2nd strength null means cap. size */
2599  if (strentyp == CAP_STREN) { __get_vtok(); return(TRUE); }
2600  if (__toktyp == RPAR)
2601   {
2602    __pv_ferr(1015,
2603     "required 2nd drive strength missing - %s read", __prt_vtok());
2604    return(FALSE);
2605   }
2606 
2607  /* know comma read to get here */
2608  __get_vtok();
2609  if (!rd_1verstren(&strentyp)) return(FALSE);
2610  if (__toktyp == COMMA)
2611   {
2612    __pv_ferr(1016, "strength list has more than 2 strengths");
2613    return(FALSE);
2614   }
2615  __get_vtok();
2616  if (__v0stren == NO_STREN || __v1stren == NO_STREN)
2617   {
2618    __pv_ferr(1017, "0 or 1 transition strength repeated (other missing)");
2619    if (__v0stren == NO_STREN) __v0stren = __v1stren;
2620    else __v1stren = __v0stren;
2621   }
2622  if (__v0stren == ST_HIGHZ && __v1stren == ST_HIGHZ)
2623   {
2624    __pv_ferr(1018, "(highz0, highz1) strength illegal");
2625    __v0stren = __v1stren = NO_STREN;
2626   }
2627  else if (__v0stren == ST_STRONG && __v1stren == ST_STRONG)
2628   {
2629    __finform(424,
2630     "explicit (strong0, strong1) removed to speed up simulation");
2631    __v0stren = __v1stren = NO_STREN;
2632   }
2633  return(TRUE);
2634 }
2635 
2636 
2637 /*
2638  * get 1 strength - know leading '(' and strength read
2639  * reads ending ')' or ',', sets __v1stren and __v0stren
2640  *
2641  * notice this returns symbolic constant that is strength type set either
2642  * __v0stren or __v1stren depending on token type
2643  * returns F on token error else F, if bad sets to none
2644  */
rd_1verstren(int32 * strentyp)2645 static int32 rd_1verstren(int32 *strentyp)
2646 {
2647  int32 strenval;
2648 
2649  *strentyp = NO_STREN;
2650  if ((*strentyp = is_tokstren(__toktyp)) == CAP_STREN)
2651   {
2652    strenval = __fr_stren_nam(__toktyp);
2653    __get_vtok();
2654    if (__toktyp != RPAR)
2655     {
2656      __pv_ferr(1019, "trireg charge strength ending ')' expected - %s read",
2657       __prt_vtok());
2658      return(FALSE);
2659     }
2660    __v0stren = strenval;
2661    return(TRUE);
2662   }
2663  if (*strentyp == LOW_STREN)
2664   {
2665    if (__v0stren != NO_STREN)
2666     __pv_fwarn(569, "both strengths are 0 transition - 2nd changed");
2667    __v0stren = __fr_stren_nam(__toktyp);
2668   }
2669  else if (*strentyp == HIGH_STREN)
2670   {
2671    if (__v1stren != NO_STREN)
2672     __pv_fwarn(569, "both strengths are 1 transition - 2nd changed");
2673    __v1stren = __fr_stren_nam(__toktyp);
2674   }
2675  else
2676   {
2677    __pv_ferr(1020, "expected strength missing - %s read", __prt_vtok());
2678    return(FALSE);
2679   }
2680  __get_vtok();
2681  if (__toktyp != COMMA && __toktyp != RPAR)
2682   {
2683    __pv_ferr(1021,
2684     "strength not followed by comma or right parenthesis - %s read",
2685     __prt_vtok());
2686    return(FALSE);
2687   }
2688  return(TRUE);
2689 }
2690 
2691 /*
2692  * determine if token type strength and whether 0 or 1 group
2693  */
is_tokstren(int32 ttyp)2694 static int32 is_tokstren(int32 ttyp)
2695 {
2696  switch ((byte) ttyp) {
2697   case SUPPLY0: case STRONG0: case PULL0: case WEAK0: case HIGHZ0:
2698    return(LOW_STREN);
2699   case SUPPLY1: case STRONG1: case PULL1: case WEAK1: case HIGHZ1:
2700    return(HIGH_STREN);
2701   case SMALL: case MEDIUM: case LARGE:
2702    return(CAP_STREN);
2703  }
2704  return(NO_STREN);
2705 }
2706 
2707 /*
2708  * read the parameter statement (declares the parameter)
2709  * form: parameter [name] = [value], [name] = [value], ...;
2710  * where name is a simple id and [value] is a constant expr.
2711  *
2712  * no # or () around delay in parameter decl. but min:typ:max form
2713  * needs () since rhs is constant expr. in grammar not mintypmax expr.
2714  *
2715  * if returns F synced to next module, else synced to SEMI
2716  *
2717  * also reads vendor1 specific param types
2718  *
2719  * SJM 10/07/03 - add optional signed declaration - following normal
2720  * rule for parameter typing, if signed not present determined from rhs
2721  *
2722  * SJM 05/25/04 - added new P1364 module #(<param decl>, ...) form but only
2723  * for modules parameter declarations and unlike header list of ports both
2724  * types can be combined
2725  */
rd_paramdecl(int32 is_hdr_form,int32 is_local_param)2726 static int32 rd_paramdecl(int32 is_hdr_form, int32 is_local_param)
2727 {
2728  int32 ptyp_decl, prng_decl, pwtyp, pwid, r1, r2, wlen;
2729  int32 psign_decl;
2730  word32 *wp;
2731  struct expr_t *dx1, *dx2, *x1, *x2, *ax1, *ax2;
2732  struct net_t *np;
2733  struct xstk_t *xsp;
2734  char paramnam[IDLEN], ptnam[RECLEN];
2735 
2736  if (is_local_param) strcpy(ptnam, "localparam");
2737  else strcpy(ptnam, "parameter");
2738 
2739  dx1 = dx2 = x1 = x2 = ax1 = ax2 = NULL;
2740  ptyp_decl = FALSE;
2741  prng_decl = FALSE;
2742  pwtyp = -1;
2743  pwid = 0;
2744  psign_decl = FALSE;
2745  __get_vtok();
2746  if (__toktyp == SIGNED)
2747   {
2748    psign_decl = TRUE;
2749    __get_vtok();
2750   }
2751 
2752  /* case 1: range but not decl type */
2753  if (__toktyp == LSB)
2754   {
2755    /* also check to make sure ranges are non x/z 32 bit values */
2756    if (!__rd_opt_param_vec_rng(&dx1, &dx2, is_hdr_form)) return(FALSE);
2757    if (dx1 == NULL || dx2 == NULL) goto rd2_param_list;
2758 
2759    r1 = (int32) __contab[dx1->ru.xvi];
2760    r2 = (int32) __contab[dx2->ru.xvi];
2761    pwid = (r1 >= r2) ? r1 - r2 + 1 : r2 - r1 + 1;
2762    pwtyp = N_REG;
2763    x1 = dx1; x2 = dx2;
2764    prng_decl = TRUE;
2765    /* DBG remove --- */
2766    if (x1 == NULL) goto rd_param_list;
2767    /* --- */
2768    /* know parameter name read */
2769    goto rd2_param_list;
2770   }
2771 
2772  /* if next token not optional - if range, implied reg type */
2773  if ((pwtyp = __fr_wtnam(__toktyp)) == -1)
2774   {
2775    pwtyp = N_REG;
2776    x1 = dx1; x2 = dx2;
2777    /* implied decl as range */
2778    if (x1 != NULL) ptyp_decl = TRUE;
2779    goto rd2_param_list;
2780   }
2781  else
2782   {
2783    if (pwtyp == N_EVENT || pwtyp < NONWIRE_ST)
2784     {
2785      __pv_ferr(685, "%s declaration illegal type %s", ptnam, __prt_vtok());
2786      x1 = x2 = NULL;
2787      pwtyp = N_REG;
2788      goto rd_param_list;
2789     }
2790 
2791    ptyp_decl = TRUE;
2792    switch ((byte) pwtyp) {
2793     case N_REAL:
2794      pwid = REALBITS;
2795      goto chk_norng;
2796     case N_TIME:
2797      pwid = TIMEBITS;
2798      goto chk_norng;
2799     case N_INT:
2800      pwid = WBITS;
2801 chk_norng:
2802      if (dx1 != NULL)
2803       {
2804        __pv_ferr(686, "%s declaration range illegal for opt_type %s",
2805         ptnam, __to_wtnam2(__xs, (word32) pwtyp));
2806       }
2807      x1 = __bld_rng_numxpr(pwid - 1, 0L, WBITS);
2808      x2 = __bld_rng_numxpr(0L, 0L, WBITS);
2809      prng_decl = FALSE;
2810      break;
2811     default:
2812      __case_terr(__FILE__, __LINE__);
2813      return(FALSE);
2814    }
2815   }
2816 
2817 rd_param_list:
2818  __get_vtok();
2819 rd2_param_list:
2820  /* SJM 10/06/03 - signed keyword not allowed with var types */
2821  if (psign_decl && (pwtyp == N_TIME || pwtyp == N_INT || pwtyp == N_REAL))
2822   {
2823    __pv_ferr(3423,
2824     "signed keyword illegal when parameter variable type %s",
2825     __to_wtnam2(__xs, pwtyp));
2826    psign_decl = FALSE;
2827   }
2828 
2829  /* if ptyp decl F, then must attempt to determine param type from rhs */
2830  for (;;)
2831   {
2832    if (__toktyp != ID)
2833     {
2834      __pv_ferr(1023,
2835       "%s declaration parameter name expected - %s read", ptnam,
2836       __prt_kywrd_vtok());
2837 bad_end:
2838      /* part of delay expression may have been built */
2839      if (!is_hdr_form)
2840       {
2841        if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
2842        if (__toktyp == COMMA) { __get_vtok(); continue; }
2843       }
2844      else
2845       {
2846        if (!__vskipto2_any(COMMA, RPAR)) return(FALSE);
2847        if (__toktyp == COMMA) { __get_vtok(); continue; }
2848       }
2849      return(TRUE);
2850     }
2851    strcpy(paramnam, __token);
2852 
2853    /* notice the initial value is required */
2854    __get_vtok();
2855    /* parameter arrays now but only declarator present legal */
2856    /* also range for arrays must be repeated for each one */
2857    if (__toktyp == LSB)
2858     {
2859      /* also check to make sure ranges are non x/z 32 bit values */
2860      if (!rd_opt_param_array_rng(&ax1, &ax2, is_hdr_form)) return(FALSE);
2861     }
2862    if (ax1 != NULL && !ptyp_decl)
2863     {
2864      __pv_ferr(687,
2865       "parameter array %s illegal - explicit type declaration required for parameter arrays",
2866       paramnam);
2867      /* notice not freeing expr. memory on syntax error */
2868      ax1 = ax2 = NULL;
2869     }
2870 
2871    if (__toktyp != EQ)
2872     {
2873      __pv_ferr(1024,
2874       "%s declaration equal expected - %s read", ptnam, __prt_vtok());
2875      goto bad_end;
2876     }
2877 
2878    /* notice initial value required */
2879    __get_vtok();
2880    /* this can collect array construct that will look like concat */
2881    if (is_hdr_form)
2882     {
2883      /* SJM 05/26/04 - new module decl #(list of param decls) form needs */
2884      /* different collect routine because semi illegal */
2885      if (!__col_lofp_paramrhsexpr()) goto bad_end;
2886     }
2887    else
2888     {
2889      if (!__col_newparamrhsexpr()) goto bad_end;
2890     }
2891    __bld_xtree(0);
2892 
2893    if (__has_top_mtm)
2894     {
2895      __pv_fwarn(652,
2896       "%s %s declaration min:typ:max expression needs parentheses under 1364 - unportable",
2897       ptnam, paramnam);
2898     }
2899 
2900    /* handle parameter arrays as special case */
2901    if (ax1 != NULL)
2902     {
2903      /* warning if parameter array used */
2904      __pv_fwarn(643,
2905       "parameter array %s enhancement - not part of P1364 standard",
2906       paramnam);
2907      /* notice range and type for all in possible param list but */
2908      /* array range and initializer different for each */
2909      /* if error returns nil and try to resync */
2910      if ((np = chkadd_array_param(paramnam, pwtyp, pwid, psign_decl, x1, x2,
2911        ax1, ax2))
2912        == NULL) goto bad_end;
2913 
2914      goto nxt_param;
2915     }
2916 
2917 
2918    /* checking rhs does no evaluation but set sizes and checks for */
2919    /* only params that are defined previously in module */
2920    /* SJM 10/06/03 - rd chk paramexpr routine set expr signed bit */
2921    if (__expr_has_glb(__root_ndp) || !__src_rd_chk_paramexpr(__root_ndp, 0))
2922     {
2923      __pv_ferr(1025,
2924       "%s %s declaration right hand side \"%s\" error - defined %ss and constants only",
2925       ptnam, paramnam, __msgexpr_tostr(__xs, __root_ndp), ptnam);
2926      /* need to still add value of x to prevent further errors */
2927      __free2_xtree(__root_ndp);
2928      __root_ndp->szu.xclen = WBITS;
2929      __set_numval(__root_ndp, ALL1W, ALL1W, WBITS);
2930      /* SJM 03/15/00 - on err if decl as real - must convert to non real */
2931      if (pwtyp == N_REAL) pwtyp = N_REG;
2932     }
2933 
2934    /* check and links on modules parameter list */
2935    /* when rhs expr. evaluated, if real will change */
2936    /* LOOKATME - problem with all params in list sharing range xprs? */
2937    /* SJM 01/24/00 - works since for globalparam runs in virt glb param mod */
2938    if ((np = __add_param(paramnam, x1, x2, is_local_param)) == NULL)
2939     {
2940      return(FALSE);
2941     }
2942 
2943    /* require that at this point all param rhs expressions are numbers */
2944    /* know possible and needed for copying and later defparam assign */
2945    /* rule from LRM is that all param initial values known when first read */
2946    xsp = __src_rd_eval_xpr(__root_ndp);
2947 
2948    /* case parameter type declared - maybe convert - must eval before here */
2949    /* if range, implied pwtyp set to reg type */
2950    if (ptyp_decl || prng_decl)
2951     {
2952      if (pwtyp == N_REAL)
2953       {
2954        np->ntyp = N_REAL;
2955        np->n_signed = TRUE;
2956        np->nwid = REALBITS;
2957        np->nu.ct->pbase = BDBLE;
2958        if (!__root_ndp->is_real)
2959         __src_rd_cnv_stk_fromreg_toreal(xsp, (__root_ndp->has_sign == 1));
2960       }
2961      else
2962       {
2963        np->ntyp = pwtyp;
2964        /* if declared always know width */
2965        np->nwid = pwid;
2966        if (np->ntyp == N_INT || (np->ntyp == N_REG && psign_decl))
2967         np->n_signed = TRUE;
2968 
2969        /* even if declared use rhs expr. for param ncomp expr formats */
2970        if (__root_ndp->is_string) np->nu.ct->pstring = TRUE;
2971        np->nu.ct->pbase = __root_ndp->ibase;
2972 
2973        /* convert declared param type real rhs to int/reg */
2974        if (__root_ndp->is_real)
2975         {
2976          __src_rd_cnv_stk_fromreal_toreg32(xsp);
2977          np->nu.ct->pbase = BDEC;
2978         }
2979        /* xsp always right width for parameter net width */
2980        if (xsp->xslen != pwid) __sizchgxs(xsp, pwid);
2981 
2982        /* SJM 09/29/03 - change to handle sign extension and separate types */
2983        if (xsp->xslen != pwid) __narrow_sizchg(xsp, pwid);
2984        else if (xsp->xslen < pwid)
2985         {
2986          if (__root_ndp->has_sign) __sgn_xtnd_widen(xsp, pwid);
2987          else __sizchg_widen(xsp, pwid);
2988         }
2989       }
2990     }
2991    else
2992     {
2993      /* no parameter range given or will not get here */
2994      if (__root_ndp->is_real)
2995       {
2996        np->ntyp = N_REAL;
2997        np->n_signed = TRUE;
2998       }
2999      else
3000       {
3001        np->ntyp = N_REG;
3002        /* SJM 10/06/03 - no range or var type but signed may be present */
3003        if (psign_decl) np->n_signed = TRUE;
3004        else
3005         {
3006          if (__root_ndp->has_sign) np->n_signed = TRUE;
3007         }
3008       }
3009 
3010      np->nwid = __root_ndp->szu.xclen;
3011      if (np->nwid > 1)
3012       {
3013        np->n_isavec = TRUE;
3014        np->vec_scalared = TRUE;
3015        np->nu.ct->nx1 = __bld_rng_numxpr(np->nwid - 1, 0L, WBITS);
3016        np->nu.ct->nx2 = __bld_rng_numxpr(0L, 0L, WBITS);
3017       }
3018      /* always true for real and int32 - maybe true from others */
3019      if (__root_ndp->is_string) np->nu.ct->pstring = TRUE;
3020      /* this works because param expr checking always sets ibase */
3021      np->nu.ct->pbase = __root_ndp->ibase;
3022     }
3023 
3024    if (ptyp_decl) np->nu.ct->ptypdecl = TRUE;
3025    if (prng_decl) np->nu.ct->prngdecl = TRUE;
3026    if (psign_decl) np->nu.ct->psigndecl = TRUE;
3027    if (__xpr_has_param(__root_ndp))
3028     {
3029      np->nu.ct->p_rhs_has_param = TRUE;
3030      __inst_mod->mod_rhs_param = TRUE;
3031     }
3032 
3033    /* using ncomp delay union to store original expresssion - set first */
3034    np->nu.ct->n_dels_u.d1x = __root_ndp;
3035    np->nu.ct->parm_srep = SR_PXPR;
3036 
3037    /* value must be evaluated to constant expr - since may need to */
3038    /* change to IS form */
3039    /* assign the value as SR PNUM form because now always "declared" - has */
3040    /* kown type so can store as net value */
3041    wlen = wlen_(xsp->xslen);
3042    wp = (word32 *) __my_malloc(2*WRDBYTES*wlen);
3043    memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
3044    np->nva.wp = wp;
3045    np->srep = SR_PNUM;
3046    __pop_xstk();
3047 
3048 
3049    if (__debug_flg)
3050     {
3051      char s1[RECLEN], s2[RECLEN], *chp;
3052 
3053      strcpy(s1, "");
3054      strcpy(s2, "");
3055      if (__root_ndp->is_real) strcpy(s1, "real ");
3056      else
3057       {
3058        sprintf(s2, " width %d", __root_ndp->szu.xclen);
3059        if (__root_ndp->is_string) strcpy(s1, "string ");
3060        else if (__root_ndp->has_sign) strcpy(s1, "signed ");
3061       }
3062      /* SJM 04/20/00 - changed so uses param type for printing */
3063      /* SJM 05/24/00 - trim leading spaces */
3064      __pregab_tostr(__xs, wp, &(wp[wlen]), np);
3065      for (chp = __xs;; chp++) { if (*chp != ' ') break; }
3066      __dbg_msg(
3067       "%s%s %s defined at **%s(%d) has initial value %s%s\n", s1,
3068       ptnam, paramnam, __cur_fnam, __lin_cnt, chp, s2);
3069     }
3070 
3071 nxt_param:
3072    if (is_hdr_form)
3073     {
3074      if (__toktyp == RPAR) break;
3075      if (__toktyp != COMMA)
3076       {
3077        __pv_ferr(1026,
3078         "%s module header form declaration right paren or comma expected - %s read",
3079         ptnam, __prt_vtok());
3080        if (!__vskipto2_any(COMMA, RPAR)) return(FALSE);
3081        if (__toktyp == RPAR) break;
3082       }
3083     }
3084    else
3085     {
3086      if (__toktyp == SEMI) break;
3087      if (__toktyp != COMMA)
3088       {
3089        __pv_ferr(1026,
3090         "%s declaration semicolon or comma separator expected - %s read",
3091         ptnam, __prt_vtok());
3092        if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
3093        if (__toktyp == SEMI) break;
3094       }
3095     }
3096    __get_vtok();
3097    if (is_hdr_form)
3098     {
3099      /* if , followed by ID, part of list else new parameter decl */
3100      if (__toktyp == PARAMETER) break;
3101     }
3102   }
3103  return(TRUE);
3104 }
3105 
3106 /*
3107  * return T if parameter define rhs expr contains any param
3108  *
3109  * set ncomp rhs has param bit causes re-eval of param value
3110  * to use new pound and defparam values if changed
3111  */
__xpr_has_param(struct expr_t * ndp)3112 extern int32 __xpr_has_param(struct expr_t *ndp)
3113 {
3114  struct sy_t *syp;
3115  struct net_t *np;
3116  struct expr_t *fandp;
3117 
3118  switch ((byte) ndp->optyp) {
3119   case NUMBER: case REALNUM: case ISNUMBER: case ISREALNUM: return(FALSE);
3120   case ID:
3121    syp = ndp->lu.sy;
3122    if (!syp->sydecl || syp->sytyp != SYM_N) return(FALSE);
3123    np = syp->el.enp;
3124    if (np->n_isaparam) return(TRUE);
3125    return(FALSE);
3126   case GLBREF: return(FALSE);
3127   case FCALL:
3128    for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
3129     {
3130      /* LOOKATME - even if real param not allowed arg to const systf */
3131      /* can be real */
3132      if (__xpr_has_param(fandp->lu.x)) return(TRUE);
3133     }
3134    return(FALSE);
3135  }
3136  if (ndp->lu.x != NULL) if (__xpr_has_param(ndp->lu.x)) return(TRUE);
3137  if (ndp->ru.x != NULL) if (__xpr_has_param(ndp->ru.x)) return(TRUE);
3138  return(FALSE);
3139 }
3140 
3141 /*
3142  * version of chk paramexpr that is called for parameters during
3143  * source input
3144  */
__src_rd_chk_paramexpr(struct expr_t * ndp,int32 xwid)3145 extern int32 __src_rd_chk_paramexpr(struct expr_t *ndp, int32 xwid)
3146 {
3147  int32 rv, sav_sfnam_ind, sav_slin_cnt;
3148 
3149  /* SJM 10/01/99 - improve error location for param checking */
3150  /* chk param expr needs sim locations set - set temporary guess here */
3151  sav_sfnam_ind = __sfnam_ind;
3152  sav_slin_cnt = __slin_cnt;
3153  __sfnam_ind = __cur_fnam_ind;
3154  __slin_cnt = __lin_cnt;
3155 
3156  rv = __chk_paramexpr(ndp, xwid);
3157 
3158  __sfnam_ind = sav_sfnam_ind;
3159  __slin_cnt = sav_slin_cnt;
3160 
3161  return(rv);
3162 }
3163 
3164 /*
3165  * read a parameter vector declaration range
3166  *
3167  * know [ read and reads one past ]
3168  */
__rd_opt_param_vec_rng(struct expr_t ** ax1,struct expr_t ** ax2,int32 is_hdr_form)3169 extern int32 __rd_opt_param_vec_rng(struct expr_t **ax1, struct expr_t **ax2,
3170  int32 is_hdr_form)
3171 {
3172  int32 rngerr;
3173  struct expr_t *x1, *x2;
3174  char ptnam[RECLEN], s1[RECLEN];
3175 
3176  if (__cur_declobj == SPECIFY) strcpy(ptnam, "specparam");
3177  strcpy(ptnam, "parameter");
3178 
3179  *ax1 = *ax2 = NULL;
3180  rngerr = FALSE;
3181  if (!__rd_decl_rng(&x1, &x2))
3182   {
3183    if (!is_hdr_form)
3184     {
3185      if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
3186      if (__toktyp == SEMI) return(TRUE);
3187     }
3188    else
3189     {
3190      if (!__vskipto3_any(COMMA, RPAR, RSB)) return(FALSE);
3191      if (__toktyp != RSB) return(TRUE);
3192     }
3193    rngerr = TRUE;
3194    __get_vtok();
3195    goto done;
3196   }
3197  if (__expr_has_glb(x1) || !__src_rd_chk_paramexpr(x1, 0))
3198   {
3199    __pv_ferr(1025,
3200     "%s declaration first range \"%s\" illegal - defined %ss and constants only",
3201     ptnam, __msgexpr_tostr(__xs, x1), ptnam);
3202    rngerr = TRUE;
3203   }
3204  else
3205   {
3206    /* because of previous check, this can not fail */
3207    __eval_param_rhs_tonum(x1);
3208    sprintf(s1, "%s declaration first range", ptnam);
3209    if (!__nd_ndxnum(x1, s1, TRUE)) rngerr = TRUE;
3210   }
3211  if (__expr_has_glb(x2) || !__chk_paramexpr(x2, 0))
3212   {
3213    __pv_ferr(1025,
3214     "%s declaration second range \"%s\" illegal - defined %ss and constants only",
3215     ptnam, __msgexpr_tostr(__xs, x2), ptnam);
3216    rngerr = TRUE;
3217   }
3218  else
3219   {
3220    /* because of previous check, this can not fail */
3221    __eval_param_rhs_tonum(x2);
3222    sprintf(s1, "%s declaration second range", ptnam);
3223    if (!__nd_ndxnum(x2, s1, TRUE)) rngerr = TRUE;
3224   }
3225 
3226 done:
3227  if (rngerr)
3228   {
3229    if (x1 != NULL) __free_xtree(x1);
3230    if (x2 != NULL) __free_xtree(x2);
3231    x1 = x2 = NULL;
3232   }
3233  *ax1 = x1;
3234  *ax2 = x2;
3235  return(TRUE);
3236 }
3237 
3238 /*
3239  * read a parameter array declaration range
3240  *
3241  * know [ read and reads one past ]
3242  */
rd_opt_param_array_rng(struct expr_t ** ax1,struct expr_t ** ax2,int32 is_hdr_form)3243 static int32 rd_opt_param_array_rng(struct expr_t **ax1, struct expr_t **ax2,
3244  int32 is_hdr_form)
3245 {
3246  int32 rngerr;
3247  struct expr_t *x1, *x2;
3248 
3249  rngerr = FALSE;
3250  if (!__rd_decl_rng(&x1, &x2) || x1 == NULL || x2 == NULL)
3251   {
3252    if (!is_hdr_form)
3253     {
3254      if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
3255      if (__toktyp == SEMI) return(TRUE);
3256     }
3257    else
3258     {
3259      if (!__vskipto3_any(COMMA, RPAR, RSB)) return(FALSE);
3260      if (__toktyp != RSB) return(TRUE);
3261     }
3262    rngerr = TRUE;
3263    __get_vtok();
3264    goto done;
3265   }
3266  /* one past possible ] read */
3267  /* convert ranges to constant index */
3268  if (__expr_has_glb(x1) || !__src_rd_chk_paramexpr(x1, 0))
3269   {
3270    __pv_ferr(1025,
3271     "parameter array declaration first range \"%s\" illegal - defined parameters and constants only",
3272     __msgexpr_tostr(__xs, x1));
3273    rngerr = TRUE;
3274   }
3275  else
3276   {
3277    /* because of previous check, this can not fail */
3278    __eval_param_rhs_tonum(x1);
3279    if (!__nd_ndxnum(x1, "parameter array declaration first range", TRUE))
3280      rngerr = TRUE;
3281   }
3282  if (__expr_has_glb(x2) || !__src_rd_chk_paramexpr(x2, 0))
3283   {
3284    __pv_ferr(1025,
3285     "parameter array declaration second range \"%s\" illegal - defined parameters and constants only",
3286     __msgexpr_tostr(__xs, x2));
3287    rngerr = TRUE;
3288   }
3289  else
3290   {
3291    /* because of previous check, this can not fail */
3292    __eval_param_rhs_tonum(x2);
3293    if (!__nd_ndxnum(x2, "parameter array declaration second range", TRUE))
3294     rngerr = TRUE;
3295   }
3296 done:
3297  if (rngerr)
3298   {
3299    if (x1 != NULL) __free_xtree(x1);
3300    if (x2 != NULL) __free_xtree(x2);
3301    x1 = x2 = NULL;
3302   }
3303  *ax1 = x1;
3304  *ax2 = x2;
3305  return(TRUE);
3306 }
3307 
3308 /*
3309  * routine to check and declare array param
3310  *
3311  * also sets initial array value
3312  * know cur mod set when this is called
3313  */
chkadd_array_param(char * paramnam,int32 pwtyp,int32 pwid,int32 psign,struct expr_t * x1,struct expr_t * x2,struct expr_t * ax1,struct expr_t * ax2)3314 static struct net_t *chkadd_array_param(char *paramnam, int32 pwtyp, int32 pwid,
3315  int32 psign, struct expr_t *x1, struct expr_t *x2, struct expr_t *ax1,
3316   struct expr_t *ax2)
3317 {
3318  register int32 ai;
3319  word32 *wp;
3320  int32 unnorm_ai, r1, r2, awid, wlen;
3321  int32 initerr, some_str, all_str;
3322  struct expr_t *catndp, *xp, **avalxtab;
3323  struct net_t *np;
3324  struct xstk_t *xsp;
3325  char s1[RECLEN];
3326 
3327  if (__root_ndp->optyp != LCB)
3328   {
3329    __pv_ferr(688,
3330     "parameter %s array initial value %s not array constructor ({} concatenate) ",
3331     paramnam, __msgexpr_tostr(__xs, x2));
3332    return(NULL);
3333   }
3334  /* build table of parameters */
3335  r1 = (int32) __contab[ax1->ru.xvi];
3336  r2 = (int32) __contab[ax2->ru.xvi];
3337  /* number of cells in array */
3338  awid = (r1 >= r2) ? r1 - r2 + 1 : r2 - r1 + 1;
3339  avalxtab = (struct expr_t **) __my_malloc(awid*sizeof(struct expr_t *));
3340  for (ai = 0; ai < awid; ai++) avalxtab[ai] = NULL;
3341 
3342  /* first step unwind array constructor repeats */
3343  unwind_param_array_constructor(__root_ndp);
3344  if (__debug_flg)
3345   {
3346    __dbg_msg("parameter %s declare array initializer unwound to: %s\n",
3347    paramnam, __msgexpr_tostr(__xs, __root_ndp));
3348   }
3349 
3350  /* fill table of expressions */
3351  catndp = __root_ndp->ru.x;
3352  /* first is internal high cell */
3353  initerr = FALSE;
3354  for (ai = awid - 1; catndp != NULL; catndp = catndp->ru.x)
3355   {
3356    unnorm_ai = (r1 >= r2) ? (r2 + ai) : (r2 - ai);
3357    xp = catndp->lu.x;
3358    /* DBG remove --- */
3359    if (xp->optyp == CATREP) __misc_terr(__FILE__, __LINE__);
3360    /* --- */
3361    chk1_arrinit_expr(xp, paramnam, unnorm_ai);
3362    if (ai < 0)
3363     {
3364      __pv_ferr(689,
3365       "parameter array initializer at %s[%d] %s illegal - fills past end",
3366       paramnam, unnorm_ai, __msgexpr_tostr(__xs, xp));
3367      initerr = TRUE;
3368      continue;
3369     }
3370    avalxtab[ai] = __copy_expr(xp);
3371    ai--;
3372   }
3373  /* finally check to make sure fill width correct */
3374  if (ai >= 0)
3375   {
3376    __pv_ferr(689,
3377     "parameter array %s initializer width %d illegal - only %d filled",
3378     paramnam, awid, ai + 1);
3379    return(NULL);
3380   }
3381  /* do not add unless initializer good */
3382  if (initerr) return(NULL);
3383 
3384  /* know all cells in aval xtab filled - add param - must be declared */
3385  if ((np = __add_param(paramnam, x1, x2, TRUE)) == NULL) return(NULL);
3386 
3387  np->nu.ct->ax1 = ax1;
3388  np->nu.ct->ax2 = ax2;
3389  np->n_isarr = TRUE;
3390  /* index of this cannot be used in pound params */
3391  np->nu.ct->p_locparam = TRUE;
3392  np->srep = SR_PNUM;
3393 
3394  if (pwtyp == N_REAL)
3395   {
3396    np->ntyp = N_REAL;
3397    np->n_signed = TRUE;
3398    np->nwid = REALBITS;
3399    np->nu.ct->pbase = BDBLE;
3400   }
3401  else
3402   {
3403    np->ntyp = pwtyp;
3404    /* if declared always know width */
3405    np->nwid = pwid;
3406    if (np->ntyp == N_INT) np->n_signed = TRUE;
3407    else
3408     {
3409      if (psign && np->ntyp != N_TIME) np->n_signed = TRUE;
3410     }
3411 
3412    /* if some but not all strings needs warning */
3413    for (some_str = FALSE, all_str = TRUE, ai = awid - 1; ai >= 0; ai--)
3414     {
3415      if (avalxtab[ai]->is_string) some_str = TRUE;
3416      else all_str = FALSE;
3417     }
3418    if (some_str && !all_str)
3419     {
3420      __pv_fwarn(615,
3421       "parameter array %s some but not all cells initialized to strings - strings treated as numbers",
3422       paramnam);
3423     }
3424    if (all_str) np->nu.ct->pstring = TRUE;
3425    np->nu.ct->pbase = __root_ndp->ibase;
3426   }
3427  /* allocate and fill parameter array - never packed */
3428 
3429  /* allocate and fill parameter array */
3430  wlen = wlen_(np->nwid);
3431  np->nva.wp = (word32 *) __my_malloc(2*WRDBYTES*awid*wlen);
3432  for (ai = awid - 1; ai >= 0; ai--)
3433   {
3434    unnorm_ai = (r1 >= r2) ? (r2 + ai) : (r2 - ai);
3435    xsp = __src_rd_eval_xpr(avalxtab[ai]);
3436    sprintf(s1, "parameter array cell %s[%d] initializer", np->nsym->synam,
3437     unnorm_ai);
3438    /* afer here know xsp width match declared parameter width */
3439    cnvt_to_pdecl(xsp, avalxtab[ai], np, s1);
3440    wp = &(np->nva.wp[2*wlen*ai]);
3441    memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
3442    __pop_xstk();
3443   }
3444 
3445  /* save expression that is original array constructor expression */
3446  np->nu.ct->n_dels_u.d1x = __root_ndp;
3447  np->nu.ct->parm_srep = SR_PXPR;
3448 
3449  /* free expression table */
3450  for (ai = awid - 1; ai >= 0; ai--) __free_xtree(avalxtab[ai]);
3451  __my_free((char *) avalxtab, awid*sizeof(struct expr_t *));
3452 
3453  if (__debug_flg)
3454   {
3455    if (np->ntyp == N_REAL)
3456     sprintf(s1, "[%d:%d] cell real array", r1, r2);
3457    else if (pwtyp == N_INT)
3458     sprintf(s1, "[%d:%d] cell integer array", r1, r2);
3459    else
3460     {
3461      sprintf(s1, " [%d:%d] cell %d bit reg array", r1, r2, np->nwid);
3462      if (np->nu.ct->pstring) strcat(s1, " [string]");
3463      else if (np->n_signed && pwtyp != N_INT) strcat(s1, " [signed]");
3464     }
3465    __dbg_msg("%s parameter %s defined at **%s(%d):\n", s1, paramnam,
3466     __cur_fnam, __lin_cnt);
3467    for (ai = awid - 1; ai >= 0; ai--)
3468     {
3469      unnorm_ai = (r1 >= r2) ? (r2 + ai) : (r2 - ai);
3470 
3471      wp = &(np->nva.wp[2*wlen*ai]);
3472      __dbg_msg("  %s[%d] = %s\n", paramnam, unnorm_ai, __pregab_tostr(__xs,
3473       wp, &(wp[wlen]), np));
3474     }
3475   }
3476  return(np);
3477 }
3478 
3479 /*
3480  * special xstk conversion routine where must convert to declared size
3481  *
3482  * this converts to type and size of param - new algorithm assumes
3483  * that parameters are somehow declared (possibly from initial rhs expr)
3484  */
cnvt_to_pdecl(struct xstk_t * xsp,struct expr_t * xrhs,struct net_t * np,char * innam)3485 static void cnvt_to_pdecl(struct xstk_t *xsp, struct expr_t *xrhs,
3486  struct net_t *np, char *innam)
3487 {
3488  char s1[RECLEN];
3489 
3490  /* DBG remove -- */
3491  if (!np->n_isaparam) __arg_terr(__FILE__, __LINE__);
3492  /* --- */
3493 
3494  if (np->ntyp == N_REAL)
3495   {
3496    if (!xrhs->is_real)
3497     {
3498      if (xrhs->szu.xclen == WBITS && xrhs->has_sign) strcpy(s1, "integer");
3499      else sprintf(s1, "%d bit register", xrhs->szu.xclen);
3500      __gfinform(486, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3501       "parameter %s in %s assign required conversion from %s to real",
3502       np->nsym->synam, innam, s1);
3503 
3504      __cnv_stk_fromreg_toreal(xsp, (xrhs->has_sign == 1));
3505     }
3506   }
3507  else
3508   {
3509    /* know param is non real */
3510    if (xrhs->is_real)
3511     {
3512      if (np->nwid == WBITS && np->n_signed) strcpy(s1, "integer");
3513      else sprintf(s1, "%d bit register", np->nwid);
3514 
3515      __gfinform(487, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3516       "parameter %s in %s assign required conversion from real to %s",
3517       np->nsym->synam, innam, s1);
3518 
3519      __cnv_stk_fromreal_toreg32(xsp);
3520     }
3521    /* but it may have wrong width - in new algorithm param assigns */
3522    if (xsp->xslen != np->nwid)
3523     {
3524      __gfinform(488, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3525       "parameter %s in %s assign required width change from %d to %d",
3526       np->nsym->synam, innam, xsp->xslen, np->nwid);
3527      /* key always convert to declared */
3528 
3529      /* SJM 09/29/03 - change to handle sign extension and separate types */
3530      if (xsp->xslen > np->nwid) __narrow_sizchg(xsp, np->nwid);
3531      else if (xsp->xslen < np->nwid)
3532       {
3533        if (xrhs->has_sign) __sgn_xtnd_widen(xsp, np->nwid);
3534        else __sizchg_widen(xsp, np->nwid);
3535       }
3536     }
3537   }
3538 }
3539 
3540 /*
3541  * check and unwind array constructor
3542  *
3543  * this will create normal array constructor from repeat count form
3544  * when done concatenate is one level with catreps removed
3545  */
unwind_param_array_constructor(struct expr_t * ndp)3546 static void unwind_param_array_constructor(struct expr_t *ndp)
3547 {
3548  if (__isleaf(ndp)) return;
3549 
3550  /* array constructor (concatenate) unwinding must be done bottom up */
3551  if (ndp->lu.x != NULL) { unwind_param_array_constructor(ndp->lu.x); }
3552  if (ndp->ru.x != NULL) { unwind_param_array_constructor(ndp->ru.x); }
3553 
3554  /* node is top of concatenate with all sub concatenates simplified */
3555  if (ndp->optyp == LCB)
3556   {
3557    register struct expr_t *ndp2;
3558    struct expr_t *last_ndp2, *end_ndp;
3559 
3560    last_ndp2 = ndp;
3561    for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
3562     {
3563      struct expr_t *lop;
3564 
3565      lop = ndp2->lu.x;
3566      /* notice ,, form illegal in concatentate */
3567      switch ((byte) lop->optyp) {
3568       case NUMBER: case REALNUM:
3569        break;
3570       case LCB:
3571        {
3572         /* nested concatenate - splice up one level */
3573         last_ndp2->ru.x = lop->ru.x;
3574 	/* find rightmost element - know always there */
3575 	end_ndp = __find_catend(lop);
3576 	/* if rightmost up one node will make null */
3577 	end_ndp->ru.x = ndp2->ru.x;
3578 	/* end of new chain is new last */
3579 	last_ndp2 = end_ndp;
3580        }
3581        continue;
3582       case CATREP:
3583        {
3584         int32 repval;
3585 	struct expr_t *dupndp;
3586 	struct xstk_t *xsp;
3587 
3588         if (__src_rd_chk_paramexpr(lop->lu.x, 0))
3589 	 {
3590 	  xsp = __src_rd_eval_xpr(lop->lu.x);
3591 	  if (xsp->xslen > WBITS)
3592 	   {
3593             if (!vval_is0_(&(xsp->ap[1]), xsp->xslen - WBITS)
3594              || !vval_is0_(&(xsp->bp[1]), xsp->xslen - WBITS)
3595 	     || xsp->bp[0] != 0L) goto bad_rep;
3596 	   }
3597           else if (xsp->bp[0] != 0) goto bad_rep;
3598 	  repval = (int32) xsp->ap[0];
3599           if (repval == 1)
3600            __finform(442,
3601             "array constructore repeat value of 1 has no effect");
3602 	 }
3603         else
3604 	 {
3605 bad_rep:
3606           __pv_ferr(814,
3607            "array constructor repeat value %s not an integral constant expression",
3608 	   __msgexpr_tostr(__xs, lop->lu.x));
3609           repval = 1;
3610          }
3611 
3612 	__pop_xstk();
3613         /* know the rhs thing must be a concatenate */
3614         dupndp = __dup_concat(repval, lop->ru.x->ru.x);
3615 
3616         /* nested concatenate - splice up one level */
3617         last_ndp2->ru.x = dupndp;
3618         /* find rightmost element - know always there */
3619 	end_ndp = __find_catend(dupndp);
3620 
3621 	/* if rightmost up one node will make null */
3622 	end_ndp->ru.x = ndp2->ru.x;
3623 	/* end of new chain is new last */
3624 	last_ndp2 = end_ndp;
3625        }
3626        continue;
3627       }
3628      /* NUMBER or other means move last down tree one */
3629      last_ndp2 = ndp2;
3630     }
3631   }
3632 }
3633 
3634 /*
3635  * check one array initializer expression
3636  */
chk1_arrinit_expr(struct expr_t * xp,char * paramnam,int32 ai)3637 static void chk1_arrinit_expr(struct expr_t *xp, char *paramnam, int32 ai)
3638 {
3639  if (__expr_has_glb(xp) || !__src_rd_chk_paramexpr(xp, 0))
3640   {
3641    __pv_ferr(1025,
3642     "parameter array initializer cell %s[%d] \"%s\" illegal - parameters and constants only",
3643     paramnam, ai, __msgexpr_tostr(__xs, xp));
3644    /* need to still add value of x to prevent further errors */
3645    __free2_xtree(xp);
3646    xp->szu.xclen = WBITS;
3647    __set_numval(xp, ALL1W, ALL1W, WBITS);
3648   }
3649 }
3650 
3651 /*
3652  * return T if expression has any global reference
3653  */
__expr_has_glb(struct expr_t * xp)3654 extern int32 __expr_has_glb(struct expr_t *xp)
3655 {
3656  if (__isleaf(xp))
3657   {
3658    if (xp->optyp == GLBREF) return(TRUE);
3659    return(FALSE);
3660   }
3661  if (xp->lu.x != NULL) { if (__expr_has_glb(xp->lu.x)) return(TRUE); }
3662  if (xp->ru.x != NULL) { if (__expr_has_glb(xp->ru.x)) return(TRUE); }
3663  return(FALSE);
3664 }
3665 
3666 /*
3667  * routine to evaluate parameters or defparam rhs and produce constant
3668  *
3669  * this expects itree location to be set but no IS forms allowed by here
3670  * know rhs legal (only params and constants)
3671  * this freezes any parameter, # param or defparam to number from now on
3672  */
__eval_param_rhs_tonum(struct expr_t * ndp)3673 extern void __eval_param_rhs_tonum(struct expr_t *ndp)
3674 {
3675  int32 wlen, is_str, xbase;
3676  double d1;
3677  struct xstk_t *xsp;
3678 
3679  if (ndp->is_string) is_str = TRUE; else is_str = FALSE;
3680  xbase = ndp->ibase;
3681 
3682  /* possibly different expr. */
3683  switch ((byte) ndp->optyp) {
3684   case NUMBER: case REALNUM: break;
3685   /* IS forms can only be created by # or defparam assignments later */
3686   /* can never be in source */
3687   case ISNUMBER: case ISREALNUM: __arg_terr(__FILE__, __LINE__); break;
3688  default:
3689   if (ndp->optyp == ID && ndp->lu.sy->el.enp->n_isaparam)
3690    {
3691     is_str = ndp->lu.sy->el.enp->nu.ct->pstring;
3692     xbase = ndp->lu.sy->el.enp->nu.ct->pbase;
3693    }
3694   else if (ndp->optyp == LCB) is_str = TRUE;
3695   xsp = __src_rd_eval_xpr(ndp);
3696   __free2_xtree(ndp);
3697   wlen = wlen_(xsp->xslen);
3698   if (xsp->xslen <= WBITS)
3699    {
3700     if (ndp->is_real)
3701      {
3702       memcpy(&d1, xsp->ap, sizeof(double));
3703       ndp->ru.xvi = __alloc_shareable_rlcval(d1);
3704      }
3705     else
3706      {
3707       ndp->ru.xvi = __alloc_shareable_cval(xsp->ap[0], xsp->bp[0], xsp->xslen);
3708      }
3709    }
3710   else
3711    {
3712     ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, wlen);
3713    }
3714   __pop_xstk();
3715   /* notice string from rhs param expr. impossible */
3716   if (ndp->is_real) ndp->optyp = REALNUM;
3717   else
3718    {
3719     ndp->optyp = NUMBER;
3720     /* notice leave rest of ndp fields the same */
3721     ndp->is_string = is_str;
3722    }
3723   ndp->ibase = xbase;
3724  }
3725 }
3726 
3727 /*
3728  * add newly declared parameter - better not be already defined
3729  * called from parameter declaration item only
3730  * range must be passed because of parameter "v[h:l] =" form (not yet in)
3731  *
3732  * uses initial expressions to set wire type - defparam can change
3733  * but one type for all instance
3734  *
3735  * this is for both parameters and specparams indicated by current decl obj
3736  * for specparam top of scope symbol table stack is special symbol table
3737  * just for specparams - no other symbols legal
3738  *
3739  * code that reads parameter arrays calls this then sets fields it
3740  */
__add_param(char * nam,struct expr_t * x1,struct expr_t * x2,int32 is_local_param)3741 extern struct net_t *__add_param(char *nam, struct expr_t *x1,
3742  struct expr_t *x2, int32 is_local_param)
3743 {
3744  int32 is_spec;
3745  struct tnode_t *tnp;
3746  struct sy_t *syp;
3747  struct net_t *np;
3748  char s1[RECLEN], ptypnam[RECLEN];
3749 
3750  if (__cur_declobj == SPECIFY)
3751   { is_spec = TRUE; strcpy(ptypnam, "specparam"); }
3752  else
3753   {
3754    is_spec = FALSE;
3755    if (is_local_param) strcpy(ptypnam, "localparam");
3756    else strcpy(ptypnam, "parameter");
3757   }
3758  /* just look in local scope here since parameter decl. must be local */
3759  tnp = __vtfind(nam, __venviron[__top_sti]);
3760  if (__sym_is_new)
3761   {
3762    __add_sym(nam, tnp);
3763    /* notice still need to update total symbol count */
3764    (__venviron[__top_sti]->numsyms)++;
3765    syp = tnp->ndp;
3766    /* this initializes ncomp for all net forms including params */
3767    np = __add_net(syp);
3768   }
3769  else
3770   {
3771    syp = tnp->ndp;
3772    if (syp->sytyp == SYM_N) np = syp->el.enp; else np = NULL;
3773    if (!syp->sydecl)
3774     {
3775      /* is previously used as net, then ok */
3776      if (syp->sytyp != SYM_N)
3777       {
3778        __pv_ferr(1027,
3779         "cannot declare %s %s - previously used as %s at %s",
3780         nam, ptypnam, __to_sytyp(s1, syp->sytyp), __bld_lineloc(__xs,
3781         syp->syfnam_ind, syp->sylin_cnt));
3782        return(NULL);
3783       }
3784     }
3785    else
3786     {
3787      /* this needs to be explicit to include param wire types */
3788      if (np != NULL) __to_wtnam2(s1, np->ntyp);
3789      else __to_sytyp(s1, syp->sytyp);
3790      __pv_ferr(1028, "cannot declare %s %s - previously declared as %s at %s",
3791       nam, ptypnam, s1, __bld_lineloc(__xs, syp->syfnam_ind,
3792       syp->sylin_cnt));
3793      return(NULL);
3794     }
3795    /* know will be wire to get to be declared here */
3796    syp->syfnam_ind = __cur_fnam_ind;
3797    syp->sylin_cnt = __lin_cnt;
3798   }
3799  syp->sydecl = TRUE;
3800 
3801  /* change to proper type of wire even if already used */
3802  /* io type for parameter unused instead used for wire type */
3803  np->iotyp = NON_IO;
3804  np->n_isaparam = TRUE;
3805  np->nu.ct->p_locparam = is_local_param;
3806  if (is_spec) np->nu.ct->p_specparam = TRUE;
3807 
3808  /* if has range know is vector */
3809  if (x1 != NULL) { np->n_isavec = TRUE; np->vec_scalared = TRUE; }
3810  np->nu.ct->nx1 = x1;
3811  np->nu.ct->nx2 = x2;
3812 
3813  /* notice already linked into wire list - must also link into param list */
3814  /* link on end to preserve order */
3815  /* link the LOCAL parameters on a seperate list than the regular params */
3816  if (is_local_param)
3817   {
3818    if (__cur_declobj == MODULE)
3819     {
3820      if (__end_loc_paramnp == NULL) __inst_mod->mlocprms = np;
3821      else __end_loc_paramnp->nu2.nnxt = np;
3822      __end_loc_paramnp = np;
3823     }
3824    else if (__cur_declobj == TASK)
3825     {
3826      if (__end_tsk_loc_paramnp == NULL) __cur_tsk->tsk_locprms = np;
3827      else __end_tsk_loc_paramnp->nu2.nnxt = np;
3828      __end_tsk_loc_paramnp = np;
3829     }
3830    else __case_terr(__FILE__, __LINE__);
3831   }
3832  else
3833   {
3834    /* regular parameter list */
3835    if (__cur_declobj == MODULE)
3836     {
3837      /* module parameter declaration */
3838      if (__end_paramnp == NULL) __inst_mod->mprms = np;
3839      else __end_paramnp->nu2.nnxt = np;
3840      __end_paramnp = np;
3841     }
3842    else if (__cur_declobj == SPECIFY)
3843     {
3844      if (__end_msprms == NULL) __cur_spfy->msprms = np;
3845      else __end_msprms->nu2.nnxt = np;
3846      __end_msprms = np;
3847     }
3848    else if (__cur_declobj == TASK)
3849     {
3850      if (__end_tskparamnp == NULL) __cur_tsk->tsk_prms = np;
3851      else __end_tskparamnp->nu2.nnxt = np;
3852      __end_tskparamnp = np;
3853     }
3854    else __case_terr(__FILE__, __LINE__);
3855   }
3856  return(np);
3857 }
3858 
3859 /*
3860  * read a continuous assign module item
3861  * assign statement read and reads ending ;
3862  * return F if cannot sync to ending ;, if F will be sync to next mod/prim
3863  * list of assignments allowed here
3864  */
rd_contassign(void)3865 static int32 rd_contassign(void)
3866 {
3867  struct expr_t *lhsndp, *rhsndp;
3868  struct paramlst_t *pmphdr;
3869  struct conta_t *cap;
3870  int32 first_time, sfnind, slcnt;
3871 
3872  /* must read drive strength and delay */
3873  pmphdr = NULL;
3874  __v0stren = __v1stren = NO_STREN;
3875 
3876  __get_vtok();
3877  if (__toktyp == LPAR)
3878   {
3879    __get_vtok();
3880    if (!rd_verstrens())
3881     {
3882      if (!__vskipto2_any(RPAR, SEMI)) return(FALSE);
3883      if (__toktyp == RPAR) { __get_vtok(); goto rd_parms; }
3884      return(TRUE);
3885     }
3886   }
3887 
3888 rd_parms:
3889  if (__toktyp == SHARP)
3890   {
3891    if (!rd_oparamdels(&pmphdr))
3892     {
3893 bad_end:
3894      return(__vskipto_any(SEMI));
3895     }
3896   }
3897  for (first_time = TRUE;;)
3898   {
3899    sfnind = __cur_fnam_ind;
3900    slcnt = __lin_cnt;
3901    /* collect lhs */
3902    if (!__col_lval()) goto bad_end;
3903    __bld_xtree(0);
3904 
3905    lhsndp = __root_ndp;
3906    __get_vtok();
3907    if (!__col_comsemi(-1)) goto bad_end;
3908    __bld_xtree(0);
3909    rhsndp = __root_ndp;
3910    cap = add_conta(lhsndp, rhsndp, sfnind, slcnt);
3911    if (first_time) cap->ca_du.pdels = pmphdr;
3912    else cap->ca_du.pdels = __copy_dellst(pmphdr);
3913 
3914    if (__v0stren != NO_STREN)
3915     {
3916      cap->ca_hasst = TRUE;
3917      cap->ca_stval = ((__v0stren << 3) | __v1stren) & 0x3f;
3918     }
3919    if (__toktyp == SEMI) break;
3920    if (__toktyp != COMMA)
3921     {
3922      /* try to sync to next list el. if present */
3923      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
3924      if (__toktyp == SEMI) break;
3925     }
3926    first_time = FALSE;
3927    __get_vtok();
3928   }
3929  return(TRUE);
3930 }
3931 
3932 /*
3933  * add a continuous assignment form cell
3934  * even if lhs 1 bit stored in non gate form here
3935  */
add_conta(struct expr_t * lhsndp,struct expr_t * rhsndp,int32 sfnind,int32 slcnt)3936 static struct conta_t *add_conta(struct expr_t *lhsndp,
3937  struct expr_t *rhsndp, int32 sfnind, int32 slcnt)
3938 {
3939  struct conta_t *cap;
3940  struct sy_t *syp;
3941 
3942  syp = __bld_loc_symbol(__conta_num, __venviron[0], "assgn",
3943   "continuous assign");
3944  syp->sytyp = SYM_CA;
3945  /* this is place of declaration */
3946  syp->syfnam_ind = sfnind;
3947  syp->sylin_cnt = slcnt;
3948  syp->sydecl = TRUE;
3949 
3950  cap = (struct conta_t *) __my_malloc(sizeof(struct conta_t));
3951  cap->casym = syp;
3952  syp->el.ecap = cap;
3953  cap->ca_hasst = FALSE;
3954  cap->ca_stval = ST_STRVAL;
3955  cap->ca_delrep = DT_CMPLST;
3956  cap->ca_du.pdels = NULL;
3957  cap->ca_4vdel = FALSE;
3958  cap->ca_gone = FALSE;
3959  cap->ca_pb_sim = FALSE;
3960  cap->ca_pb_el = FALSE;
3961  cap->lhsx = lhsndp;
3962  cap->rhsx = rhsndp;
3963  cap->caschd_tevs = NULL;
3964  cap->ca_drv_wp.wp = NULL;
3965  cap->schd_drv_wp.wp = NULL;
3966  /* SJM 12/19/04 - when chk contas done - contas now tab of size m ca num */
3967  /* removed nxt field from conta type - can be in pbca's built in prp pass */
3968  cap->pbcau.canxt = NULL;
3969  /* link on to list */
3970  if (__end_ca == NULL) __inst_mod->mcas = cap;
3971  else __end_ca->pbcau.canxt = cap;
3972  __end_ca = cap;
3973  __conta_num++;
3974  return(cap);
3975 }
3976 
3977 /*
3978  * read an event declaration
3979  *
3980  * parsing routine to read and declare an event decl (can't be array/vec)
3981  * need to declare as task var if reading task/func/named block
3982  */
rd_eventdecl(int32 reading_tsk)3983 static int32 rd_eventdecl(int32 reading_tsk)
3984 {
3985  int32 first_time, has_attr;
3986  struct net_t *np;
3987 
3988  /* use local has attr flag so can turn glb seen of before return */
3989  if (__wrk_attr.attr_seen) { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
3990  else has_attr = FALSE;
3991  for (first_time = TRUE;;)
3992   {
3993    __get_vtok();
3994    if (__toktyp != ID)
3995     {
3996      __pv_ferr(1029,
3997       "event declaration event name expected - %s read", __prt_kywrd_vtok());
3998      goto try_resync;
3999     }
4000    /* since no range, if fails just try next one*/
4001    if (reading_tsk) np = decl_taskvar(N_EVENT, NULL, NULL);
4002    else np = __decl_wirereg(N_EVENT, NULL, NULL, NULL);
4003 
4004    /* SJM - 03/20/00 - save wire decl attrs */
4005    if (has_attr)
4006     {
4007      /* until Verilog 2000 will not see also event port attrs */
4008      if (np != NULL) add_net_attr(np, EVENT);
4009     }
4010 
4011    if (first_time) first_time = FALSE;
4012 
4013    __get_vtok();
4014    if (__toktyp == SEMI) break;
4015    if (__toktyp != COMMA)
4016     {
4017      __pv_ferr(1033,
4018       "event declaration comma or semicolon separator expected - %s read",
4019       __prt_vtok());
4020      /* try to resync */
4021 try_resync:
4022      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
4023      if (__toktyp == SEMI) break;
4024     }
4025   }
4026  return(TRUE);
4027 }
4028 
4029 /*
4030  * allocate a statement entry
4031  * for empty statement (;) never get here
4032  */
__alloc_stmt(int32 styp)4033 extern struct st_t *__alloc_stmt(int32 styp)
4034 {
4035  struct st_t *stp;
4036  struct for_t *frp;
4037  struct qconta_t *qcafs;
4038 
4039  stp = (struct st_t *) __my_malloc(sizeof(struct st_t));
4040  __init_stmt(stp, styp);
4041  (__inst_mod->mstnum)++;
4042 
4043  /* DBG remove --
4044  if (__debug_flg)
4045   {
4046     extern char *__to_sttyp(char *, word32);
4047 
4048     __dbg_msg("AT %s %s - STMT ALLOC (%s)\n",
4049      __bld_lineloc(__xs, stp->stfnam_ind, stp->stlin_cnt),
4050      __inst_mod->msym->synam, __to_sttyp(__xs2, styp));
4051   }
4052  --- */
4053  /* DBG remove --
4054  if (__debug_flg)
4055   {
4056    extern char *__to_sttyp(char *, unsigned);
4057 
4058    __dbg_msg("%04d: AT %s %s - STMT ALLOC (%s)\n",
4059     __inst_mod->mstnum - 1, __bld_lineloc(__xs, stp->stfnam_ind,
4060     stp->stlin_cnt), __inst_mod->msym->synam, __to_sttyp(__xs2, styp));
4061   }
4062  --- */
4063  /* ALTERNATE DBG remove --
4064  if (__debug_flg)
4065   {
4066    extern char *__to_sttyp(char *, unsigned);
4067 
4068    __dbg_msg("AT %s %s - STMT ALLOC %04d (%s)\n",
4069     __bld_lineloc(__xs, stp->stfnam_ind, stp->stlin_cnt),
4070     __inst_mod->msym->synam, __inst_mod->mstnum - 1, __to_sttyp(__xs2, styp));
4071   }
4072  --- */
4073 
4074  switch ((byte) styp) {
4075   /* null just has type value and NULL pointer */
4076   case S_NULL: case S_STNONE: break;
4077   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA: case S_NBPROCA:
4078    stp->st.spra.lhsx = NULL;
4079    stp->st.spra.rhsx = NULL;
4080    break;
4081   case S_IF:
4082    stp->st.sif.condx = NULL;
4083    stp->st.sif.thenst = NULL;
4084    stp->st.sif.elsest = NULL;
4085    break;
4086   case S_CASE:
4087    stp->st.scs.castyp = UNDEF;
4088    stp->st.scs.maxselwid = 0;
4089    stp->st.scs.csx = NULL;
4090    stp->st.scs.csitems = NULL;
4091    break;
4092   case S_REPEAT:
4093    stp->st.srpt.repx = NULL;
4094    stp->st.srpt.reptemp = NULL;
4095    stp->st.srpt.repst = NULL;
4096    break;
4097   case S_FOREVER:
4098   case S_WHILE:
4099    stp->st.swh.lpx = NULL;
4100    stp->st.swh.lpst = NULL;
4101    break;
4102   case S_WAIT:
4103    stp->st.swait.lpx = NULL;
4104    stp->st.swait.lpst = NULL;
4105    stp->st.swait.wait_dctp = __alloc_dctrl();
4106    break;
4107   case S_FOR:
4108    frp = (struct for_t *) __my_malloc(sizeof(struct for_t));
4109    stp->st.sfor = frp;
4110    frp->forassgn = NULL;
4111    frp->fortermx = NULL;
4112    frp->forinc = NULL;
4113    frp->forbody = NULL;
4114    break;
4115   case S_DELCTRL:
4116    stp->st.sdc = __alloc_dctrl();
4117    break;
4118   case S_NAMBLK:
4119    stp->st.snbtsk = NULL;
4120    break;
4121   case S_UNBLK:
4122    stp->st.sbsts = NULL;
4123    break;
4124   case S_UNFJ:
4125    stp->st.fj.fjstps = NULL;
4126    stp->st.fj.fjlabs = NULL;
4127    break;
4128   case S_TSKCALL:
4129    stp->st.stkc.targs = NULL;
4130    stp->st.stkc.tsksyx = NULL;
4131    stp->st.stkc.tkcaux.trec = NULL;
4132    break;
4133   case S_QCONTA:
4134    /* SJM 06/23/02 - since pre-building dce for qcaf need more fields */
4135    qcafs = (struct qconta_t *) __my_malloc(sizeof(struct qconta_t));
4136    stp->st.sqca = qcafs;
4137    qcafs->qcatyp = UNDEF;
4138    qcafs->regform = FALSE;
4139    qcafs->qclhsx = NULL;
4140    qcafs->qcrhsx = NULL;
4141    qcafs->rhs_qcdlstlst = NULL;
4142    break;
4143   case S_QCONTDEA:
4144    stp->st.sqcdea.qcdatyp = UNDEF;
4145    stp->st.sqcdea.qcdalhs = NULL;
4146    break;
4147   case S_CAUSE:
4148    stp->st.scausx = NULL;
4149    break;
4150   case S_DSABLE:
4151    stp->st.sdsable.dsablx = NULL;
4152    stp->st.sdsable.func_nxtstp = NULL;
4153    break;
4154   /* statement added for execution */
4155   case S_REPSETUP:
4156    /* union field unused */
4157    stp->st.scausx = NULL;
4158    break;
4159   case S_REPDCSETUP:
4160    /* union field unused */
4161    stp->st.scausx = NULL;
4162    break;
4163   case S_GOTO:
4164    stp->st.sgoto = NULL;
4165    break;
4166   default: __case_terr(__FILE__, __LINE__);
4167   }
4168  return(stp);
4169 }
4170 
4171 /*
4172  * initialize stmt
4173  */
__init_stmt(struct st_t * stp,int32 styp)4174 extern void __init_stmt(struct st_t *stp, int32 styp)
4175 {
4176  stp->stlin_cnt = __lin_cnt;
4177  stp->stfnam_ind = __cur_fnam_ind;
4178  stp->stmttyp = styp;
4179  stp->st_unbhead = FALSE;
4180  /* notice this always has the statement type even if break point not set */
4181  stp->rl_stmttyp = styp;
4182  stp->strb_seen_now = FALSE;
4183  stp->lpend_goto = FALSE;
4184  stp->dctrl_goto = FALSE;
4185  stp->lstend_goto = FALSE;
4186  stp->st_schd_ent = FALSE;
4187  stp->lpend_goto_dest = FALSE;
4188  /* assume if non blocking need the sched tev table */
4189  stp->stnxt = NULL;
4190 }
4191 
4192 /*
4193  * allocate and initialize a delay control record
4194  */
__alloc_dctrl(void)4195 extern struct delctrl_t *__alloc_dctrl(void)
4196 {
4197  struct delctrl_t *dctp;
4198 
4199  dctp = (struct delctrl_t *) __my_malloc(sizeof(struct delctrl_t));
4200  dctp->dctyp = DC_NONE;
4201  dctp->dc_iact = FALSE;
4202  dctp->dc_delrep = DT_CMPLST;
4203  dctp->dc_nblking = FALSE;
4204  dctp->implicit_evxlst = FALSE;
4205  dctp->dc_du.pdels = NULL;
4206  dctp->repcntx = NULL;
4207  dctp->dceschd_tevs = NULL;
4208  dctp->actionst = NULL;
4209  /* this is allocated during prep - nil for now */
4210  dctp->dce_repcnts = NULL;
4211  return(dctp);
4212 }
4213 
4214 /*
4215  * variant of alloc stmt that takes "real" location as args
4216  */
__alloc2_stmt(int32 styp,int32 fnind,int32 lcnt)4217 extern struct st_t *__alloc2_stmt(int32 styp, int32 fnind, int32 lcnt)
4218 {
4219  int32 sav_fnami, sav_flini;
4220  struct st_t *stp;
4221 
4222  sav_fnami = __cur_fnam_ind;
4223  sav_flini = __lin_cnt;
4224  __cur_fnam_ind = fnind;
4225  __lin_cnt = lcnt;
4226 
4227  stp = __alloc_stmt(styp);
4228 
4229  __cur_fnam_ind = sav_fnami;
4230  __lin_cnt = sav_flini;
4231  return(stp);
4232 }
4233 
4234 /*
4235  * DEFPARAM READING ROUTINES
4236  */
4237 
4238 /*
4239  * read the parameter defparam statement
4240  * assigns values to this or other params
4241  * form: defparam [hieriarch path or id] = [param. value expr.], ... ;
4242  *
4243  * if returns F synced to next mod/prim else synced to ;
4244  * list of assignments allowed here
4245  */
rd_dfparam_stmt(void)4246 static int32 rd_dfparam_stmt(void)
4247 {
4248  struct dfparam_t *dfpp;
4249  struct expr_t *lhsndp;
4250 
4251  for (;;)
4252   {
4253    __get_vtok();
4254    /* notice only for lhs not right */
4255    if (!__col_lval())
4256     {
4257      /* part of lhs may have been built */
4258      if (!__vskipto3_any(EQ, COMMA, SEMI)) return(FALSE);
4259      if (__toktyp == EQ) goto do_rhs;
4260      if (__toktyp == COMMA) continue;
4261      return(TRUE);
4262     }
4263 do_rhs:
4264    __bld_xtree(0);
4265    lhsndp = __root_ndp;
4266    if (lhsndp->optyp != ID && lhsndp->optyp != GLBREF)
4267     {
4268      __pv_ferr(1034, "defparam lvalue %s not identifier or hierarchical path",
4269       __msgexpr_tostr(__xs, lhsndp));
4270     }
4271    /* know = read */
4272    __get_vtok();
4273    if (!__col_comsemi(-1))
4274     {
4275 err_cont:
4276      if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
4277      if (__toktyp == COMMA) continue;
4278      return(TRUE);
4279     }
4280    __bld_xtree(0);
4281 
4282    /* checking rhs does no evaluation but set sizes and checks for only */
4283    /* numbers and previously defined in source order parameters */
4284    /* defparam rhs params must be defined previously in module */
4285    /* notice must be converted to number immediately else can have */
4286    /* circular dependency */
4287    /* LRM requires source order definition before use */
4288    /* SJM 08/07/96 */
4289    if (__expr_has_glb(__root_ndp) || !__src_rd_chk_paramexpr(__root_ndp, 0))
4290     {
4291      __pv_ferr(1025,
4292       "defparam right hand side \"%s\" illegal - parameters and constants only",
4293       __msgexpr_tostr(__xs, __root_ndp));
4294      /* need to still add value of x to prevent further errors */
4295      __free2_xtree(__root_ndp);
4296      __root_ndp->szu.xclen = WBITS;
4297      __set_numval(__root_ndp, ALL1W, ALL1W, WBITS);
4298     }
4299    /* SJM 01/27/04 - must leave as rhs expr since just gets evaled */
4300    /* bug if convert when downward propagation of defparams used on rhs */
4301    /* of other defparams used */
4302 
4303    /* notice cannot check rhs here since defparam statement rhs can be */
4304    /* any local parameter(possibly defined later in source) from LRM */
4305    dfpp = alloc_dfpval();
4306    dfpp->dfpxlhs = lhsndp;
4307    dfpp->dfpxrhs = __root_ndp;
4308    dfpp->in_mdp = __inst_mod;
4309 
4310    /* must always put on end of list - order important */
4311    /* since reading in source order list stays in source order */
4312    /* within each module */
4313    if (__end_dfp == NULL) __inst_mod->mdfps = dfpp;
4314    else __end_dfp->dfpnxt = dfpp;
4315    __end_dfp = dfpp;
4316 
4317    /* can be comma separated assignment list */
4318    if (__toktyp == SEMI) break;
4319    if (__toktyp != COMMA)
4320     {
4321      __pv_ferr(1039,
4322       "defparam semicolon or comma separator expected - %s read",
4323       __prt_vtok());
4324      goto err_cont;
4325     }
4326   }
4327  return(TRUE);
4328 }
4329 
4330 /*
4331  * allocate a module defparam structure for later processing
4332  */
alloc_dfpval(void)4333 static struct dfparam_t *alloc_dfpval(void)
4334 {
4335  struct dfparam_t *dfpp;
4336 
4337  dfpp = (struct dfparam_t *) __my_malloc(sizeof(struct dfparam_t));
4338  dfpp->dfpxlhs = NULL;
4339  dfpp->dfpxrhs = NULL;
4340  dfpp->in_mdp = NULL;
4341  dfpp->dfpfnam_ind = __cur_fnam_ind;
4342  dfpp->dfplin_cnt = __lin_cnt;
4343  dfpp->dfp_local = FALSE;
4344  dfpp->dfp_rooted = FALSE;
4345  dfpp->dfp_done = FALSE;
4346  dfpp->dfp_mustsplit = FALSE;
4347  dfpp->dfp_has_idents = FALSE;
4348  dfpp->dfp_checked = FALSE;
4349  dfpp->dfpnxt = NULL;
4350 
4351  dfpp->dfpiis = NULL;
4352  dfpp->last_dfpi = -1;
4353  dfpp->gdfpnam = NULL;
4354  dfpp->targsyp = NULL;
4355  dfpp->idntmastdfp = NULL;
4356  dfpp->idntnxt = NULL;
4357  dfpp->rooted_dfps = NULL;
4358  dfpp->dfptskp = NULL;
4359  return(dfpp);
4360 }
4361 
4362 /*
4363  * TASK DEFINITION ROUTINES
4364  * here because uses common declaration code
4365  */
4366 
4367 /*
4368  * process a task definition
4369  * know task or function keyword read, reads the endtask
4370  * no F return on error, since either build d.s. or not
4371  */
rd_task(void)4372 static int32 rd_task(void)
4373 {
4374  struct st_t *stp;
4375 
4376  __lofp_port_decls = FALSE;
4377  __get_vtok();
4378  if (__toktyp != ID)
4379   {
4380    __pv_ferr(1130, "task name expected - %s read", __prt_kywrd_vtok());
4381 sync_to_endtask:
4382    /* could change to dummy tsk name and continue here */
4383    /* but for now must find ENDTASK or skip to module level item */
4384    if (__vskipto_modend(ENDTASK)) return(TRUE);
4385    __syncto_class = SYNC_FLEVEL;
4386    return(FALSE);
4387   }
4388  /* FALSE means previously defined - must not read */
4389  if (!__bld_tsk(__token, TASK)) goto sync_to_endtask;
4390 
4391  __get_vtok();
4392  if (__toktyp == LPAR)
4393   {
4394    /* if couldn't sync to end of list of tf decls list ); */
4395    if (!rd_tf_list_of_ports_decl(__cur_tsk, "task"))
4396     {
4397      switch ((byte) __syncto_class) {
4398       case SYNC_FLEVEL: case SYNC_MODLEVEL: return(FALSE);
4399       case SYNC_STMT: __get_vtok(); goto more_stmts;
4400       default: __case_terr(__FILE__, __LINE__);
4401      }
4402     }
4403    if (__toktyp == RPAR) __get_vtok();
4404   }
4405  if (__toktyp != SEMI)
4406   {
4407    __pv_ferr(1131,
4408     "task declaration name not followed by semicolon - %s read",
4409     __prt_vtok());
4410   }
4411  else __get_vtok();
4412 
4413  /* first decl. type token read */
4414  if (!__rd_tfdecls("task")) return(FALSE);
4415 more_stmts:
4416  if ((stp = __rd_stmt()) == NULL)
4417   {
4418    switch ((byte) __syncto_class) {
4419     case SYNC_FLEVEL: case SYNC_MODLEVEL: return(FALSE);
4420     case SYNC_STMT: __get_vtok(); goto more_stmts;
4421     case SYNC_TARG: break;
4422     default: __case_terr(__FILE__, __LINE__);
4423    }
4424   }
4425  /* only one task statement */
4426  __cur_tsk->tskst = stp;
4427  __get_vtok();
4428  if (__toktyp != ENDTASK)
4429   {
4430    __pv_ferr(1132, "endtask expected - %s read", __prt_vtok());
4431    /* must free task symbol table on error */
4432    if (__top_sti > 0) __top_sti = 0;
4433    /* this will sync to next module item if possible */
4434    return(__vskipto_any(ENDTASK));
4435   }
4436  __cur_tsk->tsk_last_lini = __lin_cnt;
4437  __cur_tsk->tsk_last_ifi = __cur_fnam_ind;
4438 
4439  __get_vtok();
4440  if (__toktyp == SEMI)
4441   __pv_ferr(999, "semicolon following endtask illegal");
4442  else __unget_vtok();
4443  /* if error will not get linked in to module's task list */
4444  if (__end_tbp == NULL) __inst_mod->mtasks = __cur_tsk;
4445  else __end_tbp->tsknxt = __cur_tsk;
4446  __end_tbp = __cur_tsk;
4447  /* symbols no longer accessible */
4448  __top_sti--;
4449  return(TRUE);
4450 }
4451 
4452 /*
4453  * build a task structure from declaration (label block/task/function)
4454  * expects task name and return task symbol - __cur_tsk set to inited task
4455  * notice that this does not link task into task chain
4456  */
__bld_tsk(char * tnam,int32 tsktok)4457 extern int32 __bld_tsk(char *tnam, int32 tsktok)
4458 {
4459  int32 tstyp;
4460  struct symtab_t *upsyt;
4461  struct sy_t *syp;
4462  char s1[RECLEN], s2[RECLEN];
4463 
4464  if (*tnam == '$')
4465   {
4466    __pv_ferr(1133, "system function or task %s cannot be redefined", tnam);
4467    return(FALSE);
4468   }
4469  tstyp = to_tasksytyp(tsktok);
4470 
4471  /* must be find sym since if redefines something higher error */
4472  syp = __find_sym(tnam);
4473  if (!__sym_is_new)
4474   {
4475    /* if disable caused decl. as task, change to named block */
4476    if (syp->sytyp == SYM_TSK && tstyp == SYM_LB) syp->sytyp = SYM_LB;
4477    if (syp->sydecl || syp->sytyp != tstyp)
4478     {
4479      __pv_ferr(1134,
4480      "%s definition of \"%s\" illegal - previously defined as %s at %s",
4481       __get_vkeynam(s1, tsktok), __token, __to_sytyp(s2, syp->sytyp),
4482       __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
4483      return(FALSE);
4484     }
4485   }
4486  /* possibilities include named block fork and join */
4487  syp->sytyp = tstyp;
4488  __cur_tsk = __alloc_task(syp);
4489  /* all different task types still point to etskp element */
4490  syp->el.etskp = __cur_tsk;
4491  syp->sydecl = TRUE;
4492  syp->syfnam_ind = __cur_fnam_ind;
4493  syp->sylin_cnt = __lin_cnt;
4494 
4495  /* must also allocate the new symbol table */
4496  __cur_tsk->tsksymtab = __alloc_symtab(TRUE);
4497  __cur_tsk->tsktyp = tsktok;
4498  /* link symbol table to object it is symbol of */
4499  __cur_tsk->tsksymtab->sypofsyt = syp;
4500  /* set list ends for elements that must be kept in order */
4501  __end_tpp = NULL;
4502  __end_tskparamnp = NULL;
4503  __end_tsk_loc_paramnp = NULL;
4504  __venviron[++__top_sti] = __cur_tsk->tsksymtab;
4505 
4506  /* link in symbol table structure */
4507  upsyt = __venviron[__top_sti - 1];
4508  __cur_tsk->tsksymtab->sytpar = upsyt;
4509  if (upsyt->sytofs == NULL) upsyt->sytofs = __cur_tsk->tsksymtab;
4510  /* link on front */
4511  else
4512   {
4513    __cur_tsk->tsksymtab->sytsib = upsyt->sytofs;
4514    upsyt->sytofs = __cur_tsk->tsksymtab;
4515   }
4516  return(TRUE);
4517 }
4518 
4519 /*
4520  * convert one of the task token types to corresponding symbol type
4521  */
to_tasksytyp(int32 ttyp)4522 static word32 to_tasksytyp(int32 ttyp)
4523 {
4524  int32 styp;
4525 
4526  styp = SYM_UNKN;
4527  switch ((byte) ttyp) {
4528   case TASK: styp = SYM_TSK; break;
4529   case FUNCTION: styp = SYM_F; break;
4530   case FORK: case Begin: styp = SYM_LB; break;
4531   default: __case_terr(__FILE__, __LINE__);
4532  }
4533  return(styp);
4534 }
4535 
4536 /*
4537  * allocate a new task
4538  */
__alloc_task(struct sy_t * syp)4539 extern struct task_t *__alloc_task(struct sy_t *syp)
4540 {
4541  struct task_t *tskp;
4542 
4543  tskp = (struct task_t *) __my_malloc(sizeof(struct task_t));
4544  init_task(tskp);
4545  tskp->tsksyp = syp;
4546  return(tskp);
4547 }
4548 
4549 /*
4550  * initialize a task
4551  */
init_task(struct task_t * tskp)4552 static void init_task(struct task_t *tskp)
4553 {
4554  tskp->tsksyp = NULL;
4555  tskp->tsk_last_lini = -1;
4556  tskp->tsk_last_ifi = -1;
4557  tskp->tsktyp = UNDEF;
4558  tskp->t_used = FALSE;
4559  tskp->thas_outs = FALSE;
4560  tskp->thas_tskcall = FALSE;
4561  tskp->fhas_fcall = FALSE;
4562  tskp->tf_lofp_decl = FALSE;
4563  tskp->tsksymtab = NULL;
4564  tskp->st_namblkin = NULL;
4565  tskp->tskpins = NULL;
4566  tskp->tsk_prms = NULL;
4567  tskp->tsk_locprms = NULL;
4568  tskp->tprmnum = 0;
4569  tskp->tsk_regs = NULL;
4570  tskp->trnum = 0;
4571  tskp->tlocprmnum = 0;
4572  tskp->tskst = NULL;
4573  tskp->tsknxt = NULL;
4574  tskp->tthrds = NULL;
4575 }
4576 
4577 /*
4578  * ROUTINES TO READ AND ADD LIST OF PORTS STYLE TASK/FUNC HEADER PORT DECLS
4579  */
4580 
4581 /*
4582  * read list of task/func header port declarations
4583  * new alternative ANSII style port header decl form added to 2001 LRM
4584  *
4585  * initial ( read and reads ending );
4586  * think now () form legal
4587  *
4588  * if return T, even if error parsing can continue in module
4589  * on error must sync to end of tf list of decls ')' - if not returns F
4590  * and sets sync class to right place to continue in t/f
4591  * may also sync to ; on error with T return
4592  */
rd_tf_list_of_ports_decl(struct task_t * tskp,char * tftypnam)4593 static int32 rd_tf_list_of_ports_decl(struct task_t *tskp, char *tftypnam)
4594 {
4595  int32 first_time, wtyp, ptyp, attr_ttyp, has_attr, decl_signed;
4596  struct sy_t *syp;
4597  struct net_t *np;
4598  struct expr_t *x1, *x2, *ox1, *ox2;
4599  struct task_pin_t *tpp;
4600  char s1[RECLEN];
4601 
4602  ptyp = -1;
4603  /* even if syntax error, T once a port type keyword appears in hdr */
4604  tskp->tf_lofp_decl = TRUE;
4605  __lofp_port_decls = TRUE;
4606 
4607  __get_vtok();
4608  for (;;)
4609   {
4610    if (__toktyp == RPAR)
4611     {
4612      __pv_fwarn(3136,
4613       "%s %s header list of ports decl form - but list of ports empty",
4614       tftypnam, tskp->tsksyp->synam);
4615      /* assuming this forces list of ports header form */
4616      return(TRUE);
4617     }
4618 
4619    if (__toktyp != INPUT && __toktyp != OUTPUT && __toktyp != INOUT)
4620     {
4621      __pv_ferr(3422, "%s list of ports form port direction expected - %s read",
4622       tftypnam, __prt_kywrd_vtok());
4623      if (!__vskipto_lofp_end()) return(FALSE);
4624      return(TRUE);
4625     }
4626 
4627    /* attribute collected by scanner - but need to save so associates with */
4628    /* right port */
4629    if (__attr_prefix)
4630     {
4631      __wrk_attr.attr_tok = __toktyp;
4632      __wrk_attr.attr_seen = TRUE;
4633      /* for now this is unparsed entire attr. string */
4634      __wrk_attr.attrnam = __pv_stralloc(__attrwrkstr);
4635      __wrk_attr.attr_fnind = __attr_fnam_ind;
4636      __wrk_attr.attrlin_cnt = __attr_lin_cnt;
4637     }
4638    else __wrk_attr.attr_seen = FALSE;
4639 
4640    attr_ttyp = __toktyp;
4641    if (__toktyp == INPUT) ptyp = IO_IN;
4642    else if (__toktyp == OUTPUT) ptyp = IO_OUT;
4643    else if (__toktyp == INOUT) ptyp = IO_BID;
4644    else __case_terr(__FILE__, __LINE__);
4645 
4646    __get_vtok();
4647 
4648    /* defaults to reg if net type omitted - can be var/reg type */
4649    if ((wtyp = __fr_wtnam(__toktyp)) != -1) __get_vtok();
4650    else wtyp = N_REG;
4651 
4652    if (wtyp == N_INT || wtyp == N_REAL) decl_signed = TRUE;
4653    else decl_signed = FALSE;
4654    /* vectored or scalared keywords never appear in port decls */
4655 
4656    if (__toktyp == SIGNED)
4657     {
4658      decl_signed = TRUE;
4659      if (wtyp == N_TIME || wtyp == N_INT || wtyp == N_REAL
4660       || wtyp == N_EVENT)
4661       {
4662        __pv_ferr(3423,
4663         "signed keyword illegal when task or function variable has type %s",
4664         __to_wtnam2(s1, wtyp));
4665       }
4666      __get_vtok();
4667     }
4668 
4669    /* even if error if 1 past ending ] continue */
4670    if (!__rd_decl_rng(&ox1, &ox2))
4671     {
4672      /* bad decl - but if sync to new I/O port direction, caller will cont */
4673      if (!__vskipto_lofp_end()) return(FALSE);
4674      if (__toktyp == RPAR) return(TRUE);
4675      /* semi read */
4676      return(TRUE);
4677     }
4678 
4679    /* use local has attr flag so can turn glb seen off before return */
4680    if (__wrk_attr.attr_seen)
4681     { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
4682    else has_attr = FALSE;
4683 
4684    x1 = x2 = NULL;
4685    for (first_time = TRUE;;)
4686     {
4687      if (__toktyp != ID)
4688       {
4689        __pv_ferr(992,
4690         "%s header list of port form %s port name expected - %s read",
4691         tftypnam, __to_ptnam(s1, ptyp), __prt_kywrd_vtok());
4692 
4693        if (__vskipto2_lofp_end())
4694         {
4695          if (__toktyp == SEMI) return(TRUE);
4696          if (__toktyp == RPAR) { __get_vtok(); return(TRUE); }
4697          /* only other possibility is the port name separating comma */
4698          continue;
4699         }
4700        /* can't recover (resync) from error - synced to module item */
4701        return(FALSE);
4702       }
4703 
4704      /* SJM 05/25/04 - must just search for redeclare in tf sym tab */
4705      if ((syp = __get_sym(__token, __venviron[__top_sti])) != NULL)
4706       {
4707        __pv_ferr(3418,
4708         "%s header list of ports form %s port name %s redeclared",
4709         tftypnam, __to_ptnam(s1, ptyp), __token);
4710        goto nxt_port;
4711       }
4712 
4713      if (first_time) { x1 = ox1; x2 = ox2; first_time = FALSE; }
4714      else
4715       {
4716        if (x1 == NULL) x1 = x2 = NULL;
4717        else { x1 = __copy_expr(ox1); x2 = __copy_expr(ox2); }
4718       }
4719 
4720      /* first declare the port's wire/reg */
4721      if ((np = decl_taskvar(wtyp, x1, x2)) == NULL) goto nxt_port;
4722 
4723      /* if previously used will be treated as reg - must set to compatible */
4724      /* wire type if declared as time or int32 */
4725      syp = np->nsym;
4726 
4727      /* if saw an (* *) attribute for module item token, seen on */
4728      if (has_attr)
4729       {
4730        /* this add to net's attr list on end if also net decl first */
4731        add_net_attr(np, attr_ttyp);
4732       }
4733 
4734      /* SJM 10/02/03 - signed can be turned on either in port or wire decl */
4735      if (decl_signed) np->n_signed = TRUE;
4736      np->iotyp = ptyp;
4737 
4738      /* alloc port and add to end of list - order here crucial */
4739      tpp = alloc_tskpin();
4740      tpp->tpsy = syp;
4741      tpp->trtyp = ptyp;
4742 
4743      /* although with hdr list of ports form list known, for other form */
4744      /* don't know task/func ports until end of task/func */
4745      if (__end_tpp == NULL) __cur_tsk->tskpins = tpp;
4746      else __end_tpp->tpnxt = tpp;
4747      __end_tpp = tpp;
4748 
4749 nxt_port:
4750      __get_vtok();
4751      if (__toktyp == RPAR) return(TRUE);
4752 
4753      if (__toktyp != COMMA)
4754       {
4755        __pv_ferr(995,
4756         "%s list of ports form declaration list comma or right paren expected - %s read",
4757         tftypnam, __prt_vtok());
4758        /* try to resync */
4759        if (!__vskipto_lofp_end()) return(FALSE);
4760        if (__toktyp == COMMA) goto nxt_var;
4761        /* misplaced semi or sync to rpar */
4762        return(TRUE);
4763       }
4764 nxt_var:
4765      __get_vtok();
4766      if (__toktyp == INPUT || __toktyp == OUTPUT || __toktyp == INOUT)
4767       break;
4768     }
4769   }
4770  __misc_terr(__FILE__, __LINE__);
4771  return(TRUE);
4772 }
4773 
4774 /*
4775  * read task declarations
4776  * notice in any kind of task, function, or named block, decls come first
4777  * with one statement at end
4778  * expects first token to have been read and reads start of 1st statement
4779  */
__rd_tfdecls(char * tftypnam)4780 extern int32 __rd_tfdecls(char *tftypnam)
4781 {
4782  word32 wtyp, pntyp;
4783 
4784  for (;;)
4785   {
4786    /* routines called in switch expected to read ending ; or token */
4787    switch((byte) __toktyp) {
4788     case TEOF:
4789      __pv_ferr(1135, "%s unexpected EOF", tftypnam);
4790      return(FALSE);
4791     case PARAMETER:
4792     case LOCALPARAM:
4793      /* this add to symbol table and list */
4794      /* notice for these, if error but synced to ;, still returns T */
4795      if (!rd_paramdecl(FALSE, (__toktyp == LOCALPARAM)))
4796       {
4797 tfdecl_sync:
4798        switch ((byte) __syncto_class) {
4799         case SYNC_FLEVEL: return(FALSE);
4800         case SYNC_MODLEVEL: break;
4801         /* statement follows task decls */
4802         case SYNC_STMT: return(TRUE);
4803         case SYNC_TARG: break;
4804         default: __case_terr(__FILE__, __LINE__);
4805        }
4806       }
4807      break;
4808     case INOUT:
4809      pntyp = IO_BID;
4810      goto decl_port;
4811     case OUTPUT:
4812      pntyp = IO_OUT;
4813      goto decl_port;
4814     case INPUT:
4815      pntyp = IO_IN;
4816 decl_port:
4817      if (!rd_taskvardecl(pntyp, TRUE, tftypnam)) goto tfdecl_sync;
4818      break;
4819     case REG:
4820      wtyp = N_REG;
4821 do_tfwdecl:
4822      if (!rd_taskvardecl(wtyp, FALSE, tftypnam)) goto tfdecl_sync;
4823      break;
4824     case TIME: wtyp = N_TIME; goto do_tfwdecl;
4825     case INTEGER: wtyp = N_INT; goto do_tfwdecl;
4826     case REAL: case REALTIME: wtyp = N_REAL; goto do_tfwdecl;
4827     case EVENT:
4828      if (!rd_eventdecl(TRUE)) goto tfdecl_sync;
4829      break;
4830     default:
4831      /* assume start of statement */
4832      goto decl_end;
4833    }
4834    __get_vtok();
4835   }
4836 decl_end:
4837  return(TRUE);
4838 }
4839 
4840 /*
4841  * read and process a task reg/time/int/real declaration
4842  * know reg type read and reads final semi
4843  */
rd_taskvardecl(word32 regwtyp,int32 is_io,char * tftypnam)4844 static int32 rd_taskvardecl(word32 regwtyp, int32 is_io, char *tftypnam)
4845 {
4846  int32 decl_signed, first_time, ttyp, has_attr;
4847  word32 wtyp;
4848  struct sy_t *syp;
4849  struct net_t *np;
4850  struct task_pin_t *tpp;
4851  struct expr_t *x1, *x2, *ox1, *ox2, *xa1, *xa2;
4852  char s1[RECLEN], s2[RECLEN];
4853 
4854  ttyp = __toktyp;
4855  if (is_io) wtyp = N_REG; else wtyp = regwtyp;
4856  /* SJM 10/02/03 - need sign bit for reals even though always signed */
4857  if (wtyp == N_INT || wtyp == N_REAL) decl_signed = TRUE;
4858  else decl_signed = FALSE;
4859  __get_vtok();
4860 
4861  if (__toktyp == SIGNED)
4862   {
4863    decl_signed = TRUE;
4864    if (wtyp == N_TIME || wtyp == N_INT || wtyp == N_REAL || wtyp == N_EVENT)
4865     {
4866      __pv_ferr(3423,
4867       "signed keyword illegal when task or function variable type %s",
4868       __to_wtnam2(s1, wtyp));
4869     }
4870    __get_vtok();
4871   }
4872 
4873  if (!__rd_decl_rng(&ox1, &ox2))
4874   {
4875    if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
4876    if (__toktyp == SEMI) return(TRUE);
4877    __get_vtok();
4878   }
4879  if (ox1 != NULL)
4880   {
4881    if (wtyp == N_INT || wtyp == N_TIME || wtyp == N_REAL
4882     || wtyp == N_EVENT)
4883     {
4884      __pv_ferr(1142, "%s %s %s vector range illegal", tftypnam,
4885       __to_wtnam2(s1, wtyp), __token);
4886      x1 = x2 = NULL;
4887     }
4888   }
4889  /* use local has attr flag so can turn glb seen of before return */
4890  if (__wrk_attr.attr_seen) { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
4891  else has_attr = FALSE;
4892  for (first_time = TRUE;;)
4893   {
4894    if (__toktyp != ID)
4895     {
4896      __pv_ferr(1140, "%s declaration name of reg expected - %s read",
4897       tftypnam, __prt_kywrd_vtok());
4898 bad_end:
4899      return(__vskipto_any(SEMI));
4900     }
4901 
4902    /* any port decl illegal - new ones or re-decls */
4903    if (__lofp_port_decls)
4904     {
4905      if (is_io)
4906       {
4907        __pv_ferr(3421,
4908        "port declaration of \"%s\" illegal - list of ports declaration form used",
4909        __prt_kywrd_vtok());
4910        /* if I/O decl, know read entire decl, i.e. can't be array */
4911        goto nxt_var;
4912       }
4913      else
4914       {
4915        if (((syp = __get_sym_env(__token)) != NULL) && syp->sytyp == SYM_N
4916         && syp->el.enp->iotyp != NON_IO)
4917         {
4918          __pv_ferr(3421,
4919           "%s declaration of port \"%s\" illegal - %s uses list of ports declarations form",
4920           __to_wtnam2(s1, wtyp), __prt_kywrd_vtok(), tftypnam);
4921 
4922          /* here may need to skip the possible array decl */
4923          if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
4924          if (__toktyp == SEMI) return(TRUE);
4925          goto nxt_var;
4926         }
4927       }
4928     }
4929 
4930    /* each time through need to call this to make copy */
4931    if (ox1 == NULL) set_reg_widths(wtyp, &x1, &x2);
4932    else if (first_time) { x1 = ox1; x2 = ox2; first_time = FALSE; }
4933    else { x1 = __copy_expr(ox1); x2 = __copy_expr(ox2); }
4934 
4935    /* this handles all normal wire setting and checking */
4936    if ((np = decl_taskvar(wtyp, x1, x2)) == NULL)
4937     {
4938      /* if no np, cannot read possible declaration - must skip over it */
4939      if (__toktyp == LSB)
4940       {
4941        if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
4942        if (__toktyp == SEMI) return(TRUE);
4943        __get_vtok();
4944       }
4945      goto nxt_var;
4946     }
4947    syp = np->nsym;
4948 
4949    /* SJM - 03/20/00 - save reg decl attrs */
4950    /* if saw an (* *) attribute for module item token, seen on */
4951    if (has_attr) add_net_attr(np, ttyp);
4952 
4953    __get_vtok();
4954    /* notice task/function ports do not allow array syntax */
4955    /* also notice no strength or wire delay syntax */
4956    if (is_io) xa1 = xa2 = NULL;
4957    else
4958     {
4959      if (!__rd_decl_rng(&xa1, &xa2))
4960       {
4961        if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
4962        if (__toktyp == SEMI) return(TRUE);
4963        __get_vtok();
4964       }
4965      if (xa1 != NULL && wtyp == N_EVENT)
4966       {
4967        __pv_ferr(1143, "%s %s %s cannot be a array", tftypnam,
4968         __to_wtnam2(s1, wtyp), syp->synam);
4969        xa1 = xa2 = NULL;
4970       }
4971     }
4972    if (xa1 != NULL)
4973     { np->n_isarr = TRUE; np->nu.ct->ax1 = xa1; np->nu.ct->ax2 = xa2; }
4974    if (decl_signed) np->n_signed = TRUE;
4975 
4976    if (is_io)
4977     {
4978      /* check for repeated I/O decls - wrong */
4979      if (np->iotyp != NON_IO)
4980       {
4981        if (np->iotyp == regwtyp)
4982         {
4983          __pv_fwarn(574, "%s %s port declaration of \"%s\" repeated",
4984 	  tftypnam, __to_ptnam(s1, regwtyp), syp->synam);
4985 	}
4986        else
4987         {
4988          __pv_ferr(1144, "%s %s port %s previously declared as %s port",
4989           tftypnam, __to_ptnam(s1, regwtyp), syp->synam,
4990           __to_ptnam(s2, np->iotyp));
4991 	 goto nxt_var;
4992         }
4993       }
4994      np->iotyp = regwtyp;
4995      /* alloc port and add to end of list - order here crucial */
4996      tpp = alloc_tskpin();
4997      tpp->tpsy = syp;
4998      tpp->trtyp = regwtyp;
4999      if (__end_tpp == NULL) __cur_tsk->tskpins = tpp;
5000      else __end_tpp->tpnxt = tpp;
5001      __end_tpp = tpp;
5002     }
5003 
5004 nxt_var:
5005    if (__toktyp == SEMI) break;
5006    if (__toktyp != COMMA)
5007     {
5008      __pv_ferr(1145,
5009       "%s reg declaration list comma or semicolon expected - %s read",
5010       tftypnam, __prt_vtok());
5011      goto bad_end;
5012     }
5013    __get_vtok();
5014   }
5015  return(TRUE);
5016 }
5017 
5018 /*
5019  * add the task variable type decl. symbol and associated reg
5020  * caller must set reg type after checking for duplicates
5021  * returns null on error
5022  */
decl_taskvar(word32 wtyp,struct expr_t * x1,struct expr_t * x2)5023 static struct net_t *decl_taskvar(word32 wtyp, struct expr_t *x1,
5024  struct expr_t *x2)
5025 {
5026  struct net_t *np;
5027  struct sy_t *syp;
5028  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
5029 
5030  syp = __decl_sym(__token, __venviron[__top_sti]);
5031  if (__sym_is_new)
5032   {
5033    np = __add_net(syp);
5034    np->iotyp = NON_IO;
5035    if (x1 != NULL)
5036     {
5037      np->nu.ct->n_rngknown = TRUE;
5038      np->n_isavec = TRUE;
5039      np->nu.ct->nx1 = x1;
5040      np->nu.ct->nx2 = x2;
5041     }
5042    np->ntyp = wtyp;
5043    syp->sydecl = TRUE;
5044    /* even if used before, must set to declaration place */
5045    syp->syfnam_ind = __cur_fnam_ind;
5046    syp->sylin_cnt = __lin_cnt;
5047   }
5048  else
5049   {
5050    if (syp->sytyp != SYM_N)
5051     {
5052      __pv_ferr(1028,
5053       "cannot declare %s as %s - previously declared as %s at %s",
5054       syp->synam, __to_wtnam2(s2, wtyp), __to_wtnam2(s1, syp->sytyp),
5055       __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
5056      return(NULL);
5057     }
5058    /* wire/reg decl. after I/O decl. may set range */
5059    np = syp->el.enp;
5060    /* need special handling for I/O ports - declared in header, */
5061    /* I/O direction and maybe wire */
5062    if (np->iotyp != NON_IO)
5063     {
5064      /* task vars can be anthing providing output is lhs */
5065      /* this only has meaning for I/O port redecls */
5066      if (np->nu.ct->n_wirtypknown)
5067       {
5068        __pv_ferr(1146, "%s port %s previously declared as %s cannot be %s",
5069 	__to_ptnam(s1, np->iotyp), syp->synam, __to_wtnam(s2, np),
5070 	__to_wtnam2(s3, wtyp));
5071        /* must cause skipping because no np */
5072        return(NULL);
5073       }
5074     }
5075    else { if (is_decl_err(syp, SYM_N, wtyp)) return(NULL); }
5076    np->ntyp = wtyp;
5077    if (!chkset_wdrng(np, x1, x2)) return(NULL);
5078    np->nu.ct->n_wirtypknown = TRUE;
5079 
5080    /* if I/O decl follows reg decl, symbol uses I/O decl. place */
5081    if (np->iotyp != NON_IO)
5082     {
5083      syp->sydecl = TRUE;
5084      /* even if used before, must set to declaration place */
5085      syp->syfnam_ind = __cur_fnam_ind;
5086      syp->sylin_cnt = __lin_cnt;
5087     }
5088   }
5089  return(np);
5090 }
5091 
5092 /*
5093  * allocate a task pin (port) list element
5094  */
alloc_tskpin(void)5095 static struct task_pin_t *alloc_tskpin(void)
5096 {
5097  struct task_pin_t *tpp;
5098 
5099  tpp = (struct task_pin_t *) __my_malloc(sizeof(struct task_pin_t));
5100  tpp->tpsy = NULL;
5101  tpp->trtyp = NON_IO;
5102  tpp->tpnxt = NULL;
5103  return(tpp);
5104 }
5105 
5106 /*
5107  * process a function definition
5108  * keyword function reads and reads decl. and final endfunction
5109  * no F return on error since either build d.s. or not
5110  */
rd_func(void)5111 static int32 rd_func(void)
5112 {
5113  int32 frwtyp, decl_signed;
5114  word32 rhigh;
5115  struct st_t *stp;
5116  struct expr_t *x1, *x2, *dx1, *dx2;
5117 
5118  __lofp_port_decls = FALSE;
5119  dx1 = dx2 = NULL;
5120  decl_signed = FALSE;
5121  __get_vtok();
5122  if (__toktyp == SIGNED)
5123   {
5124    decl_signed = TRUE;
5125    __get_vtok();
5126   }
5127 
5128  if (__toktyp == LSB)
5129   {
5130    if (!__rd_decl_rng(&dx1, &dx2))
5131     {
5132      if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
5133      if (__toktyp == SEMI) return(TRUE);
5134      __get_vtok();
5135     }
5136   }
5137  /* if not a wire - assume next token is func. name (if not error below) */
5138  /* this is 1 bit wire if not range */
5139  if ((frwtyp = __fr_wtnam(__toktyp)) == -1)
5140   { frwtyp = N_REG; x1 = dx1; x2 = dx2; }
5141  else
5142   {
5143    if (frwtyp == N_EVENT || frwtyp < NONWIRE_ST)
5144     {
5145      __pv_ferr(1141, "function cannot return type %s", __prt_vtok());
5146      frwtyp = N_REG;
5147      x1 = x2 = NULL;
5148      goto get_funcnam;
5149     }
5150   switch ((byte) frwtyp) {
5151    case N_REAL:
5152     rhigh = REALBITS - 1;
5153     goto chk_norng;
5154    case N_INT:
5155     rhigh = WBITS - 1;
5156 chk_norng:
5157     if (dx1 != NULL)
5158      {
5159       __pv_ferr(1149,
5160        "function returning %s range illegal", __to_wtnam2(__xs,
5161        (word32) frwtyp));
5162      }
5163     x1 = __bld_rng_numxpr(rhigh, 0L, WBITS);
5164     x2 = __bld_rng_numxpr(0L, 0L, WBITS);
5165     break;
5166    case N_TIME:
5167     rhigh = TIMEBITS - 1;
5168     goto chk_norng;
5169    default:
5170     __case_terr(__FILE__, __LINE__);
5171     return(FALSE);
5172   }
5173   __get_vtok();
5174  }
5175 
5176 get_funcnam:
5177  if (__toktyp != ID)
5178   {
5179    __pv_ferr(1148, "function name expected - %s read", __prt_kywrd_vtok());
5180 no_sym:
5181    if (__vskipto_modend(ENDFUNCTION)) return(TRUE);
5182    __syncto_class = SYNC_FLEVEL;
5183    return(FALSE);
5184   }
5185  if (!__bld_tsk(__token, FUNCTION)) goto no_sym;
5186 
5187  if (decl_signed && (frwtyp == N_TIME || frwtyp == N_INT || frwtyp == N_REAL))
5188   {
5189    __pv_ferr(3423,
5190     "signed keyword illegal when function declaration return type %s",
5191     __to_wtnam2(__xs, frwtyp));
5192   }
5193  if (frwtyp == N_INT || frwtyp == N_REAL) decl_signed = TRUE;
5194  add_funcretdecl(__token, (word32) frwtyp, x1, x2, decl_signed);
5195 
5196  __get_vtok();
5197  if (__toktyp == LPAR)
5198   {
5199    /* if couldn't sync to end of list of tf decls list ); */
5200    if (!rd_tf_list_of_ports_decl(__cur_tsk, "function"))
5201     {
5202      switch ((byte) __syncto_class) {
5203       case SYNC_FLEVEL: case SYNC_MODLEVEL: return(FALSE);
5204       case SYNC_STMT: __get_vtok(); goto more_stmts;
5205       default: __case_terr(__FILE__, __LINE__);
5206      }
5207     }
5208    if (__toktyp == RPAR) __get_vtok();
5209   }
5210 
5211  if (__toktyp != SEMI)
5212   {
5213    __pv_ferr(1153,
5214     "function declaration name not followed by semicolon - %s read",
5215     __prt_vtok());
5216   }
5217  else __get_vtok();
5218 
5219  if (!__rd_tfdecls("function")) return(FALSE);
5220 more_stmts:
5221  if ((stp = __rd_stmt()) == NULL)
5222   {
5223    /* only get here on error */
5224    if (__toktyp == ENDFUNCTION)
5225     {
5226      __get_vtok();
5227      if (__toktyp == SEMI)
5228       __pv_ferr(999, "semicolon following endfunction illegal");
5229      else __unget_vtok();
5230      return(TRUE);
5231     }
5232    switch ((byte) __syncto_class) {
5233     case SYNC_FLEVEL: case SYNC_MODLEVEL: return(FALSE);
5234     /* legally only 1 stmt - but try to parse all */
5235     case SYNC_STMT:
5236      __get_vtok();
5237      goto more_stmts;
5238     case SYNC_TARG: break;
5239     default: __case_terr(__FILE__, __LINE__);
5240    }
5241   }
5242  __cur_tsk->tskst = stp;
5243  __get_vtok();
5244  if (__toktyp != ENDFUNCTION)
5245   {
5246    __pv_ferr(1154, "endfunction expected - %s read", __prt_vtok());
5247    /* if missing endfunction, need to deallocate symbol table */
5248    if (__top_sti > 0) __top_sti = 0;
5249    return(__vskipto_any(ENDFUNCTION));
5250   }
5251  /* set line of end */
5252  __cur_tsk->tsk_last_lini = __lin_cnt;
5253  __cur_tsk->tsk_last_ifi = __cur_fnam_ind;
5254 
5255  /* if error will not get linked in to module's task list */
5256  /* notice functions get linked in task order on module task list */
5257  if (__end_tbp == NULL) __inst_mod->mtasks = __cur_tsk;
5258  else __end_tbp->tsknxt = __cur_tsk;
5259  __end_tbp = __cur_tsk;
5260  /* symbols no longer accessible */
5261  __top_sti--;
5262  return(TRUE);
5263 }
5264 
5265 /*
5266  * add implicit first output port return value decl. to task d.s.
5267  */
add_funcretdecl(char * rvnam,word32 frwtyp,struct expr_t * x1,struct expr_t * x2,int32 decl_signed)5268 static void add_funcretdecl(char *rvnam, word32 frwtyp,
5269  struct expr_t *x1, struct expr_t *x2, int32 decl_signed)
5270 {
5271  struct sy_t *syp;
5272  struct net_t *np;
5273  struct task_pin_t *tpp;
5274 
5275  /* notice symbol already in one up task decl. also name of port */
5276  syp = __decl_sym(rvnam, __venviron[__top_sti]);
5277  /* function declaration symbol table inconsisent */
5278  if (!__sym_is_new) __misc_fterr(__FILE__, __LINE__);
5279 
5280  np = __add_net(syp);
5281  if (x1 != NULL)
5282   {
5283    np->nu.ct->n_rngknown = TRUE;
5284    np->n_isavec = TRUE;
5285    np->nu.ct->nx1 = x1;
5286    np->nu.ct->nx2 = x2;
5287   }
5288  np->iotyp = IO_OUT;
5289  np->ntyp = frwtyp;
5290  np->nu.ct->n_rngknown = TRUE;
5291  np->nu.ct->n_iotypknown = TRUE;
5292  np->nu.ct->n_wirtypknown = TRUE;
5293  if (decl_signed) np->n_signed = TRUE; else np->n_signed = FALSE;
5294 
5295  syp->sydecl = TRUE;
5296  syp->syfnam_ind = __cur_fnam_ind;
5297  syp->sylin_cnt = __lin_cnt;
5298 
5299  /* alloc port and add to end of list - order here crucial */
5300  tpp = alloc_tskpin();
5301  tpp->tpsy = syp;
5302  tpp->trtyp = IO_OUT;
5303  if (__end_tpp == NULL) __cur_tsk->tskpins = tpp;
5304  else __end_tpp->tpnxt = tpp;
5305  __end_tpp = tpp;
5306 }
5307 
5308 /*
5309  * INSTANCE READING ROUTINES
5310  */
5311 
5312 /*
5313  * [module type] [# param list] [inst] ([mod connections]) ;
5314  * [udp/prim type] [strength] [#param list] [inst] ([prim. conn.]);
5315  */
5316 
5317 /*
5318  * read an instance - treat as if not yet defined or resolved
5319  * module type name read, reads final ;
5320  * at this point do not know if instance, gate or udp
5321  * return F if synced to next mod/prim else T if synced to ; even if err
5322  */
rd_inst(char * typnam)5323 static int32 rd_inst(char *typnam)
5324 {
5325  int32 first_time, has_iname, strenval, has_attr;
5326  struct cell_t *cp;
5327  struct sy_t *syp;
5328  struct tnode_t *tnp;
5329  struct namparam_t *nprmhdr;
5330  struct expr_t *x1, *x2;
5331  char s1[IDLEN];
5332 
5333  nprmhdr = NULL;
5334  first_time = TRUE;
5335  __v0stren = __v1stren = NO_STREN;
5336  has_iname = TRUE;
5337  x1 = x2 = NULL;
5338 
5339  /* must go here because for gate maybe no inam */
5340  /* use local has attr flag so can turn glb seen of before return */
5341  if (__wrk_attr.attr_seen) { has_attr = TRUE; __wrk_attr.attr_seen = FALSE; }
5342  else has_attr = FALSE;
5343 
5344  if (*typnam == '$')
5345   {
5346    __pv_ferr(1042,
5347    "instance/gate type \"%s\" cannot begin with $ - reserved for system tasks",
5348     typnam);
5349 bad_end:
5350    return(__vskipto_any(SEMI));
5351   }
5352  __get_vtok();
5353  if (__toktyp == LPAR)
5354   {
5355    __get_vtok();
5356    if (is_tokstren(__toktyp) == NO_STREN)
5357     {
5358      sprintf(s1, "__gate$$%d", __cp_num);
5359      has_iname = FALSE;
5360      goto no_inam;
5361     }
5362    /* need special strength read routine for pull */
5363    if (strcmp(typnam, "pullup") == 0 || strcmp(typnam, "pulldown") == 0)
5364     {
5365      if (!rd_pull_stren(typnam, &strenval)) goto bad_stren;
5366 
5367      /* here syntax good but strength values illegal - assume strong */
5368      /* error already emitted */
5369      if (strenval == NO_STREN)
5370       {
5371        if (strcmp(typnam, "pullup") == 0) strenval = STRONG1;
5372        else strenval = STRONG0;
5373       }
5374      /* LOOKATME - both strength must be same and right selected one */
5375      /* since simualtion uses low 3 bits of strength value */
5376      __v0stren = __v1stren = strenval;
5377      __get_vtok();
5378      goto rd_parms;
5379     }
5380 
5381    if (!rd_verstrens())
5382     {
5383 bad_stren:
5384      if (!__vskipto2_any(RPAR, SEMI)) return(FALSE);
5385      if (__toktyp == RPAR) { __get_vtok(); goto rd_parms; }
5386      /* bad strengths do not provide any punctuation to sync to */
5387      return(TRUE);
5388     }
5389   }
5390 
5391 rd_parms:
5392  if (__toktyp == SHARP)
5393   {
5394    if ((nprmhdr = rd_npndparams()) == NULL) goto bad_end;
5395   }
5396  else nprmhdr = NULL;
5397 
5398  for (;;)
5399   {
5400    if (__toktyp == LPAR)
5401     {
5402      /* name is [module name]$[unique number] */
5403      sprintf(s1, "__gate$$%d", __cp_num);
5404      has_iname = FALSE;
5405     }
5406    else
5407     {
5408      if (__toktyp != ID)
5409       {
5410        __pv_ferr(1043, "instance/gate name for type \"%s\" expected - %s read",
5411         typnam, __prt_kywrd_vtok());
5412        /* resyncing of comma list of same type insts not port lists */
5413        if (!__vskipto2_any(COMMA, SEMI)) return(FALSE);
5414        if (__toktyp == SEMI) return(TRUE);
5415        __get_vtok();
5416        continue;
5417       }
5418      strcpy(s1, __token);
5419      __get_vtok();
5420      /* new arrays of gates/instances [h:l] becomes "_"[number] suffix later */
5421      /* if no range, this just returns T and sets x1 and x2 to nil */
5422      /* if range, sets x1, x2 and reads one past ] */
5423      if (!__rd_decl_rng(&x1, &x2))
5424       {
5425        if (!__vskipto2_any(SEMI, RSB)) return(FALSE);
5426        if (__toktyp == SEMI) return(TRUE);
5427        __get_vtok();
5428       }
5429      if (__toktyp != LPAR)
5430       {
5431        __pv_ferr(1044,
5432         "instance/gate \"%s\" type \"%s\" connection list expected - %s read",
5433   	s1, typnam, __prt_vtok());
5434         goto bad_end;
5435       }
5436     }
5437    __get_vtok();
5438 no_inam:
5439    /* if port errors just inst. with no ports */
5440    if ((cp = add_cell(s1)) != NULL)
5441     {
5442      /* no checking for type sep. name space - if never decled err later */
5443      tnp = __vtfind(typnam, __modsyms);
5444      if (__sym_is_new)
5445       {
5446        __add_sym(typnam, tnp);
5447        (__modsyms->numsyms)++;
5448        syp = tnp->ndp;
5449        syp->sytyp = SYM_M;
5450        /* getting here means module/udp referenced before defined */
5451        /* and only place mod/udp can be seen */
5452        __add_syp_to_undefs(syp);
5453       }
5454      else syp = tnp->ndp;
5455      /* AIV 06/01/04 - mark all as not in config - config processing */
5456      /* will mark as true later */
5457      syp->cfg_needed = FALSE;
5458      /* instance must be named, error caught only after lib. processed */
5459      /* using inst. num that is unused until design wide checking */
5460      if (has_iname) cp->c_named = TRUE;
5461      if (x1 != NULL) { cp->cx1 = x1; cp->cx2 = x2; }
5462 
5463      cp->cmsym = syp;
5464      if (first_time) cp->c_nparms = nprmhdr;
5465      else cp->c_nparms = copy_namparamlst(nprmhdr);
5466      if (__v0stren != NO_STREN)
5467       {
5468        cp->c_hasst = TRUE;
5469        cp->c_stval = ((__v0stren << 3) | __v1stren) & 0x3f;
5470       }
5471     }
5472    /* if synced to ;, T even if errors */
5473    if (!rd_iports(s1)) return(TRUE);
5474    if (cp != NULL) cp->cpins = __cphdr;
5475 
5476    /* if saw an (* *) attribute for module item token, seen on */
5477    if (has_attr)
5478     {
5479      if (cp != NULL) add_cell_attr(cp);
5480     }
5481 
5482    __get_vtok();
5483    if (__toktyp == SEMI) break;
5484    first_time = FALSE;
5485    if (__toktyp == COMMA) { __get_vtok(); continue; }
5486 
5487    __pv_ferr(1048,
5488    "instance or gate terminal list ending semicolon or comma missing - %s read",
5489     __prt_vtok());
5490    /* must find a semi to continue */
5491    goto bad_end;
5492   }
5493  return(TRUE);
5494 }
5495 
5496 /*
5497  * add an inst attribute
5498  */
add_cell_attr(struct cell_t * cp)5499 static void add_cell_attr(struct cell_t *cp)
5500 {
5501  /* DBG remove -- */
5502  if (cp->cattrs != NULL) __misc_terr(__FILE__, __LINE__);
5503  /* --- */
5504 
5505  /* need to set token type so each parsed attr_spec has right tok type */
5506  __wrk_attr.attr_tok = MODULE;
5507 
5508  /* return nil on error */
5509  cp->cattrs = __rd_parse_attribute(&__wrk_attr);
5510  /* SJM 07/30/01 - this is work read value, but now done with it */
5511  __my_free(__wrk_attr.attrnam, __attr_line_len + 1);
5512  __wrk_attr.attr_seen = FALSE;
5513 }
5514 
5515 /*
5516  * read the pull strength
5517  * know leading '(' and strength read, reads optional second , stren and
5518  * then ending ')' or just ending ')'
5519  * on F return trys to sync to ending ')' or ';'
5520  *
5521  * SJM 10/01/99 - allow both 0 and 1 strength where unused one dropped
5522  * required by 1999 LRM
5523  *
5524  * where two strengths given, drops unused one here
5525  * know ehen called first token is some kind of strength
5526  */
rd_pull_stren(char * pullnam,int32 * strenval)5527 static int32 rd_pull_stren(char *pullnam, int32 *strenval)
5528 {
5529  int32 st1typ, st1val, st2val, st2typ, err_seen;
5530  int32 strentyp, strenval1, strenval2;
5531 
5532  err_seen = FALSE;
5533  st1typ = st2typ = strentyp = NO_STREN;
5534  st1val = st2val = TOK_NONE;
5535  *strenval = NO_STREN;
5536  /* know 1st required */
5537  st1val = __toktyp;
5538  if ((st1typ = is_tokstren(__toktyp)) == CAP_STREN || st1typ == NO_STREN)
5539   {
5540    __pv_ferr(1032, "%s strength %s non driving or illegal", pullnam,
5541     __prt_vtok());
5542    st1typ = NO_STREN;
5543    err_seen = TRUE;
5544   }
5545 
5546  __get_vtok();
5547  if (__toktyp == COMMA)
5548   {
5549    /* second strength present */
5550    __get_vtok();
5551    st2val = __toktyp;
5552    if ((st2typ = is_tokstren(__toktyp)) == CAP_STREN || st2typ == NO_STREN)
5553     {
5554      __pv_ferr(1032, "%s second strength %s non driving or illegal", pullnam,
5555       __prt_vtok());
5556      st2typ = NO_STREN;
5557      err_seen = TRUE;
5558     }
5559    __get_vtok();
5560   }
5561  if (__toktyp != RPAR)
5562   {
5563    __pv_ferr(1031, "%s strength ending ')' expected - %s read", pullnam,
5564     __prt_vtok());
5565    return(FALSE);
5566   }
5567  if (err_seen) return(TRUE);
5568 
5569  /* know one or two strengths read and legal */
5570  /* case 1: old only one strength form - check to make sure right type */
5571  if (st2typ == NO_STREN)
5572   {
5573    strentyp = st1typ;
5574    /* map from strength token to strength constant value */
5575    *strenval = __fr_stren_nam(st1val);
5576    if (strcmp(pullnam, "pullup") == 0)
5577     {
5578      if (strentyp == LOW_STREN)
5579       {
5580        __pv_fwarn(608,
5581         "%s single strength form low (0) strength %s should be high (1) - changed",
5582         pullnam, __to1_stren_nam(__xs, *strenval, st1typ));
5583       }
5584     }
5585    else
5586     {
5587      if (strentyp == HIGH_STREN)
5588       {
5589        __pv_fwarn(608,
5590         "%s single strength form high (1) strength %s should be low (0) - changed",
5591         pullnam, __to1_stren_nam(__xs, *strenval, st1typ));
5592       }
5593     }
5594    if (*strenval == ST_HIGHZ)
5595     {
5596      __pv_ferr(1018,
5597       "highz strength illegal for single strength form %s gate",
5598       pullnam);
5599      strentyp = NO_STREN;
5600      *strenval = NO_STREN;
5601     }
5602    return(TRUE);
5603   }
5604  /* case 2 */
5605  /* make sure not both 0 strens and not both 1 strens */
5606  if (st1typ == LOW_STREN && st2typ == LOW_STREN)
5607   {
5608    __pv_ferr(1032, "%s two strength form both strengths low (0)", pullnam);
5609    return(TRUE);
5610   }
5611  if (st1typ == LOW_STREN && st2typ == LOW_STREN)
5612   {
5613    __pv_ferr(1032, "%s two strength form both strengths high (1)", pullnam);
5614    return(TRUE);
5615   }
5616  /* map from strength token to strength constant value for both */
5617  strenval1 = __fr_stren_nam(st1val);
5618  strenval2 = __fr_stren_nam(st2val);
5619  if (strenval1 == ST_HIGHZ || strenval2 == ST_HIGHZ)
5620   {
5621    __pv_ferr(1018, "highz strength illegal as either strength for %s gate",
5622     pullnam);
5623    strentyp = NO_STREN;
5624    *strenval = NO_STREN;
5625    return(TRUE);
5626   }
5627  /* select right strength from two */
5628  if (strcmp(pullnam, "pullup") == 0)
5629   {
5630    if (st1typ == LOW_STREN) *strenval = strenval2; else *strenval = strenval1;
5631   }
5632  else
5633   {
5634    if (st1typ == HIGH_STREN) *strenval = strenval2; else *strenval = strenval1;
5635   }
5636  return(TRUE);
5637 }
5638 
5639 /*
5640  * read a new style instance only old implicit or new explicit param form
5641  *
5642  * know # read and reads one past list ending ) - maybe only one and no ()
5643  * must also read new style for gates since until types resolved do not
5644  * know if gate or instance - error during fixup in new style for gate/udp
5645  */
rd_npndparams(void)5646 static struct namparam_t *rd_npndparams(void)
5647 {
5648  int32 prm_err;
5649  struct namparam_t *npmphdr, *npmp, *last_npmp;
5650 
5651  __get_vtok();
5652  /* case 1: old #[one token] case */
5653  if (__toktyp != LPAR)
5654   {
5655    /* notice must surround m:t:m with () */
5656    if (__toktyp != ID && __toktyp != NUMBER && __toktyp != REALNUM)
5657     {
5658      __pv_ferr(1049,
5659      "non parenthesized pound parameter one element identifier or number expected - %s read",
5660       __prt_kywrd_vtok());
5661      return(NULL);
5662     }
5663    __last_xtk = -1;
5664    /* on error, set as error expr. - maybe since param should be 0 */
5665    if (!__bld_expnode()) __set_xtab_errval();
5666    /* here does the allocating */
5667    __bld_xtree(0);
5668    npmphdr = __alloc_namparam();
5669    npmphdr->pxndp = __root_ndp;
5670    npmphdr->prmfnam_ind = __cur_fnam_ind;
5671    npmphdr->prmlin_cnt = __lin_cnt;
5672    __get_vtok();
5673    return(npmphdr);
5674   }
5675 
5676  /* case 2: #(...) - either , list (no empties) or explicit form */
5677  for (npmphdr = NULL, last_npmp = NULL, prm_err = FALSE;;)
5678   {
5679    __get_vtok();
5680 
5681    /* read the pound parameter (maybe new explicit form) and one token past */
5682    /* illegal forms caught during fix up */
5683    if ((npmp = rd1_namedparam()) == NULL) goto bad_skipend;
5684    if (npmphdr == NULL) npmphdr = npmp; else last_npmp->nprmnxt = npmp;
5685    last_npmp = npmp;
5686 
5687    if (__toktyp == RPAR) break;
5688    if (__toktyp == COMMA) continue;
5689 
5690    __pv_ferr(1051, "pound parameter list comma or ) expected - %s read ",
5691     __prt_vtok());
5692 
5693 bad_skipend:
5694    prm_err = TRUE;
5695    if (!__vskipto3_any(RPAR, COMMA, SEMI)) return(FALSE);
5696    if (__toktyp == COMMA) { __get_vtok(); continue; }
5697    /* if ) or ; done and synced to right place */
5698    if (__toktyp == SEMI) __unget_vtok();
5699    break;
5700   }
5701  __get_vtok();
5702 
5703  if (prm_err)
5704   {
5705    if (npmphdr != NULL) __free_namedparams(npmphdr);
5706    return(NULL);
5707   }
5708  return(npmphdr);
5709 }
5710 
5711 /*
5712  * read one instance (cell) or gate param (may have new named form)
5713  *
5714  * know 1st token read and reads punctuation after , or )
5715  * returns built named param record
5716  *
5717  * on error returns nil, caller (not in this routine) tries to resync
5718  * on , and read next param * but on .[id](<some error> ..., this trys
5719  * to resync to list ending )
5720  *
5721  * LOOKATME - allowing ,, form
5722  */
rd1_namedparam(void)5723 static struct namparam_t *rd1_namedparam(void)
5724 {
5725  int32 namedparam_form, slcnt, sfnind;
5726  struct namparam_t *npmp;
5727  char nam[IDLEN];
5728 
5729  slcnt = __lin_cnt;
5730  sfnind = __cur_fnam_ind;
5731  if (__toktyp == DOT)
5732   {
5733    __get_vtok();
5734    if (__toktyp != ID)
5735     {
5736      __pv_ferr(1052, "name of pound param expected - %s read",
5737       __prt_kywrd_vtok());
5738      return(NULL);
5739     }
5740    strcpy(nam, __token);
5741    __get_vtok();
5742    if (__toktyp != LPAR)
5743     {
5744      __pv_ferr(1053,
5745       "pound param explicitly named form left parenthesis expected - %s read",
5746       __prt_vtok());
5747      return(NULL);
5748     }
5749    /* 1st token in expr. must be read */
5750    __get_vtok();
5751    /* explicit param name .[param]() for unc. is legal */
5752    if (__toktyp == RPAR)
5753     {
5754      __last_xtk = 0;
5755      __set_opempty(0);
5756     }
5757    else
5758     {
5759      /* need to collect delay expr. because min-typ-max without () ok */
5760      if (!__col_delexpr()) return(NULL);
5761     }
5762    namedparam_form = TRUE;
5763   }
5764  else
5765   {
5766    namedparam_form = FALSE;
5767    /* (, - ,, and ,) all legal */
5768    if (__toktyp == COMMA || __toktyp == RPAR)
5769     {  __last_xtk = 0; __set_opempty(0); }
5770    else
5771     {
5772      /* need to collect delay expr. because min-typ-max without () ok */
5773      if (!__col_delexpr()) return(NULL);
5774     }
5775   }
5776  /* build the tree, copy/allocate nodes, sets __root_ndp to its root */
5777  /* this must be a constant expr but checked later - this will decl */
5778  __bld_xtree(0);
5779 
5780  if (namedparam_form)
5781   {
5782    if (__toktyp != RPAR)
5783     {
5784      __pv_ferr(1055,
5785       "explicitly named pound param form right parenthesis expected - %s read",
5786       __prt_vtok());
5787      return(NULL);
5788     }
5789    __get_vtok();
5790    /* LOOKATME - why is this check here - think no longer needed */
5791    /* but catching user or PLI sys function here does not hurt */
5792    if (__root_ndp->optyp == FCALL )
5793     {
5794      struct sy_t *syp;
5795 
5796      /* only built in sysfuncs allowed - const args checked later */
5797      syp = __root_ndp->lu.x->lu.sy;
5798      if (syp->sytyp == SYM_SF && syp->el.esyftbp->tftyp == SYSF_BUILTIN)
5799       goto named_ok;
5800 
5801      __pv_ferr(1055,
5802       "explicitly named pound param %s illegal -  not required .[name]([value])",
5803       __msgexpr_tostr(__xs, __root_ndp));
5804      return(NULL);
5805     }
5806   }
5807 named_ok:
5808  npmp = __alloc_namparam();
5809  npmp->pxndp = __root_ndp;
5810  if (namedparam_form) npmp->pnam = __pv_stralloc(nam);
5811  else npmp->pnam = NULL;
5812  npmp->prmfnam_ind = sfnind;
5813  npmp->prmlin_cnt = slcnt;
5814  return(npmp);
5815 }
5816 
5817 /*
5818  * free list of named param records
5819  */
__free_namedparams(struct namparam_t * npmphdr)5820 extern void __free_namedparams(struct namparam_t *npmphdr)
5821 {
5822  register struct namparam_t *npmp, *npmp2;
5823  int32 slen;
5824 
5825  for (npmp = npmphdr; npmp != NULL;)
5826   {
5827    npmp2 = npmp->nprmnxt;
5828 
5829    /* expr. may be nil, when freeing after expr. copied */
5830    if (npmp->pxndp != NULL) __free_xtree(npmp->pxndp);
5831    if (npmp->pnam != NULL)
5832     {
5833      slen = strlen(npmp->pnam);
5834      __my_free((char *) npmp->pnam, slen + 1);
5835     }
5836    __my_free((char *) npmp, sizeof(struct namparam_t));
5837 
5838    npmp = npmp2;
5839   }
5840 }
5841 
5842 /*
5843  * add module symbol (possibly later changed to udp) to undef list
5844  */
__add_syp_to_undefs(struct sy_t * syp)5845 extern void __add_syp_to_undefs(struct sy_t *syp)
5846 {
5847  struct undef_t *undefp;
5848 
5849  undefp = (struct undef_t *) __my_malloc(sizeof(struct undef_t));
5850  undefp->msyp = syp;
5851  undefp->undefnxt = NULL;
5852  undefp->dfi = -1;
5853  undefp->modnam = NULL;
5854  syp->syundefmod = TRUE;
5855  syp->el.eundefp = undefp;
5856 
5857  if (__undeftail == NULL)
5858   {
5859    __undeftail = __undefhd = undefp;
5860    undefp->undefprev = NULL;
5861   }
5862  else
5863   {
5864    undefp->undefprev = __undeftail;
5865    __undeftail->undefnxt = undefp;
5866    __undeftail = undefp;
5867   }
5868  __undef_mods++;
5869 }
5870 
5871 /*
5872  * copy possibly named param list
5873  *
5874  * only needed during instance reading because converted to dellst form
5875  * when module copying needed
5876  */
copy_namparamlst(struct namparam_t * old_npmp)5877 static struct namparam_t *copy_namparamlst(struct namparam_t *old_npmp)
5878 {
5879  register struct namparam_t *npmphdr, *npmp, *onpmp, *last_npmp;
5880 
5881  if (old_npmp == NULL) return(NULL);
5882 
5883  npmphdr = NULL;
5884  last_npmp = NULL;
5885  for (onpmp = old_npmp; onpmp != NULL; onpmp = onpmp->nprmnxt)
5886   {
5887    npmp = (struct namparam_t *) __my_malloc(sizeof(struct namparam_t));
5888    /* since mallocing, need to fill all fields */
5889    npmp->prmfnam_ind = onpmp->prmfnam_ind;
5890    npmp->prmlin_cnt = onpmp->prmlin_cnt;
5891    npmp->pxndp = __copy_expr(onpmp->pxndp);
5892    if (onpmp->pnam != NULL) npmp->pnam = __pv_stralloc(onpmp->pnam);
5893    else npmp->pnam = NULL;
5894    npmp->nprmnxt = NULL;
5895 
5896    if (last_npmp == NULL) npmphdr = npmp; else last_npmp->nprmnxt = npmp;
5897    last_npmp = npmp;
5898   }
5899  return(npmphdr);
5900 }
5901 
5902 /*
5903  * allocate and initialize a inst/gate pound param record
5904  */
__alloc_namparam(void)5905 extern struct namparam_t *__alloc_namparam(void)
5906 {
5907  struct namparam_t *npmp;
5908 
5909  npmp = (struct namparam_t *) __my_malloc(sizeof(struct namparam_t));
5910  npmp->pxndp = NULL;
5911  npmp->prmfnam_ind = 0;
5912  npmp->prmlin_cnt = -1;
5913  npmp->pnam = NULL;
5914  npmp->nprmnxt = NULL;
5915  return(npmp);
5916 }
5917 
5918 /*
5919  * make a copy of a param list
5920  * know at copy point delay is DT_CMPLST list
5921  */
__copy_dellst(struct paramlst_t * oplp)5922 extern struct paramlst_t *__copy_dellst(struct paramlst_t *oplp)
5923 {
5924  register struct paramlst_t *plp;
5925  struct paramlst_t *nplphdr, *nplp, *last_nplp;
5926 
5927  if (oplp == NULL) return(NULL);
5928 
5929  nplphdr = NULL;
5930  for (last_nplp = NULL, plp = oplp; plp != NULL; plp = plp->pmlnxt)
5931   {
5932    nplp = __alloc_pval();
5933    nplp->plxndp = __copy_expr(plp->plxndp);
5934    if (last_nplp == NULL) nplphdr = nplp; else last_nplp->pmlnxt = nplp;
5935    nplp->pmlnxt = NULL;
5936    last_nplp = nplp;
5937   }
5938  return(nplphdr);
5939 }
5940 
5941 /*
5942  * read instance ports - probably no module def. at this point
5943  * know 1st token of port expr. read and reads final )
5944  */
rd_iports(char * inam)5945 static int32 rd_iports(char *inam)
5946 {
5947  for (__cphdr = NULL;;)
5948   {
5949    /* read the cell-pin reference and one token past */
5950    /* illegal forms caught during fix up */
5951    if (!rd_cpin_conn()) goto bad_trynxt;
5952 
5953    if (__toktyp == RPAR) break;
5954    if (__toktyp == COMMA) { __get_vtok(); continue; }
5955    __pv_ferr(1051,
5956     "instance/gate %s port connection list comma or ) expected - %s read ",
5957     inam, __prt_vtok());
5958 
5959 bad_trynxt:
5960    if (!__vskipto3_any(RPAR, COMMA, SEMI)) return(FALSE);
5961    if (__toktyp == COMMA) { __get_vtok(); continue; }
5962    /* if ) or ; done and synced to right place */
5963    if (__toktyp == SEMI) __unget_vtok();
5964    break;
5965   }
5966  return(TRUE);
5967 }
5968 
5969 /*
5970  * read an instance port connection
5971  * know 1st token read and reads punctuation after , or )
5972  * then adds to end of global cell pin list header __cphdr
5973  *
5974  * on error returns F, caller tries to resync on , and read next port
5975  * but on .[id](<some error> ..., this trys to resync to port ending )
5976  */
rd_cpin_conn(void)5977 static int32 rd_cpin_conn(void)
5978 {
5979  int32 namedport_form;
5980  struct cell_pin_t *cpp;
5981 
5982  if (__toktyp == DOT)
5983   {
5984    __get_vtok();
5985    if (__toktyp != ID)
5986     {
5987      __pv_ferr(1052,
5988       "instance/gate connection name of port expected - %s read",
5989       __prt_kywrd_vtok());
5990      return(FALSE);
5991     }
5992    strcpy(__portnam, __token);
5993    __get_vtok();
5994    if (__toktyp != LPAR)
5995     {
5996      __pv_ferr(1053,
5997       "explicit port name form left parenthesis expected - %s read",
5998       __prt_vtok());
5999      return(FALSE);
6000     }
6001    /* 1st token in expr. must be read */
6002    __get_vtok();
6003    /* instance connection .[port]() for unc. is legal */
6004    if (__toktyp == RPAR)
6005     {
6006      __last_xtk = 0;
6007      __set_opempty(0);
6008      /* need to leave right paren in token since checked for later */
6009     }
6010    else
6011     {
6012      if (!__col_parenexpr(-1))
6013       {
6014        /* if can resync to ) move to next tok - then caller resyncs again */
6015        if (__vskipto_modend(RPAR)) __get_vtok();
6016        return(FALSE);
6017       }
6018     }
6019    namedport_form = TRUE;
6020   }
6021  else
6022   {
6023    namedport_form = FALSE;
6024    /* (, - ,, and ,) all legal */
6025    if (__toktyp == COMMA || __toktyp == RPAR)
6026     {  __last_xtk = 0; __set_opempty(0); }
6027    else { if (!__col_connexpr(-1)) return(FALSE); }
6028   }
6029  /* this declares undeclared wire */
6030  /* build the tree, copy/allocate nodes, sets __root_ndp to its root */
6031  __bld_xtree(0);
6032 
6033  if (namedport_form)
6034   {
6035    if (__toktyp != RPAR)
6036     {
6037      __pv_ferr(1055,
6038       "instance explicit named port form right parenthesis expected - %s read",
6039       __prt_vtok());
6040      if (__vskipto_modend(RPAR)) { __get_vtok(); return(TRUE); }
6041      return(FALSE);
6042     }
6043    __get_vtok();
6044   }
6045  /* this save the global portnam as a string if present */
6046  cpp = __alloc_cpin(namedport_form);
6047  cpp->cpxnd = __root_ndp;
6048  if (__cphdr == NULL) __cphdr = cpp; else __cpp_last->cpnxt = cpp;
6049  __cpp_last = cpp;
6050 
6051  return(TRUE);
6052 }
6053 
6054 /*
6055  * allocate a cell pin - fill mostly from global data
6056  */
__alloc_cpin(int32 has_name)6057 extern struct cell_pin_t *__alloc_cpin(int32 has_name)
6058 {
6059  struct cell_pin_t *cpp;
6060 
6061  cpp = alloc_memcpins();
6062  if (has_name) cpp->pnam = alloc_cpnam(__portnam);
6063  else cpp->pnam = NULL;
6064  cpp->cplin_cnt = __lin_cnt;
6065  cpp->cpfnam_ind = __cur_fnam_ind;
6066  cpp->cpxnd = NULL;
6067  cpp->cpnxt = NULL;
6068 
6069  return(cpp);
6070 }
6071 
6072 /*
6073  * allocate a string element a preallocated block for fast freeing
6074  */
alloc_cpnam(char * s)6075 static char *alloc_cpnam(char *s)
6076 {
6077  char *cp;
6078  int32 slen, rem, real_size;
6079  struct cpnblk_t *cpnbp;
6080 
6081  slen = strlen(s) + 1;
6082  if ((rem = slen % 4) != 0) real_size = slen + 4 - rem;
6083  else real_size = slen;
6084 
6085  if ((__hdr_cpnblks->cpn_start_sp + real_size + 4) >=
6086   __hdr_cpnblks->cpn_end_sp)
6087   {
6088    cpnbp = (struct cpnblk_t *) __my_malloc(sizeof(struct cpnblk_t));
6089    cpnbp->cpnblknxt = __hdr_cpnblks;
6090    __hdr_cpnblks = cpnbp;
6091    cpnbp->cpnblks = cpnbp->cpn_start_sp = __my_malloc(BIG_ALLOC_SIZE);
6092    cpnbp->cpn_end_sp = cpnbp->cpn_start_sp + BIG_ALLOC_SIZE - 16;
6093   }
6094  cp = __hdr_cpnblks->cpn_start_sp;
6095  __hdr_cpnblks->cpn_start_sp += real_size;
6096  strcpy(cp, s);
6097  return(cp);
6098 }
6099 
6100 /*
6101  * allocate a ncomp element from a preallocated block for fast freeing
6102  */
alloc_memcpins(void)6103 static struct cell_pin_t *alloc_memcpins(void)
6104 {
6105  struct cppblk_t *cppbp;
6106  struct cell_pin_t *cpp;
6107 
6108  if (__cppblk_nxti == -1)
6109   {
6110    cppbp = (struct cppblk_t *) __my_malloc(sizeof(struct cppblk_t));
6111    cppbp->cppblks = (struct cell_pin_t *) __my_malloc(BIG_ALLOC_SIZE);
6112    cppbp->cppblknxt = __hdr_cppblks;
6113    __hdr_cppblks = cppbp;
6114    __cppblk_nxti = 0;
6115   }
6116  cpp = (struct cell_pin_t *) &(__hdr_cppblks->cppblks[__cppblk_nxti]);
6117  if (++__cppblk_nxti > ((BIG_ALLOC_SIZE/sizeof(struct cell_pin_t)) - 1))
6118   __cppblk_nxti = -1;
6119  return(cpp);
6120 }
6121 
6122 /*
6123  * add cell - better not be already defined at module top level
6124  * at this point both gates and module instances cells
6125  * cells always declared at top level
6126  */
add_cell(char * inam)6127 static struct cell_t *add_cell(char *inam)
6128 {
6129  struct cell_t *cp;
6130  struct sy_t *syp;
6131  char s1[RECLEN];
6132 
6133  __cp_num++;
6134  syp = __decl_sym(inam, __venviron[0]);
6135  if (__sym_is_new)
6136   {
6137 treat_as_new:
6138    syp->sytyp = SYM_I;
6139    cp = __alloc_cell(syp);
6140    syp->el.ecp = cp;
6141 
6142    syp->sydecl = TRUE;
6143     /* this is place of declaration */
6144    syp->syfnam_ind = __cur_fnam_ind;
6145    syp->sylin_cnt = __lin_cnt;
6146 
6147    /* must link on end to preserve inst. order */
6148    if (__end_cp == NULL) __inst_mod->mcells = cp;
6149    else __end_cp->cnxt = cp;
6150    __end_cp = cp;
6151    return(cp);
6152   }
6153  /* since symbol may be used as down 1 xmr in some system tasks */
6154  /* if not declared just assume is instance - checked later */
6155  if (syp->sytyp != SYM_I)
6156   {
6157    if (syp->sydecl)
6158     {
6159      __pv_ferr(1056, "instance/gate name %s previously declared as %s at %s",
6160       syp->synam, __to_sytyp(s1, syp->sytyp),
6161       __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
6162     }
6163    else goto treat_as_new;
6164   }
6165  else __pv_ferr(1057, "instance/gate name %s repeated - previous %s",
6166   syp->synam, __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
6167  return(NULL);
6168 }
6169 
6170 /*
6171  * allocate the cell - at this point can be gate, udp or inst.
6172  */
__alloc_cell(struct sy_t * syp)6173 extern struct cell_t *__alloc_cell(struct sy_t *syp)
6174 {
6175  struct cell_t *cp;
6176 
6177  /* alloc the element */
6178  cp = alloc_memcell();
6179  /* initialize contents union by zeroing all bytes of entire cell */
6180  cp->csym = syp;
6181  /* need to fill module type later */
6182  cp->cmsym = NULL;
6183  cp->cnxt = NULL;
6184  cp->c_hasst = FALSE;
6185  cp->c_stval = ST_STRVAL;
6186  cp->cp_explicit = FALSE;
6187  cp->c_named = FALSE;
6188  cp->c_iscell = FALSE;
6189  cp->cx1 = cp->cx2 = NULL;
6190  cp->c_nparms = NULL;
6191  cp->cattrs = NULL;
6192  cp->cpins = NULL;
6193  return(cp);
6194 }
6195 
6196 /*
6197  * allocate a ncomp element from a preallocated block for fast freeing
6198  */
alloc_memcell(void)6199 static struct cell_t *alloc_memcell(void)
6200 {
6201  struct cpblk_t *cpbp;
6202  struct cell_t *cp;
6203 
6204  if (__cpblk_nxti == -1)
6205   {
6206    cpbp = (struct cpblk_t *) __my_malloc(sizeof(struct cpblk_t));
6207    cpbp->cpblks = (struct cell_t *) __my_malloc(BIG_ALLOC_SIZE);
6208    cpbp->cpblknxt = __hdr_cpblks;
6209    __hdr_cpblks = cpbp;
6210    __cpblk_nxti = 0;
6211   }
6212  cp = (struct cell_t *) &(__hdr_cpblks->cpblks[__cpblk_nxti]);
6213  if (++__cpblk_nxti > ((BIG_ALLOC_SIZE/sizeof(struct cell_t)) - 1))
6214   __cpblk_nxti = -1;
6215  return(cp);
6216 }
6217