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