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 * module that fixes and checks net list after all source read
30 * all defparam and global processing in v_grf
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.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 try_cnvt_parmsel_toconst(struct expr_t *);
46 static void cnvt_paramsel_toconst(struct expr_t *, struct net_t *);
47 static void cnvt_nonis_selparm(struct net_t *, struct expr_t *,
48 struct expr_t *);
49 static void cnvt_is_bselparm(struct net_t *, struct expr_t *, struct expr_t *);
50 static void cnvt_is_arrselparm(struct net_t *, struct expr_t *,
51 struct expr_t *);
52 static int32 get_nonis_param_ndx(struct net_t *, struct expr_t *);
53 static int32 get_is_param_ndx(struct net_t *, struct expr_t *, int32);
54 static void cnvt_nonis_pselparm(struct net_t *, struct expr_t *,
55 struct expr_t *, struct expr_t *);
56 static void cnvt_is_pselparm(struct net_t *, struct expr_t *, struct expr_t *,
57 struct expr_t *);
58 static void chk_struct_rhsexpr(struct expr_t *, int32);
59 static int32 chk_rhs_id(struct expr_t *);
60 static void unwind_rhsconcats(struct expr_t *);
61 static void remove_0width_catrep_els(struct expr_t *);
62 static void set_rhswidth(struct expr_t *, int32);
63 static void set2_rhswidth(struct expr_t *, int32);
64 static void set_fcall_widths(struct expr_t *, struct task_t *);
65 static void set_sysfcall_widths(struct expr_t *);
66 static void set_rhs_signed(struct expr_t *);
67 static int32 find_xbase(struct expr_t *);
68 static void setchk_real_expr(struct expr_t *);
69 static void real_setchk_quest(struct expr_t *);
70 static void chk_specialop_rhsexpr(struct expr_t *);
71 static int32 chk_srcbsel(struct expr_t *, int32);
72 static int32 chk_srcpsel(struct expr_t *, int32);
73 static void chkspecop_fcall(struct expr_t *);
74 static int32 chk_mixedsign_relops(struct expr_t *);
75 static void fold_subexpr(struct expr_t *);
76 static int32 mark_constnd(register struct expr_t *, int32 *);
77 static void fold_const(struct expr_t *);
78 static int32 is_signed_decimal(struct expr_t *);
79 static void chk_ndfolded_specops(struct expr_t *);
80 static int32 chk_inrng_bsel(struct expr_t *);
81 static int32 chknorm_range(struct expr_t *, int32, int32, char *, int32);
82 static int32 in_range(int32, int32, int32, int32 *);
83 static int32 chk_inrng_psel(struct expr_t *);
84 static void chk_folded_fargs(struct expr_t *);
85 static int32 nd_ndxisnum(struct expr_t *, char *, int32);
86 static void chk_sysfargs_syntax(struct expr_t *);
87 static void chkbld_pli_func(struct expr_t *, int32);
88 static void chk_pli_arglist(register struct expr_t *, int32);
89 static int32 tfexpr_isrw(struct expr_t *);
90 static int32 lhs_is_decl(struct expr_t *);
91 static struct tfrec_t *chkalloc_tfrec(struct expr_t *, int32);
92 static struct tfarg_t *alloc_tfarg(register struct expr_t *, int32, int32);
93 static void chksf_count_drivers(struct expr_t *, int32);
94 static int32 is_1bwire(struct expr_t *);
95 static void chksf_getpattern(struct sy_t *, struct expr_t *, int32);
96 static void sf_errifn(struct sy_t *, int32);
97 static void chksf_q_full(struct expr_t *, int32);
98 static void chksf_rand(struct expr_t *, int32, int32);
99 static int32 chksyn_lhsexpr(struct expr_t *, int32, int32);
100 static void unwind_lhsconcats(struct expr_t *);
101 static int32 idnd_var(struct sy_t *);
102 static int32 nd_reg(struct expr_t *);
103 static int32 xpr_hasfcall(struct expr_t *);
104 static int32 xpr_has_nonsys_fcall(struct expr_t *);
105 static void chk_edge_expr(struct expr_t *);
106 static void chk_systskenable(struct st_t *, struct tskcall_t *);
107 static void mark_monit_in_src_nets(struct expr_t *);
108 static void chkbld_pli_task(struct st_t *, int32);
109 static void st_errif_rng(struct sy_t *, int32, int32, int32);
110 static void st_errifn(struct sy_t *, int32, int32);
111 static void chkst_dumpvars_enable(struct tskcall_t *, int32);
112 static void mark_mod_dvars_under(struct mod_t *, int32);
113 static void set_iact_dmpv_all_nd_nchgstore(void);
114 static void set_iact_dmpvmod_nd_nchgstore(struct mod_t *);
115 static void chkst_readmem(struct sy_t *, int32, struct tskcall_t *);
116 static int32 nd_unind_arr(struct expr_t *);
117 static void chkst_sreadmem(struct sy_t *, int32, struct tskcall_t *);
118 static void chkst_sdfannotate_enable(struct tskcall_t *, int32);
119 static int32 chk_undef_specparams(struct symtab_t *);
120 static int32 chk_1spcpth(struct spcpth_t *);
121 static int32 expr_has_nonpth(struct expr_t *, word32 *);
122 static void chk_rep_in_fullpth(struct spcpth_t *);
123 static char *pth_tostr(char *, struct spcpth_t *, struct pathel_t *,
124 struct pathel_t *);
125 static char *pthel_tostr(char *, struct pathel_t *);
126 static int32 pth_overlap(struct pathel_t *, struct pathel_t *);
127 static void chk_rep_sdpds(struct spfy_t *);
128 static struct xpnd_pthel_t *xpnd_pths(struct spfy_t *, int32 *);
129 static void chk_spterm(struct expr_t *, char *, char *, int32);
130 static int32 chk_1tchk(struct tchk_t *);
131 static void chk_tccond(struct expr_t *, char *, char *);
132 static void chk_notifier(struct tchk_t *, char *);
133 static struct tchk_t *bld_sup_of_suphld(struct tchk_t *);
134 static struct tchk_t *bld_rec_of_recrem(struct tchk_t *);
135 static void free_spcpths(struct spcpth_t *);
136 static void free_frozen_symtab(struct symtab_t *);
137 static void free_spcparms(struct net_t *, int32);
138
139 /* extern prototypes (maybe defined in this module) */
140 extern char *__my_malloc(int32);
141 extern void __my_free(char *, int32);
142 extern char *__to_idnam(struct expr_t *);
143 extern char *__to_wtnam(char *, struct net_t *);
144 extern char *__to_sytyp(char *, word32);
145 extern char *__to_tcnam(char *, word32);
146 extern char *__msgexpr_tostr(char *, struct expr_t *);
147 extern char *__to_opname(word32);
148 extern struct expr_t *__copy_expr(struct expr_t *);
149 extern struct xstk_t *__eval2_xpr(struct expr_t *);
150 extern void __grow_xstk(void);
151 extern void __chg_xstk_width(struct xstk_t *, int32);
152 extern char *__msgnumexpr_tostr(char *, struct expr_t *, int32);
153 extern char *__msg2_blditree(char *, struct itree_t *);
154 extern struct paramlst_t *__copy_dellst(struct paramlst_t *);
155 extern char *__bld_lineloc(char *, word32, int32);
156 extern int32 __isleaf(struct expr_t *);
157 extern struct expr_t *__dup_concat(int32, struct expr_t *);
158 extern struct expr_t *__find_catend(struct expr_t *);
159 extern int32 __nd_ndxnum(struct expr_t *, char *, int32);
160 extern void __free2_xtree(struct expr_t *);
161 extern void __init_xnd(struct expr_t *);
162 extern void __set_numval(struct expr_t *, word32, word32, int32);
163 extern int32 __get_netwide(struct net_t *);
164 extern int32 __wide_vval_is0(register word32 *, int32);
165 extern int32 __is_paramconstxpr(struct expr_t *, int32);
166 extern void __rhspsel(register word32 *, register word32 *, register int32,
167 register int32);
168 extern int32 __get_rhswidth(struct expr_t *);
169 extern int32 __get_widthclass(struct expr_t *);
170 extern void __narrow_sizchg(register struct xstk_t *, int32);
171 extern void __sizchg_widen(register struct xstk_t *, int32);
172 extern void __sgn_xtnd_widen(struct xstk_t *, int32);
173 extern void __getarr_range(struct net_t *, int32 *, int32 *, int32 *);
174 extern void __getwir_range(struct net_t *, int32 *, int32 *);
175 extern int32 __cnt_tfargs(register struct expr_t *);
176 extern int32 __chk_lhsexpr(struct expr_t *, int32);
177 extern void __chkbld_vpi_systf_func(struct expr_t *);
178 extern void __pli_func_sizetf(struct expr_t *);
179 extern void __set_lhswidth(struct expr_t *);
180 extern int32 __nd_wire(struct expr_t *);
181 extern int32 __chk_lhsdecl_scalared(struct expr_t *);
182 extern void __set_expr_onrhs(struct expr_t *);
183 extern int32 __is_scope_sym(struct sy_t *);
184 extern void __chk_fmt(register struct expr_t *, byte *);
185 extern void __chkbld_vpi_systf_task(struct st_t *);
186 extern void __set_xtab_errval(void);
187 extern void __bld_xtree(int32);
188 extern void __xtract_wirng(struct expr_t *, struct net_t **, int32 *, int32 *);
189 extern void __free_xtree(struct expr_t *);
190 extern void __chk_spec_delay(struct expr_t *, char *);
191 extern void __free_dellst(struct paramlst_t *);
192 extern int32 __chk_numdelay(struct expr_t *, char *);
193 extern void __init_tchk(struct tchk_t *, word32);
194 extern void __free_tchks(struct tchk_t *);
195 extern void __free_xprlst(struct exprlst_t *);
196 extern int32 __expr_has_glb(struct expr_t *);
197 extern int32 __alloc_is_cval(int32);
198 extern int32 __allocfill_cval_new(word32 *, word32 *, int32);
199 extern int32 __alloc_shareable_cval(word32, word32, int32);
200 extern int32 __alloc_shareable_rlcval(double);
201 extern struct expr_t *__widen_unsiz_rhs_assign(struct expr_t *, int);
202
203 extern void __pv_warn(int32, char *,...);
204 extern void __sgfwarn(int32, char *, ...);
205 extern void __gfinform(int32, word32, int32, char *, ...);
206 extern void __gferr(int32, word32, int32, char *, ...);
207 extern void __sgferr(int32, char *, ...);
208 extern void __ia_err(int32, char *, ...);
209 extern void __dbg_msg(char *, ...);
210 extern void __sgfinform(int32, char *, ...);
211 extern void __arg_terr(char *, int32);
212 extern void __case_terr(char *, int32);
213 extern void __misc_terr(char *, int32);
214 extern void __misc_sgfterr(char *, int32);
215
216 extern struct opinfo_t __opinfo[];
217 extern word32 __masktab[];
218
219 /*
220 * ROUTINES TO PROCESS AND CHECK RHS EXPRESSIONS
221 */
222
223 /*
224 * routine to check a rhs expr.
225 * order must be structural, fold all constant (folds params), and
226 * finally check all embedded selects
227 *
228 * all there is to rhs expression checking
229 */
__chk_rhsexpr(struct expr_t * ndp,int32 csiz)230 extern int32 __chk_rhsexpr(struct expr_t *ndp, int32 csiz)
231 {
232 int32 saverr_cnt;
233
234 saverr_cnt = __pv_err_cnt;
235 /* intercept and convert any selects from paramters to num or is num */
236 /* this finds all in expr. - returns F if error */
237 if (!__isleaf(ndp))
238 {
239 try_cnvt_parmsel_toconst(ndp);
240 if (saverr_cnt != __pv_err_cnt) return(FALSE);
241 }
242
243 /* this can also be called before parameter values (fixed) */
244 /* substitution to real operator done here */
245 chk_struct_rhsexpr(ndp, csiz);
246 /* in case expr. contains declared non wire symbol cannot try to fold */
247 if (saverr_cnt != __pv_err_cnt) return(FALSE);
248
249 /* emit warning for word32 relations comparisons - needed before folding */
250 chk_mixedsign_relops(ndp);
251
252 /* LOOKATME - is here a problem folding analog expressions */
253 /* notice that width know everywhere - so if correct all folding right */
254 /* if error still to be caught, will make reasonable guess for width */
255 fold_subexpr(ndp);
256 /* after folding need checking that requires fold constants */
257 /* for selects and function call arguments */
258 chk_ndfolded_specops(ndp);
259 if (ndp->is_real) ndp->ibase = BDBLE;
260
261 if (saverr_cnt != __pv_err_cnt) return(FALSE);
262 return(TRUE);
263 }
264
265 /*
266 * convert all selects from parameters into constants
267 */
try_cnvt_parmsel_toconst(struct expr_t * ndp)268 static void try_cnvt_parmsel_toconst(struct expr_t *ndp)
269 {
270 struct net_t *np;
271
272 if (__isleaf(ndp)) return;
273 if (ndp->optyp == LSB)
274 {
275 np = ndp->lu.x->lu.sy->el.enp;
276 if (np->n_isaparam && !np->nu.ct->p_specparam)
277 cnvt_paramsel_toconst(ndp, np);
278 else try_cnvt_parmsel_toconst(ndp->ru.x);
279 return;
280 }
281 if (ndp->optyp == PARTSEL)
282 {
283 np = ndp->lu.x->lu.sy->el.enp;
284 if (np->n_isaparam && !np->nu.ct->p_specparam)
285 cnvt_paramsel_toconst(ndp, np);
286 else
287 {
288 try_cnvt_parmsel_toconst(ndp->ru.x->lu.x);
289 try_cnvt_parmsel_toconst(ndp->ru.x->ru.x);
290 }
291 return;
292 }
293
294 if (ndp->lu.x != NULL)
295 {
296 if (!__isleaf(ndp->lu.x)) try_cnvt_parmsel_toconst(ndp->lu.x);
297 }
298 if (ndp->ru.x != NULL)
299 {
300 if (!__isleaf(ndp->ru.x)) try_cnvt_parmsel_toconst(ndp->ru.x);
301 }
302 }
303
304 /*
305 * intercept before any checking and convert to number or IS number
306 *
307 * returns F on error - must set width and handle all checking
308 * since no more processing for this rhs expr.
309 * works because nothing under here - changes guts and under of ndp to num.
310 * know current module in cur mod
311 *
312 * LOOKATME - now handle constant selects from parameter arrays
313 */
cnvt_paramsel_toconst(struct expr_t * ndp,struct net_t * np)314 static void cnvt_paramsel_toconst(struct expr_t *ndp, struct net_t *np)
315 {
316 struct expr_t *ndx1, *ndx2;
317 char selnam[RECLEN], s1[RECLEN];
318
319 /* parameter array index ok for reals, anything else is error */
320 if (np->ntyp == N_REAL && !np->n_isarr)
321 {
322 __sgferr(896, "bit or part select from real parameter %s illegal",
323 np->nsym->synam);
324 return;
325 }
326 if (np->n_isarr && ndp->optyp == PARTSEL)
327 {
328 __sgferr(896, "part select from parameter array %s illegal",
329 np->nsym->synam);
330 return;
331 }
332
333 if (np->n_isarr) strcpy(selnam, "array");
334 else if (np->n_isavec) strcpy(selnam, "bit");
335 else
336 {
337 __sgferr(896, "select from scalar parameter %s illegal", np->nsym->synam);
338 return;
339 }
340 /* step 1: check and convert indices to 32 bit values */
341 if (ndp->optyp == LSB)
342 {
343 /* index must be correct rhs expr. */
344 ndx1 = ndp->ru.x;
345 ndx2 = NULL;
346 if (!__chk_rhsexpr(ndx1, 0)) return;
347 if (ndx1->optyp != NUMBER && ndx1->optyp != ISNUMBER)
348 {
349 /* SJM 11/14/03 - must allow variable bsel from param during sim */
350 if (!np->n_isarr)
351 {
352 return;
353 }
354 else
355 {
356 __sgferr(926,
357 "parameter %s select %s[%s] index must be constant expression",
358 selnam, np->nsym->synam, __msgexpr_tostr(__xs, ndx1));
359 }
360 return;
361 }
362 /* convert to either number or is number, 32 bits - maybe x */
363 sprintf(s1, "parameter %s select index", selnam);
364 __nd_ndxnum(ndx1, s1, FALSE);
365 }
366 else if (ndp->optyp == PARTSEL)
367 {
368 ndx1 = ndp->ru.x->lu.x;
369 if (!__chk_rhsexpr(ndx1, 0)) return;
370 __nd_ndxnum(ndx1, "parmeter part select first index",
371 FALSE);
372 ndx2 = ndp->ru.x->ru.x;
373 if (!__chk_rhsexpr(ndx2, 0)) return;
374 __nd_ndxnum(ndx2, "parameter part select second index",
375 FALSE);
376 if (ndx1->optyp != NUMBER && ndx1->optyp != ISNUMBER
377 && ndx2->optyp != NUMBER && ndx2->optyp != ISNUMBER)
378 {
379 __sgferr(926,
380 "parameter %s part select %s both indices must be constant expressions",
381 np->nsym->synam, __msgexpr_tostr(__xs, ndp));
382 return;
383 }
384 }
385 else
386 {
387 __sgferr(822,
388 "bit select from parameter %s index expression non constant",
389 np->nsym->synam);
390 return;
391 }
392 if (ndp->optyp == LSB)
393 {
394 if (ndx1->optyp == NUMBER && np->srep == SR_PNUM)
395 { cnvt_nonis_selparm(np, ndp, ndx1); return; }
396 if (np->n_isarr) cnvt_is_arrselparm(np, ndp, ndx1);
397 else cnvt_is_bselparm(np, ndp, ndx1);
398 return;
399 }
400 /* these return F if out of range or x for either index */
401 if (ndx1->optyp == NUMBER && ndx2->optyp == NUMBER && np->srep == SR_PNUM)
402 cnvt_nonis_pselparm(np, ndp, ndx1, ndx2);
403 else cnvt_is_pselparm(np, ndp, ndx1, ndx2);
404 }
405
406 /*
407 * convert a parameter non IS bit select to 1 bit constant
408 * or convert parameter array select to value
409 */
cnvt_nonis_selparm(struct net_t * np,struct expr_t * ndp,struct expr_t * ndx)410 static void cnvt_nonis_selparm(struct net_t *np, struct expr_t *ndp,
411 struct expr_t *ndx)
412 {
413 int32 bi, wlen;
414 word32 *wp, av, bv;
415 struct xstk_t *xsp;
416
417 bi = get_nonis_param_ndx(np, ndx);
418 if (!np->n_isarr)
419 {
420 if (bi == -1) av = bv = 1L;
421 else
422 {
423 wlen = wlen_(np->nwid);
424 wp = np->nva.wp;
425 av = rhsbsel_(wp, bi);
426 bv = rhsbsel_(&(wp[wlen]), bi);
427 }
428 __free2_xtree(ndp);
429 __init_xnd(ndp);
430 __set_numval(ndp, av, bv, 1);
431 }
432 else
433 {
434 wlen = wlen_(np->nwid);
435 __free2_xtree(ndp);
436 __init_xnd(ndp);
437 ndp->optyp = NUMBER;
438 ndp->szu.xclen = np->nwid;
439
440 /* parameter arrays never packed */
441 if (bi == -1)
442 {
443 if (np->nwid == WBITS)
444 {
445 ndp->ru.xvi = __alloc_shareable_cval(ALL1W, ALL1W, np->nwid);
446 }
447 else
448 {
449 push_xstk_(xsp, np->nwid);
450 one_allbits_(xsp->ap, np->nwid);
451 one_allbits_(xsp->bp, np->nwid);
452 ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, wlen);
453 __pop_xstk();
454 }
455 }
456 else
457 {
458 wp = &(np->nva.wp[2*wlen*bi]);
459 if (np->nwid <= WBITS)
460 {
461 ndp->ru.xvi = __alloc_shareable_cval(wp[0], wp[1], np->nwid);
462 }
463 else
464 {
465 ndp->ru.xvi = __allocfill_cval_new(wp, &(wp[wlen]), wlen);
466 }
467 }
468 }
469 ndp->consubxpr = TRUE;
470 ndp->folded = TRUE;
471 }
472
473 /*
474 * convert a parameter IS bit select to 1 bit constant
475 * know result is an IS constant
476 */
cnvt_is_bselparm(struct net_t * np,struct expr_t * ndp,struct expr_t * ndx)477 static void cnvt_is_bselparm(struct net_t *np, struct expr_t *ndp,
478 struct expr_t *ndx)
479 {
480 register int32 ii;
481 int32 bi, nbytes, wlen, tmpxvi;
482 word32 *wp, *wp2, av, bv;
483
484 /* bit select will be 1 bit IS constant */
485 nbytes = __inst_mod->flatinum*2*WRDBYTES;
486
487 /* must not change ndp since still need to access ndx values */
488 /* passes number of words in a part alloc multiplies by 2 for b part too */
489 tmpxvi = __alloc_is_cval(__inst_mod->flatinum);
490 wp = &(__contab[tmpxvi]);
491 memset(wp, 0, nbytes);
492
493 wlen = wlen_(np->nwid);
494 for (ii = 0; ii < __inst_mod->flatinum; ii++)
495 {
496 if (ndx->optyp == NUMBER) bi = get_nonis_param_ndx(np, ndx);
497 else if (ndx->optyp == ISNUMBER) bi = get_is_param_ndx(np, ndx, ii);
498 else { __case_terr(__FILE__, __LINE__); bi = 0; }
499 if (bi == -1) av = bv = 1L;
500 else
501 {
502 wp2 = np->nva.wp;
503 if (np->srep == SR_PISNUM) wp2 = &(wp2[2*wlen*ii]);
504 av = rhsbsel_(wp2, bi);
505 bv = rhsbsel_(&(wp2[wlen]), bi);
506 }
507 wp[2*ii] = av;
508 wp[2*ii + 1] = bv;
509 }
510
511 /* notice can't free ndp because need to acc ndx (that is contained in it) */
512 __free2_xtree(ndp);
513 __init_xnd(ndp);
514 /* create IS number expr node and then fill it */
515 ndp->optyp = ISNUMBER;
516 ndp->szu.xclen = 1;
517 ndp->ru.xvi = tmpxvi;
518 ndp->consubxpr = TRUE;
519 ndp->consub_is = TRUE;
520 ndp->folded = TRUE;
521 }
522
523 /*
524 * convert a parameter IS array select to constant
525 * know result is an IS constant
526 */
cnvt_is_arrselparm(struct net_t * np,struct expr_t * ndp,struct expr_t * ndx)527 static void cnvt_is_arrselparm(struct net_t *np, struct expr_t *ndp,
528 struct expr_t *ndx)
529 {
530 register int32 ii;
531 register word32 *wp, *wp2;
532 int32 bi, wsiz, wlen, tmpxvi;
533
534 wlen = wlen_(np->nwid);
535 wsiz = __inst_mod->flatinum*wlen;
536 /* must not change ndp since still need to access ndx values */
537 tmpxvi = __alloc_is_cval(wsiz);
538 wp = &(__contab[tmpxvi]);
539 memset(wp, 0, 2*WRDBYTES*wsiz);
540
541 for (ii = 0; ii < __inst_mod->flatinum; ii++)
542 {
543 if (ndx->optyp == NUMBER) bi = get_nonis_param_ndx(np, ndx);
544 else if (ndx->optyp == ISNUMBER) bi = get_is_param_ndx(np, ndx, ii);
545 else { __case_terr(__FILE__, __LINE__); bi = 0; }
546
547 /* array select is 2*wlen value */
548 wp2 = np->nva.wp;
549 if (np->srep == SR_PISNUM) wp2 = &(wp2[2*wlen*ii]);
550
551 if (bi == -1)
552 {
553 one_allbits_(&(wp[2*wlen*ii]), np->nwid);
554 one_allbits_(&(wp[2*wlen*ii + wlen]), np->nwid);
555 }
556 else memcpy(&(wp[2*wlen*ii]), wp2, 2*WRDBYTES*wlen);
557 }
558
559 __free2_xtree(ndp);
560 __init_xnd(ndp);
561 ndp->optyp = ISNUMBER;
562 ndp->szu.xclen = np->nwid;
563 ndp->ru.xvi = tmpxvi;
564 ndp->consubxpr = TRUE;
565 ndp->consub_is = TRUE;
566 ndp->folded = TRUE;
567 }
568
569 /*
570 * access a non IS parameter index expr.
571 * SJM - 08/23/00 - allow rng on params - rng h:0 if no declared range
572 */
get_nonis_param_ndx(struct net_t * np,struct expr_t * ndx)573 static int32 get_nonis_param_ndx(struct net_t *np, struct expr_t *ndx)
574 {
575 register word32 *wp;
576 register int32 bi;
577 int32 ri1, ri2, awid, bi1;
578
579 wp = &(__contab[ndx->ru.xvi]);
580 /* if x/z, warning already emitted but must return -1 */
581 if (wp[1] != 0L) { bi = -1; return(bi); }
582
583 /* SJM 09/11/00 - SJM - must check for unnormalized range */
584 if (np->n_isarr) __getarr_range(np, &ri1, &ri2, &awid);
585 else __getwir_range(np, &ri1, &ri2);
586 if (ri1 >= ri2)
587 {
588 if (wp[0] > ri1 || wp[0] < ri2)
589 {
590 bad_rng:
591 __sgfwarn(586,
592 "parameter %s select index %d out of range [%d:%d]",
593 np->nsym->synam, (int32) wp[0], ri1, ri2);
594 bi = -1;
595 return(bi);
596 }
597 }
598 else { if (wp[0] < ri1 || wp[0] > ri2) goto bad_rng; }
599 bi1 = (int32) wp[0];
600 bi = normalize_ndx_(bi1, ri1, ri2);
601 return(bi);
602 }
603
604 /*
605 * access an IS parameter index expr.
606 * need special routine since no range for parameters
607 * know since index converted to 32 bit IS form before here
608 */
get_is_param_ndx(struct net_t * np,struct expr_t * ndx,int32 ii)609 static int32 get_is_param_ndx(struct net_t *np, struct expr_t *ndx, int32 ii)
610 {
611 register int32 bi;
612 register word32 *wp;
613 int32 bi1, ri1, ri2, awid;
614 word32 wval;
615
616 wp = &(__contab[ndx->ru.xvi]);
617 /* if x/z, warning already emitted */
618 if (wp[2*ii + 1] != 0L) { bi = -1; return(bi); }
619
620 /* SJM 09/11/00 - SJM - must check for unnormalized range */
621 if (np->n_isarr) __getarr_range(np, &ri1, &ri2, &awid);
622 else __getwir_range(np, &ri1, &ri2);
623 wval = wp[2*ii];
624 if (ri1 >= ri2)
625 {
626 if (wval > ri1 || wval < ri2)
627 {
628 bad_rng:
629 __sgfwarn(586,
630 "parameter %s (instance %s) select index %d out of range [%d:%d]",
631 np->nsym->synam, __msg2_blditree(__xs, __inst_mod->moditps[ii]),
632 wval, ri1, ri2);
633 bi = -1;
634 return(bi);
635 }
636 }
637 else { if (wval < ri1 || wval > ri2) goto bad_rng; }
638 /* good range */
639 bi1 = (int32) wval;
640 bi = normalize_ndx_(bi1, ri1, ri2);
641 return(bi);
642 }
643
644 /*
645 * convert a parameter non IS part select to psel width constant
646 * constants are stored in minimum 8 byte values
647 */
cnvt_nonis_pselparm(struct net_t * np,struct expr_t * ndp,struct expr_t * ndx1,struct expr_t * ndx2)648 static void cnvt_nonis_pselparm(struct net_t *np, struct expr_t *ndp,
649 struct expr_t *ndx1, struct expr_t *ndx2)
650 {
651 int32 bi1, bi2, pselwid, wlen;
652 word32 *wp2;
653 struct xstk_t *xsp;
654
655 /* parameters always range [(width - 1) to 0] */
656 bi1 = get_nonis_param_ndx(np, ndx1);
657 bi2 = get_nonis_param_ndx(np, ndx2);
658 if (bi1 == -1 || bi2 == -1)
659 {
660 __sgferr(1045,
661 "parameter part select %s (width %d) index(s) x/z, out of range",
662 __msgexpr_tostr(__xs, ndp), np->nwid);
663 return;
664 }
665 if (bi1 < bi2) pselwid = bi2 - bi1 + 1;
666 else pselwid = bi1 - bi2 + 1;
667
668 __free2_xtree(ndp);
669 __init_xnd(ndp);
670 ndp->optyp = NUMBER;
671 ndp->szu.xclen = pselwid;
672 ndp->consubxpr = TRUE;
673 ndp->folded = TRUE;
674
675 /* can't use shareable here becuase need to psel to set value */
676 push_xstk_(xsp, pselwid);
677 wlen = wlen_(np->nwid);
678 wp2 = np->nva.wp;
679 __rhspsel(xsp->ap, wp2, bi2, pselwid);
680 __rhspsel(xsp->bp, &(wp2[wlen]), bi2, pselwid);
681 ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, wlen_(pselwid));
682 __pop_xstk();
683 return;
684 }
685
686 /*
687 * convert a parameter IS bit select to 1 bit constant
688 * know result is an IS constant
689 */
cnvt_is_pselparm(struct net_t * np,struct expr_t * ndp,struct expr_t * ndx1,struct expr_t * ndx2)690 static void cnvt_is_pselparm(struct net_t *np, struct expr_t *ndp,
691 struct expr_t *ndx1, struct expr_t *ndx2)
692 {
693 register int32 ii;
694 int32 bi1, bi2, xwlen, wlen, wlen2, err, pselwid, tmp, tmpxvi;
695 word32 *wp, *wp2;
696
697 pselwid = 0;
698 for (err = FALSE, ii = 0; ii < __inst_mod->flatinum; ii++)
699 {
700 /* parameters always range [(width - 1) to 0] */
701 if (ndx1->optyp == NUMBER) bi1 = get_nonis_param_ndx(np, ndx1);
702 else bi1 = get_is_param_ndx(np, ndx1, ii);
703 if (ndx2->optyp == NUMBER) bi2 = get_nonis_param_ndx(np, ndx2);
704 else bi2 = get_is_param_ndx(np, ndx2, ii);
705 if (bi1 == -1 || bi2 == -1)
706 {
707 __sgferr(1045,
708 "parameter part select %s (width %d) (instance %s) index(s) x/z, out of range",
709 __msgexpr_tostr(__xs, ndp), np->nwid, __msg2_blditree(__xs,
710 __inst_mod->moditps[ii]));
711 err = TRUE;
712 }
713 if (bi1 < bi2) tmp = bi2 - bi1 + 1;
714 else tmp = bi1 - bi2 + 1;
715 /* constant is widest in case IS form indices */
716 if (tmp > pselwid) pselwid = tmp;
717 }
718 if (err) return;
719
720 xwlen = __inst_mod->flatinum*wlen_(pselwid);
721 /* must not change ndp since still need to access ndx values */
722 tmpxvi = __alloc_is_cval(xwlen);
723 wp = &(__contab[tmpxvi]);
724 memset(wp, 0, 2*xwlen*WRDBYTES);
725
726 wlen = wlen_(pselwid);
727 wlen2 = wlen_(np->nwid);
728 for (ii = 0; ii < __inst_mod->flatinum; ii++)
729 {
730 if (ndx1->optyp == NUMBER) bi1 = get_nonis_param_ndx(np, ndx1);
731 else bi1 = get_is_param_ndx(np, ndx1, ii);
732 if (ndx2->optyp == NUMBER) bi2 = get_nonis_param_ndx(np, ndx2);
733 else bi2 = get_is_param_ndx(np, ndx2, ii);
734
735 wp2 = np->nva.wp;
736 if (np->srep == SR_PISNUM) wp2 = &(wp2[2*wlen2*ii]);
737
738 tmp = bi1 - bi2 + 1;
739 /* can part select into section of constant providing starts at 0 */
740 /* tmp can be narrower than psel wid */
741 __rhspsel(&(wp[2*wlen*ii]), wp2, bi2, tmp);
742 __rhspsel(&(wp[2*wlen*ii + wlen]), &(wp2[wlen2]), bi2, tmp);
743 }
744
745 __free2_xtree(ndp);
746 __init_xnd(ndp);
747 ndp->optyp = ISNUMBER;
748 ndp->szu.xclen = pselwid;
749 ndp->ru.xvi = tmpxvi;
750 ndp->consubxpr = TRUE;
751 ndp->consub_is = TRUE;
752 ndp->folded = TRUE;
753 return;
754 }
755
756 /*
757 * SOURCE (STRUCTURAL) RHS EXPRESSION CHECKING
758 */
759
760 /*
761 * check gate/inst array index parameter expression
762 * return F on error (i.e. no constant)
763 *
764 * special case because needed before parameters set to final values
765 * if wider than 32 bits or has x/zs caught after expr. eval
766 */
__chk_giarr_ndx_expr(struct expr_t * ndp)767 extern int32 __chk_giarr_ndx_expr(struct expr_t *ndp)
768 {
769 chk_struct_rhsexpr(ndp, 0);
770 /* emit warning for word32 relations comparisons */
771 chk_mixedsign_relops(ndp);
772
773 /* real not allowed */
774 if (__is_paramconstxpr(ndp, FALSE)) return(TRUE);
775 return(TRUE);
776 }
777
778 /*
779 * check either defparam or specparam rhs expr.
780 * cannot go through chk rhs expr here since some rhs stuff not allowed
781 */
__chk_paramexpr(struct expr_t * ndp,int32 xwid)782 extern int32 __chk_paramexpr(struct expr_t *ndp, int32 xwid)
783 {
784 /* FIXME - need to allow const user function calls in param rhs exprs */
785 /* SJM 03/13/00 - now built-in sys funcs ok - chk later for non const args */
786 if (xpr_has_nonsys_fcall(ndp)) return(FALSE);
787
788 chk_struct_rhsexpr(ndp, xwid);
789 if (ndp->is_real) ndp->ibase = BDBLE;
790 /* emit warning for word32 relations comparisons */
791 chk_mixedsign_relops(ndp);
792
793 if (__is_paramconstxpr(ndp, TRUE)) return(TRUE);
794 return(FALSE);
795 }
796
797 /*
798 * return T if parameter constant expr. - else F (for ID)
799 * if expr. contains anything but numbers and correct type of param return F
800 *
801 * this is for both def params and spec params
802 * notice for spec param can never be IS form
803 */
__is_paramconstxpr(struct expr_t * ndp,int32 realok)804 extern int32 __is_paramconstxpr(struct expr_t *ndp, int32 realok)
805 {
806 int32 rv1, rv2;
807 struct sy_t *syp;
808 struct net_t *np;
809 struct expr_t *fandp;
810
811 switch ((byte) ndp->optyp) {
812 case NUMBER: return(TRUE);
813 case REALNUM:
814 if (!realok) return(FALSE);
815 return(TRUE);
816
817 /* can only make ISNUMBER after def/# param assignment */
818 case ISNUMBER: case ISREALNUM:
819 __arg_terr(__FILE__, __LINE__);
820 break;
821 case ID:
822 /* previously defined parameter ok */
823 syp = ndp->lu.sy;
824 if (!syp->sydecl) return(FALSE);
825 np = syp->el.enp;
826 if (np->n_isaparam)
827 {
828 /* SJM 02/04/00 - error if parameter used on RHS of specparam */
829 if (__cur_declobj == SPECIFY && !np->nu.ct->p_specparam) return(FALSE);
830 return(TRUE);
831 }
832 return(FALSE);
833 case GLBREF: return(FALSE);
834 /* SJM - 08/22/00 - selects from bit and part selects need to work */
835 /* case LSB: case PARTSEL: */
836 /* return(FALSE); */
837 case FCALL:
838 /* getting output width, so have right context elsewhere */
839 /* do not need to get arg. width since call shields */
840 syp = ndp->lu.x->lu.sy;
841 if (syp->sytyp != SYM_SF) return(FALSE);
842 if (syp->el.esyftbp->tftyp != SYSF_BUILTIN) return(FALSE);
843 if (!realok)
844 { if (syp->el.esyftbp->retntyp == N_REAL) return(FALSE); }
845 /* SJM 09/04/01 - for special constant sys funcs must check arg num here */
846 /* args must also be constant - first in expr list is return expr */
847 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
848 {
849 /* LOOKATME - even if real param not allowed arg to const systf */
850 /* can be real */
851 if (!__is_paramconstxpr(fandp->lu.x, TRUE)) return(FALSE);
852 }
853 return(TRUE);
854 }
855 rv1 = rv2 = TRUE;
856 if (ndp->lu.x != NULL) rv1 = __is_paramconstxpr(ndp->lu.x, realok);
857 if (ndp->ru.x != NULL) rv2 = __is_paramconstxpr(ndp->ru.x, realok);
858 if (rv1 && rv2) return(TRUE);
859 return(FALSE);
860 }
861
862 /*
863 * check a rhs expression for structural correctness
864 *
865 * only needs info available during pass 1
866 * all rhs expressions must be processed through here
867 * needs __sfnam_ind to be set before called
868 *
869 * this checks and changes structural things but does not
870 * do any evaluating or substituting or folding since needed during
871 * source input to determine parameters
872 *
873 * when done all node widths sets, all real operators substituted
874 * and all concatenates 1 level with no repeat forms
875 * if error that will prevent simulation, emitted here
876 *
877 * not done: part select and bit select normalization and range checking
878 * constant folding, conversion to WBITS values for indices and ranges
879 */
chk_struct_rhsexpr(struct expr_t * ndp,int32 xwid)880 static void chk_struct_rhsexpr(struct expr_t *ndp, int32 xwid)
881 {
882 /* handle all leaves (special fast cases) */
883 switch ((byte) ndp->optyp) {
884 case OPEMPTY: return;
885 case NUMBER: case ISNUMBER: return;
886 case REALNUM: case ISREALNUM:
887 ndp->is_real = TRUE;
888 /* reals always signed */
889 ndp->has_sign = TRUE;
890 __expr_has_real = TRUE;
891 return;
892 case ID: case GLBREF:
893 /* here must set width if possible */
894 if (chk_rhs_id(ndp)) ndp->szu.xclen = __get_netwide(ndp->lu.sy->el.enp);
895 else ndp->szu.xclen = 1;
896 return;
897 }
898 /* must next unwind all concatenates in expr. bottom up */
899 /* result is 1 level only simple concats */
900 unwind_rhsconcats(ndp);
901
902 /* SJM 09/11/03 - because XL/NC support 0 width concat elements, must */
903 /* remove any 0 width one from concat here - if now empty syntax error */
904 if (__nd_0width_catel_remove)
905 {
906 remove_0width_catrep_els(ndp);
907 __nd_0width_catel_remove = FALSE;
908 }
909
910 __expr_has_real = FALSE;
911 /* set widths and turn on flag if any reals in expr. */
912 /* also sets is_real for real constants and variables */
913 set_rhswidth(ndp, xwid);
914
915 if (__expr_has_real) setchk_real_expr(ndp);
916
917 /* 10/02/03 - use new 2001 LRM rules to set expr has sign bit */
918 set_rhs_signed(ndp);
919
920 /* check any special (bsel, psel, fcall, etc.) in rhs expr. */
921 /* this leave bit select and part select expressions as is */
922 /* must normalize and convert to WBITS number some where is const. */
923 chk_specialop_rhsexpr(ndp);
924 }
925
926 /*
927 * check a rhs identifier
928 * for global checks target
929 */
chk_rhs_id(struct expr_t * ndp)930 static int32 chk_rhs_id(struct expr_t *ndp)
931 {
932 struct net_t *np;
933 struct sy_t *syp;
934
935 syp = ndp->lu.sy;
936 /* cross module reference not yet resolved - caller will emit error */
937 if (syp == NULL) return(FALSE);
938
939 if (!syp->sydecl) return(FALSE);
940
941 if (syp->sytyp != SYM_N)
942 {
943 __sgferr(1040, "%s %s illegal in right side expression - must be variable",
944 __to_sytyp(__xs, syp->sytyp), __to_idnam(ndp));
945 return(FALSE);
946 }
947
948 /* this check for illegal expr. unindexed array and event */
949 /* params and real marking handled here also */
950 np = syp->el.enp;
951 if (np->ntyp == N_EVENT)
952 {
953 __sgferr(893, "event %s illegal in right hand side expression",
954 __to_idnam(ndp));
955 return(FALSE);
956 }
957 if (np->n_isarr)
958 {
959 __sgferr(894,
960 "illegal unindexed array reference of %s in right hand side expression",
961 __to_idnam(ndp));
962 return(FALSE);
963 }
964 /* any rhs wire expr. node must be signed if wire is */
965 if (np->n_signed) ndp->has_sign = TRUE;
966 if (np->n_stren) ndp->x_stren = TRUE;
967 if (np->ntyp == N_REAL)
968 { ndp->is_real = TRUE; ndp->has_sign = TRUE; __expr_has_real = TRUE; }
969 if (np->nrngrep == NX_CT) np->nu.ct->n_onrhs = TRUE;
970 if (!__expr_rhs_decl) np->n_onprocrhs = TRUE;
971 return(TRUE);
972 }
973
974 /*
975 * check and unwind all rhs concatenates
976 *
977 * this will create any repeat form concatenates it needs to
978 * when done concatenate is one level with catreps removed
979 * concatenate constant folding if implemented must be done after here
980 *
981 * notice this will unwind concatenates in fcall arguments
982 */
unwind_rhsconcats(struct expr_t * ndp)983 static void unwind_rhsconcats(struct expr_t *ndp)
984 {
985 if (__isleaf(ndp)) return;
986
987 /* DBG ---
988 if (__debug_flg)
989 __dbg_msg("## unwinding concat %s\n", __msgexpr_tostr(__xs, ndp));
990 --- */
991
992 /* concatenate unwinding must be done bottom up */
993 if (ndp->lu.x != NULL)
994 {
995 /* DBG ---
996 if (__debug_flg)
997 __dbg_msg("## left side %s\n", __msgexpr_tostr(__xs, ndp->lu.x));
998 --- */
999 unwind_rhsconcats(ndp->lu.x);
1000 /* DBG ---
1001 if (__debug_flg) __dbg_msg("^^ left up.\n");
1002 --- */
1003 }
1004 if (ndp->ru.x != NULL)
1005 {
1006 /* DBG ---
1007 if (__debug_flg)
1008 __dbg_msg("## right side %s\n", __msgexpr_tostr(__xs, ndp->ru.x));
1009 --- */
1010 unwind_rhsconcats(ndp->ru.x);
1011 /* DBG ---
1012 if (__debug_flg) __dbg_msg("^^ right up.\n");
1013 --- */
1014 }
1015
1016 /* node is top of concatenate with all sub concatenates simplified */
1017 if (ndp->optyp == LCB)
1018 {
1019 register struct expr_t *ndp2;
1020 struct expr_t *last_ndp2, *end_ndp;
1021
1022 last_ndp2 = ndp;
1023 for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1024 {
1025 struct expr_t *lop;
1026
1027 lop = ndp2->lu.x;
1028 /* notice ,, form illegal in concatentate */
1029 switch ((byte) lop->optyp) {
1030 case NUMBER: case ISNUMBER:
1031 if (lop->unsiznum)
1032 __sgferr(897, "unsized number illegal in concatenate");
1033 break;
1034 case REALNUM: case ISREALNUM:
1035 __sgferr(813, "real number illegal in concatenate");
1036 break;
1037 case LCB:
1038 {
1039 /* nested concatenate - splice up one level */
1040 last_ndp2->ru.x = lop->ru.x;
1041 /* find rightmost element - know always there */
1042 end_ndp = __find_catend(lop);
1043 /* if rightmost up one node will make null */
1044 end_ndp->ru.x = ndp2->ru.x;
1045 /* end of new chain is new last */
1046 last_ndp2 = end_ndp;
1047 }
1048 continue;
1049 case CATREP:
1050 {
1051 int32 repval;
1052 struct expr_t *dupndp;
1053 struct xstk_t *xsp;
1054
1055 if (__chk_paramexpr(lop->lu.x, 0))
1056 {
1057 xsp = __eval_xpr(lop->lu.x);
1058 if (xsp->xslen > WBITS)
1059 {
1060 if (!vval_is0_(&(xsp->ap[1]), xsp->xslen - WBITS)
1061 || !vval_is0_(&(xsp->bp[1]), xsp->xslen - WBITS)
1062 || xsp->bp[0] != 0L) goto bad_rep;
1063 }
1064 else if (xsp->bp[0] != 0) goto bad_rep;
1065
1066 repval = (int32) xsp->ap[0];
1067 /* SJM 09/11/03 - also need error for negative */
1068 if (repval < 0) goto bad_rep;
1069 else if (repval == 0)
1070 {
1071 __sgfwarn(3109,
1072 "concatenate repeat value of 0 causes removal of concatenate");
1073 }
1074 else if (repval == 1)
1075 __sgfinform(442, "concatenate repeat value of 1 has no effect");
1076 }
1077 else
1078 {
1079 bad_rep:
1080 __sgferr(814,
1081 "concatenate repeat value %s not a non negative constant expression",
1082 __msgexpr_tostr(__xs, lop->lu.x));
1083 repval = 1;
1084 }
1085
1086 __pop_xstk();
1087 if (repval == 0)
1088 {
1089 /* SJM 09/11/03 - contradicts 2001 LRM but 0 width removed */
1090 /* from concatenate, but because of possibility of recursive */
1091 /* upward removal must insert size 1 and remove later */
1092 /* and if remove creates empty concat, then emit syntax error */
1093 dupndp = __dup_concat(1, lop->ru.x->ru.x);
1094 dupndp->folded = TRUE;
1095 __nd_0width_catel_remove = TRUE;
1096 }
1097 else
1098 {
1099 /* know the rhs thing must be a concatenate */
1100 dupndp = __dup_concat(repval, lop->ru.x->ru.x);
1101 }
1102
1103 /* nested concatenate - splice up one level */
1104 last_ndp2->ru.x = dupndp;
1105 /* find rightmost element - know always there */
1106 end_ndp = __find_catend(dupndp);
1107
1108 /* if rightmost up one node will make null */
1109 end_ndp->ru.x = ndp2->ru.x;
1110 /* end of new chain is new last */
1111 last_ndp2 = end_ndp;
1112 }
1113 continue;
1114 }
1115 /* NUMBER or other means move last down tree one */
1116 last_ndp2 = ndp2;
1117 }
1118 }
1119 }
1120
1121 /*
1122 * return TRUE if node is leaf node (id, glbid, number)
1123 */
__isleaf(struct expr_t * ndp)1124 extern int32 __isleaf(struct expr_t *ndp)
1125 {
1126 switch ((byte) ndp->optyp) {
1127 case ID: case GLBREF: case NUMBER: case ISNUMBER:
1128 case REALNUM: case ISREALNUM: case OPEMPTY:
1129 return(TRUE);
1130 }
1131 return(FALSE);
1132 }
1133
1134 /*
1135 * duplicate a single level no embedded CATREP concatenate
1136 */
__dup_concat(int32 repcnt,struct expr_t * catndp)1137 extern struct expr_t *__dup_concat(int32 repcnt, struct expr_t *catndp)
1138 {
1139 register int32 w;
1140 struct expr_t *dupndp, *newndp, *end_ndp;
1141
1142 /* now build longer chain repeated repval - 1 times */
1143 for (newndp = NULL, w = 0; w < repcnt; w++)
1144 {
1145 /* make one copy */
1146 if (w < repcnt - 1) dupndp = __copy_expr(catndp); else dupndp = catndp;
1147 if (newndp == NULL) newndp = dupndp;
1148 else
1149 {
1150 end_ndp = __find_catend(dupndp);
1151 end_ndp->ru.x = newndp;
1152 newndp = dupndp;
1153 }
1154 }
1155 return(newndp);
1156 }
1157
1158 /*
1159 * find the end (rightmost CATCOM) of a one level concatenate chain
1160 * expects to be passed LCB concatenate chain header
1161 */
__find_catend(struct expr_t * catndp)1162 extern struct expr_t *__find_catend(struct expr_t *catndp)
1163 {
1164 register struct expr_t *ndp;
1165 struct expr_t *last_ndp;
1166
1167 for (ndp = catndp, last_ndp = NULL; ndp != NULL; ndp = ndp->ru.x)
1168 last_ndp = ndp;
1169 return(last_ndp);
1170 }
1171
1172 /*
1173 * go through linearized concat and remove all marked 0 width elements
1174 *
1175 * if all removed, must emit syntax error and replace now empty concat
1176 * with a 1 bit x concat
1177 *
1178 * BEWARE - using folded to mark removal so must not fold before here
1179 */
remove_0width_catrep_els(struct expr_t * catndp)1180 static void remove_0width_catrep_els(struct expr_t *catndp)
1181 {
1182 register struct expr_t *com_xp, *com_xp2, *last_com_xp;
1183 struct expr_t *rem_com_xp;
1184
1185 last_com_xp = NULL;
1186 rem_com_xp = NULL;
1187 com_xp2 = catndp->ru.x;
1188 for (com_xp = catndp; com_xp != NULL;)
1189 {
1190 if (com_xp->folded)
1191 {
1192 com_xp2 = com_xp->ru.x;
1193
1194 if (last_com_xp == NULL) catndp->ru.x = com_xp->ru.x;
1195 else { last_com_xp->ru.x = com_xp->ru.x; }
1196 if (rem_com_xp == NULL) rem_com_xp = com_xp;
1197
1198 com_xp = com_xp2;
1199 }
1200 else
1201 {
1202 last_com_xp = com_xp;
1203 com_xp = com_xp->ru.x;
1204 }
1205 }
1206 if (catndp->ru.x == NULL)
1207 {
1208 /* DBG remove -- */
1209 if (rem_com_xp == NULL || rem_com_xp->lu.x == NULL)
1210 __misc_terr(__FILE__, __LINE__);
1211 /* -- */
1212
1213 __sgferr(3110,
1214 "concatenate 0 width repeat removal created illegal empty expression");
1215
1216 /* SJM 09/11/03 - notice minor memory leak but can't free exprs here */
1217 __set_numval(rem_com_xp->lu.x, 1, 1, 1);
1218 catndp->ru.x = rem_com_xp;
1219 }
1220 }
1221
1222 /*
1223 * WIDTH SETTING ROUTINES
1224 */
1225
1226 /*
1227 * set all width values of an expression in a given width context
1228 */
set_rhswidth(struct expr_t * rhsx,int32 cwid)1229 static void set_rhswidth(struct expr_t *rhsx, int32 cwid)
1230 {
1231 int32 cwid2, ibas;
1232
1233 cwid2 = __get_rhswidth(rhsx);
1234 if (cwid > cwid2) cwid2 = cwid;
1235 /* if expression wider than context, need expr. max. as context */
1236 set2_rhswidth(rhsx, cwid2);
1237
1238 ibas = find_xbase(rhsx);
1239 if (ibas == '?') ibas = BHEX;
1240 rhsx->ibase = ibas;
1241 }
1242
1243 /*
1244 * calculate the width of a rhs expression
1245 * know width never IS NUMBER form
1246 */
__get_rhswidth(struct expr_t * rhsx)1247 extern int32 __get_rhswidth(struct expr_t *rhsx)
1248 {
1249 int32 wclass, xwid, xwid2, r1, r2, sav_errcnt;
1250 struct net_t *np;
1251 struct expr_t *psx1, *psx2;
1252
1253 xwid = 1;
1254 switch ((byte) rhsx->optyp) {
1255 case ID: case GLBREF:
1256 xwid = __get_netwide(rhsx->lu.sy->el.enp);
1257 break;
1258 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
1259 xwid = rhsx->szu.xclen;
1260 break;
1261 case LSB:
1262 /* bit select or array reference */
1263 np = rhsx->lu.x->lu.sy->el.enp;
1264 /* know this is net or will not get here */
1265 if (np->n_isarr) return(__get_netwide(np));
1266 return(1);
1267 case PARTSEL:
1268 /* this is tricky since constants not yet folded but since params */
1269 /* value known, check (and fold) this sub expression before continuing */
1270 psx1 = rhsx->ru.x->lu.x;
1271 psx2 = rhsx->ru.x->ru.x;
1272 sav_errcnt = __pv_err_cnt;
1273 __chk_rhsexpr(psx1, 0);
1274 __chk_rhsexpr(psx2, 0);
1275 np = rhsx->lu.x->lu.sy->el.enp;
1276 /* error caught later, set to 1 for now */
1277 if (sav_errcnt != __pv_err_cnt || psx1->optyp != NUMBER
1278 || psx2->optyp != NUMBER) xwid = 1;
1279 else
1280 {
1281 r1 = (int32) __contab[psx1->ru.xvi];
1282 r2 = (int32) __contab[psx2->ru.xvi];
1283 xwid = (r1 > r2) ? (r1 - r2 + 1) : (r2 - r1 + 1);
1284 }
1285 break;
1286 case QUEST:
1287 xwid = __get_rhswidth(rhsx->ru.x->ru.x);
1288 xwid2 = __get_rhswidth(rhsx->ru.x->lu.x);
1289 if (xwid2 > xwid) xwid = xwid2;
1290 break;
1291 case FCALL:
1292 {
1293 struct task_t *tskp;
1294 struct task_pin_t *tpp;
1295 struct sy_t *syp;
1296
1297 /* getting output width, so have right context elsewhere */
1298 /* do not need to get arg. width since call shields */
1299 syp = rhsx->lu.x->lu.sy;
1300 if (syp->sytyp == SYM_SF)
1301 {
1302 /* SJM 05/28/04 - $signed and $word32 are special case that return */
1303 /* arg width - but need to recursively call get width to determine */
1304 if (syp->el.esyftbp->syfnum == STN_SIGNED
1305 || syp->el.esyftbp->syfnum == STN_UNSIGNED)
1306 {
1307 xwid = __get_rhswidth(rhsx->ru.x->lu.x);
1308 }
1309 else xwid = syp->el.esyftbp->retwid;
1310 }
1311 /* error caught later */
1312 else if (syp->sytyp == SYM_F)
1313 {
1314 tskp = syp->el.etskp;
1315 tskp->t_used = TRUE;
1316 tpp = tskp->tskpins;
1317 np = tpp->tpsy->el.enp;
1318 xwid = __get_netwide(np);
1319 }
1320 /* if non fcall, leave as 1 bit */
1321 }
1322 return(xwid);
1323 case LCB:
1324 {
1325 register struct expr_t *ndp2;
1326
1327 /* know cat repeats removed by here - component widths set later */
1328 for (xwid = 0, ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1329 {
1330 xwid2 = __get_rhswidth(ndp2->lu.x);
1331 xwid += xwid2;
1332 }
1333 }
1334 break;
1335 default:
1336 /* this is unary or binary op */
1337 wclass = __get_widthclass(rhsx);
1338 switch ((byte) wclass) {
1339 case WIDONE: case WIDENONE: return(1);
1340 case WIDMAX:
1341 if (rhsx->ru.x == NULL) xwid = 0; else xwid = __get_rhswidth(rhsx->ru.x);
1342 if (rhsx->lu.x == NULL) xwid2 = 0; else xwid2 = __get_rhswidth(rhsx->lu.x);
1343 if (xwid2 > xwid) xwid = xwid2;
1344 break;
1345 case WIDLEFT: return(__get_rhswidth(rhsx->lu.x));
1346 case WIDSELF: return(__get_rhswidth(rhsx->lu.x));
1347 default: __case_terr(__FILE__, __LINE__);
1348 }
1349 }
1350 return(xwid);
1351 }
1352
1353 /*
1354 * get an operator's width class
1355 */
__get_widthclass(struct expr_t * rhsx)1356 extern int32 __get_widthclass(struct expr_t *rhsx)
1357 {
1358 struct opinfo_t *opip;
1359
1360 opip = &(__opinfo[rhsx->optyp]);
1361 /* unary form of both always reduction => width one */
1362 if (opip->opclass == BOTHOP && rhsx->ru.x == NULL)
1363 {
1364 /* AIV 03/09/05 - minus is only bothop with lhs cnxt size */
1365 if (rhsx->optyp != MINUS) return(WIDONE);
1366 }
1367 return(opip->reswid);
1368 }
1369
1370 /*
1371 * set rhs width - also mark expr. that are real or stren
1372 *
1373 * SJM 07/16/01 - algorithm here is that operator has correct width that
1374 * may be width of assignment lhs context because in expr eval after
1375 * pushing operands onto xstk, size changes of xstk are made where needed
1376 * according to LRM rules for propagating expression width to interim results
1377 */
set2_rhswidth(struct expr_t * rhsx,int32 cwid)1378 static void set2_rhswidth(struct expr_t *rhsx, int32 cwid)
1379 {
1380 int32 wclass, cat_stren, xwid, xwid2, r1, r2;
1381 struct expr_t *tndp, *ndx1, *ndx2;
1382 struct sy_t *syp;
1383 struct net_t *np;
1384
1385 switch ((byte) rhsx->optyp) {
1386 case ID: case GLBREF:
1387 np = rhsx->lu.sy->el.enp;
1388 /* for real id exprs, expr. is_real bit set in chk id */
1389 if (np->ntyp == N_REAL)
1390 { __expr_has_real = TRUE; rhsx->is_real = TRUE; rhsx->has_sign = TRUE; }
1391 if (np->n_stren) rhsx->x_stren = TRUE;
1392 rhsx->szu.xclen = __get_netwide(np);
1393 return;
1394 case NUMBER: case ISNUMBER: case OPEMPTY: return;
1395 case REALNUM: case ISREALNUM:
1396 /* for real numbers is real bit set in chk id */
1397 __expr_has_real = TRUE;
1398 rhsx->is_real = TRUE;
1399 rhsx->has_sign = TRUE;
1400 return;
1401 case LSB:
1402 /* bit select or array reference */
1403 syp = rhsx->lu.x->lu.sy;
1404 rhsx->lu.x->szu.xclen = __get_netwide(syp->el.enp);
1405 set_rhswidth(rhsx->ru.x, 0);
1406 np = syp->el.enp;
1407 if (np->n_isarr && np->n_isavec) xwid = __get_netwide(np); else xwid = 1;
1408 if (np->n_isarr && np->ntyp == N_REAL)
1409 {
1410 __expr_has_real = TRUE;
1411 rhsx->is_real = TRUE;
1412 rhsx->has_sign = TRUE;
1413 }
1414 if (np->n_stren) rhsx->x_stren = TRUE;
1415 rhsx->szu.xclen = xwid;
1416 return;
1417 case PARTSEL:
1418 syp = rhsx->lu.x->lu.sy;
1419 np = syp->el.enp;
1420 if (np->n_stren) rhsx->x_stren = TRUE;
1421 rhsx->lu.x->szu.xclen = __get_netwide(np);
1422 ndx1 = rhsx->ru.x->lu.x;
1423 ndx2 = rhsx->ru.x->ru.x;
1424 set_rhswidth(ndx1, 0);
1425 set_rhswidth(ndx2, 0);
1426 /* SJM 05/22/00 - error for non illegal non numeric psel caught later */
1427 /* get rhs width always folds psel indices so if not numeric error */
1428 if ((ndx1->optyp == NUMBER || ndx1->optyp == ISNUMBER)
1429 && (ndx2->optyp == NUMBER || ndx2->optyp == ISNUMBER))
1430 {
1431 r1 = (int32) __contab[ndx1->ru.xvi];
1432 r2 = (int32) __contab[ndx2->ru.xvi];
1433 rhsx->szu.xclen = (r1 >= r2) ? (r1 - r2 + 1) : (r2 - r1 + 1);
1434 }
1435 /* using 32 bits - error caught later */
1436 else rhsx->szu.xclen = WBITS;
1437 return;
1438 case QUEST:
1439 set_rhswidth(rhsx->lu.x, 0);
1440 set_rhswidth(rhsx->ru.x->ru.x, cwid);
1441 set_rhswidth(rhsx->ru.x->lu.x, cwid);
1442
1443 tndp = rhsx->ru.x;
1444 /* assume right wider */
1445 xwid = tndp->lu.x->szu.xclen;
1446 if (xwid < tndp->ru.x->szu.xclen) xwid = tndp->ru.x->szu.xclen;
1447 rhsx->szu.xclen = xwid;
1448 return;
1449 case FCALL:
1450 {
1451 int32 frntyp;
1452 struct task_t *tskp;
1453 struct task_pin_t *tpp;
1454
1455 /* notice func. name does not have width but top (rhsx) has ret. width */
1456 syp = rhsx->lu.x->lu.sy;
1457 tskp = syp->el.etskp;
1458 if (syp->sytyp == SYM_SF)
1459 {
1460 struct sysfunc_t *syfp;
1461
1462 syfp = syp->el.esyftbp;
1463 /* SJM 05/28/04 - $signed and $word32 are special case that return */
1464 /* arg width - but need to recursively call get width to determine */
1465 if (syp->el.esyftbp->syfnum == STN_SIGNED
1466 || syp->el.esyftbp->syfnum == STN_UNSIGNED)
1467 {
1468 rhsx->szu.xclen = __get_rhswidth(rhsx->ru.x->lu.x);
1469 }
1470 else
1471 {
1472 /* for real this must be WBITS */
1473 rhsx->szu.xclen = syfp->retwid;
1474 }
1475 /* notice also sets signed for function */
1476 if (syfp->retsigned) rhsx->has_sign = TRUE;
1477 frntyp = syfp->retntyp;
1478 }
1479 else if (syp->sytyp == SYM_F)
1480 {
1481 tpp = tskp->tskpins;
1482 np = tpp->tpsy->el.enp;
1483 /* functions cannot return arrays */
1484 rhsx->szu.xclen = __get_netwide(np);
1485 if (np->n_signed) rhsx->has_sign = TRUE;
1486 frntyp = np->ntyp;
1487 }
1488 /* if call of non function error (caught already) - do nothing */
1489 else return;
1490
1491 if (frntyp == N_REAL)
1492 { rhsx->is_real = TRUE; rhsx->has_sign = TRUE; __expr_has_real = TRUE; }
1493
1494 /* this sets argument widths */
1495 /* this is needed and uses right decl. var context for non sys functions */
1496 /* because width setting is structural before recursive processing */
1497 if (syp->sytyp == SYM_SF) set_sysfcall_widths(rhsx);
1498 else set_fcall_widths(rhsx, tskp);
1499 }
1500 return;
1501 case LCB:
1502 {
1503 register struct expr_t *ndp2;
1504 struct expr_t *catxp;
1505
1506 /* know concatenates never nested by here */
1507 /* first set cat self determined component widths */
1508 xwid = 0;
1509 for (cat_stren = FALSE, ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1510 {
1511 catxp = ndp2->lu.x;
1512 set_rhswidth(catxp, 0);
1513 xwid += catxp->szu.xclen;
1514 if (catxp->x_stren) { ndp2->x_stren = TRUE; cat_stren = TRUE; }
1515 }
1516 rhsx->szu.xclen = xwid;
1517 if (cat_stren) rhsx->x_stren = TRUE;
1518 /* CAT COM op width is dist from high bit of this to low (right) end */
1519 for (ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1520 {
1521 ndp2->szu.xclen = xwid;
1522 xwid -= ndp2->lu.x->szu.xclen;
1523 }
1524 if (xwid != 0) __misc_terr(__FILE__, __LINE__);
1525 }
1526 return;
1527 default:
1528 /* this is unary or binary op */
1529 wclass = __get_widthclass(rhsx);
1530 switch ((byte) wclass) {
1531 case WIDONE:
1532 /* this is for unaries only except for || and && */
1533 rhsx->szu.xclen = 1;
1534 /* under width 1 shield new context is max. width of subexpr. */
1535 /* case is something like &(a + b + c) where c widest */
1536 /* this spreads max. width because of context to all subexpressions */
1537 xwid = __get_rhswidth(rhsx->lu.x);
1538 set_rhswidth(rhsx->lu.x, xwid);
1539 /* notice binaries can be wide one also */
1540 if (rhsx->ru.x != NULL)
1541 {
1542 /* same here */
1543 xwid = __get_rhswidth(rhsx->ru.x);
1544 set_rhswidth(rhsx->ru.x, xwid);
1545 }
1546 return;
1547 case WIDENONE:
1548 /* for binaries that produce one bit result */
1549 rhsx->szu.xclen = 1;
1550 /* notice not using cwid context under here */
1551 xwid = __get_rhswidth(rhsx->lu.x);
1552 xwid2 = __get_rhswidth(rhsx->ru.x);
1553 if (xwid2 > xwid) xwid = xwid2;
1554 if (rhsx->lu.x != NULL) set_rhswidth(rhsx->lu.x, xwid);
1555 if (rhsx->ru.x != NULL) set_rhswidth(rhsx->ru.x, xwid);
1556 return;
1557 case WIDMAX:
1558 /* need context here since non shielded binary */
1559 r1 = r2 = 0;
1560 if (rhsx->ru.x != NULL)
1561 {
1562 set_rhswidth(rhsx->ru.x, cwid);
1563 r1 = rhsx->ru.x->szu.xclen;
1564 }
1565 if (rhsx->lu.x != NULL)
1566 {
1567 set_rhswidth(rhsx->lu.x, cwid);
1568 r2 = rhsx->lu.x->szu.xclen;
1569 }
1570 xwid = (r1 < r2) ? r2 : r1;
1571 select_wid:
1572 if (xwid < cwid) xwid = cwid;
1573 rhsx->szu.xclen = xwid;
1574 return;
1575 case WIDLEFT:
1576 /* set the non context right width (i.e. shift amount) */
1577 set_rhswidth(rhsx->ru.x, 0);
1578 set_rhswidth(rhsx->lu.x, cwid);
1579 xwid = rhsx->szu.xclen;
1580 goto select_wid;
1581 case WIDSELF:
1582 /* for unary - and ~ - (+ too but does nothing - optimized away) */
1583 /* LOOKATME - why getting width and using as context - would 0 work? */
1584 xwid = __get_rhswidth(rhsx->lu.x);
1585 set_rhswidth(rhsx->lu.x, xwid);
1586 /* SJM 07/16/01 - this is wrong - context width need for operator node */
1587 /* ??? rhsx->szu.xclen = xwid; */
1588 goto select_wid;
1589 default: __case_terr(__FILE__, __LINE__);
1590 }
1591 }
1592 }
1593
1594 /*
1595 * set width for user fcall arguments - context here is argument width
1596 * user functions require all arguments
1597 * wrong number of arguments caught elsewhere - use what is there
1598 */
set_fcall_widths(struct expr_t * fcrhsx,struct task_t * tskp)1599 static void set_fcall_widths(struct expr_t *fcrhsx,
1600 struct task_t *tskp)
1601 {
1602 struct expr_t *fandp;
1603 struct task_pin_t *tpp;
1604 int32 pwid;
1605
1606 /* point 1 past extra first argument - not part of source call */
1607 tpp = tskp->tskpins->tpnxt;
1608 for (fandp = fcrhsx->ru.x; fandp != NULL; fandp = fandp->ru.x)
1609 {
1610 /* move to next declared argument */
1611 if (tpp != NULL) tpp = tpp->tpnxt;
1612
1613 if (tpp == NULL || tpp->tpsy == NULL) pwid = 0;
1614 else pwid = __get_netwide(tpp->tpsy->el.enp);
1615
1616 /* notice for numbers this can't change width */
1617 set_rhswidth(fandp->lu.x, pwid);
1618 }
1619 }
1620
1621 /*
1622 * set width for system fcall arguments, no context
1623 * at this point since checking done just use expr. that is there
1624 */
set_sysfcall_widths(struct expr_t * fcrhsx)1625 static void set_sysfcall_widths(struct expr_t *fcrhsx)
1626 {
1627 struct expr_t *fandp;
1628
1629 /* 0 argument system functions common */
1630 /* notice expressions structure does not have extra 1st return value */
1631 for (fandp = fcrhsx->ru.x; fandp != NULL; fandp = fandp->ru.x)
1632 set_rhswidth(fandp->lu.x, 0);
1633 }
1634
1635
1636 /*
1637 * ROUTINE TO SET EXPR SIGNED USING NEW 2001 RULES
1638 */
1639
1640 /*
1641 * set all expression nodes has signed flag
1642 */
set_rhs_signed(struct expr_t * rhsx)1643 static void set_rhs_signed(struct expr_t *rhsx)
1644 {
1645 register struct expr_t *ndp2;
1646 int32 wclass;
1647 struct net_t *np;
1648 struct sy_t *syp;
1649 struct task_t *tskp;
1650 struct sysfunc_t *syfp;
1651 struct task_pin_t *tpp;
1652
1653 switch ((byte) rhsx->optyp) {
1654 case ID: case GLBREF:
1655 np = rhsx->lu.sy->el.enp;
1656 /* SJM 10/02/03 - for real has sign already set by width setting */
1657 /* but doing it here again doesn't hurt */
1658 if (np->n_signed) rhsx->has_sign = TRUE;
1659 break;
1660 case NUMBER: case ISNUMBER: case OPEMPTY:
1661 case REALNUM: case ISREALNUM:
1662 /* for numbers the signed flag set during source input */
1663 break;
1664 case LSB:
1665 /* bit select or array reference */
1666 /* set lhs ID node signedness */
1667 set_rhs_signed(rhsx->lu.x);
1668
1669 /* then set select node signedness */
1670 syp = rhsx->lu.x->lu.sy;
1671 np = syp->el.enp;
1672 if (np->n_isarr)
1673 {
1674 if (np->n_signed) rhsx->has_sign = TRUE;
1675 }
1676 else rhsx->has_sign = FALSE;
1677
1678 /* finally set select range signed */
1679 set_rhs_signed(rhsx->ru.x);
1680 break;
1681 case PARTSEL:
1682 /* set lhs ID node signedness */
1683 set_rhs_signed(rhsx->lu.x);
1684 rhsx->has_sign = FALSE;
1685 break;
1686 case QUEST:
1687 set_rhs_signed(rhsx->lu.x);
1688
1689 set_rhs_signed(rhsx->ru.x->lu.x);
1690 set_rhs_signed(rhsx->ru.x->ru.x);
1691 if (rhsx->ru.x->lu.x->has_sign && rhsx->ru.x->ru.x->has_sign)
1692 {
1693 rhsx->has_sign = TRUE;
1694 }
1695 else
1696 {
1697 /* SJM 05/21/04 - not both signed - easiest to just make both word32 */
1698 rhsx->has_sign = FALSE;
1699 rhsx->ru.x->lu.x->has_sign = FALSE;
1700 rhsx->ru.x->ru.x->has_sign = FALSE;
1701 }
1702 break;
1703 case FCALL:
1704 syp = rhsx->lu.x->lu.sy;
1705 tskp = syp->el.etskp;
1706 if (syp->sytyp == SYM_SF)
1707 {
1708 syfp = syp->el.esyftbp;
1709 if (syfp->retsigned) rhsx->has_sign = TRUE;
1710 }
1711 else if (syp->sytyp == SYM_F)
1712 {
1713 /* SJM 10/02/03 - LOOKATME - old rule was put info in first dummy arg */
1714 /* check to see for 2001 LRM is still true */
1715
1716 tpp = tskp->tskpins;
1717 np = tpp->tpsy->el.enp;
1718 if (np->n_signed) rhsx->has_sign = TRUE;
1719 }
1720 /* if call of non function error (caught already) - do nothing */
1721 else return;
1722
1723 /* final step sets signed flag for each argument of function call */
1724 for (ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1725 {
1726 set_rhs_signed(ndp2->lu.x);
1727 }
1728 break;
1729 case LCB:
1730 /* know concatenate result never signed */
1731 rhsx->has_sign = FALSE;
1732 /* but components can have signed sub-expressions */
1733 for (ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
1734 {
1735 set_rhs_signed(ndp2->lu.x);
1736 }
1737 break;
1738 default:
1739 wclass = __get_widthclass(rhsx);
1740 /* this is unary or binary op */
1741 switch ((byte) wclass) {
1742 case WIDONE:
1743 set_rhs_signed(rhsx->lu.x);
1744 if (rhsx->ru.x != NULL) set_rhs_signed(rhsx->ru.x);
1745 rhsx->has_sign = FALSE;
1746 break;
1747 case WIDENONE:
1748 /* this is for unaries only except for || and && */
1749 /* DBG remove */
1750 if (rhsx->ru.x == NULL) __misc_terr(__FILE__, __LINE__);
1751 /* --- */
1752 set_rhs_signed(rhsx->lu.x);
1753 set_rhs_signed(rhsx->ru.x);
1754 rhsx->has_sign = FALSE;
1755 break;
1756 case WIDMAX:
1757 /* SJM 04/26/04 - unary minus can be be WID MAX */
1758 /* rest of binaries */
1759 set_rhs_signed(rhsx->lu.x);
1760 if (rhsx->ru.x != NULL)
1761 {
1762 /* binary case */
1763 set_rhs_signed(rhsx->ru.x);
1764 if (rhsx->lu.x->has_sign && rhsx->ru.x->has_sign)
1765 rhsx->has_sign = TRUE;
1766 else rhsx->has_sign = FALSE;
1767 }
1768 else
1769 {
1770 /* unary case */
1771 if (rhsx->lu.x->has_sign) rhsx->has_sign = TRUE;
1772 else rhsx->has_sign = FALSE;
1773 }
1774 return;
1775 case WIDLEFT:
1776 /* SHIFT */
1777 set_rhs_signed(rhsx->ru.x);
1778 /* SJM 10/02/03 - LRM says shift count always word32 */
1779 rhsx->ru.x->has_sign = FALSE;
1780 set_rhs_signed(rhsx->lu.x);
1781 rhsx->has_sign = rhsx->lu.x->has_sign;
1782 break;
1783 case WIDSELF:
1784 /* for unary - and ~ - (+ too but does nothing - optimized away) */
1785 set_rhs_signed(rhsx->lu.x);
1786 rhsx->has_sign = rhsx->lu.x->has_sign;
1787 break;
1788 default: __case_terr(__FILE__, __LINE__);
1789 }
1790 }
1791 }
1792
1793 /*
1794 * find a number in an expression with a base and return
1795 * means folded expr. will have base of first component
1796 */
find_xbase(struct expr_t * ndp)1797 static int32 find_xbase(struct expr_t *ndp)
1798 {
1799 int32 ibas;
1800
1801 if (ndp->optyp == NUMBER) { ibas = ndp->ibase; return(ibas); }
1802 if (__isleaf(ndp)) return((int32) '?');
1803 if (ndp->lu.x != NULL)
1804 {
1805 ibas = find_xbase(ndp->lu.x);
1806 if (ibas != '?') return(ibas);
1807 }
1808 if (ndp->ru.x != NULL)
1809 {
1810 ibas = find_xbase(ndp->ru.x);
1811 if (ibas != '?') return(ibas);
1812 }
1813 return((int32) '?');
1814 }
1815
1816 /*
1817 * set and check expr is real and check for all real rhs expression
1818 *
1819 * only called if know somewhere in expression there is a real
1820 * expressions must be all real but some operators take real args and return
1821 * reg (1 bit) - i.e. 1 bit logicals
1822 *
1823 * this sets IS real and expects IS real bit to already be set for leaf nodes
1824 * works bottom up and assumes leaf nodes have IS real set
1825 * sets upper nodes and replaces operators
1826 */
setchk_real_expr(struct expr_t * xrhs)1827 static void setchk_real_expr(struct expr_t *xrhs)
1828 {
1829 int32 i, oandnum, wclass;
1830 struct opinfo_t *opip;
1831 struct expr_t *lx, *rx;
1832
1833 /* is real bit already set */
1834 if (__isleaf(xrhs)) return;
1835
1836 if (xrhs->optyp == QUEST)
1837 {
1838 real_setchk_quest(xrhs);
1839 return;
1840 }
1841 if (xrhs->optyp == FCALL)
1842 {
1843 /* must chk real for all arguments - know fcall is real already set */
1844 /* this is a structural entire expr. tree routine so must check reals */
1845 /* in arguments even though unrelated and arguments probably contain */
1846 /* no reals - using check real on these works - does some extra work */
1847 /* but subtley needed because probably function is real returning */
1848
1849 /* if part of relational or boolean subexpression can actually be non */
1850 /* real returning function */
1851 for (rx = xrhs->ru.x; rx != NULL; rx = rx->ru.x) setchk_real_expr(rx->lu.x);
1852 return;
1853 }
1854
1855 /* special handling of concatenates - by here know 1 level */
1856 if (xrhs->optyp == LCB)
1857 {
1858 for (rx = xrhs->ru.x, i = 1; rx != NULL; rx = rx->ru.x, i++)
1859 {
1860 setchk_real_expr(rx->lu.x);
1861 /* error if any component real - concatenate never real but can be */
1862 /* operator to real conditional */
1863 if (rx->lu.x->is_real)
1864 __sgferr(817, "real expression illegal in concatenate (pos. %d)", i);
1865 }
1866 return;
1867 }
1868
1869 oandnum = 0;
1870 if ((lx = xrhs->lu.x) != NULL) { setchk_real_expr(lx); oandnum++; }
1871 if ((rx = xrhs->ru.x) != NULL) { setchk_real_expr(rx); oandnum++; }
1872
1873 if (oandnum > 1)
1874 {
1875 /* binary case */
1876 /* case 1: neither, operand is real - node not marked as real */
1877 /* this is legal - operator is real not set so if not part of relational */
1878 /* or logical error will be caught later */
1879 /* example of ok of this: (i < j) || (d1 < d2) */
1880 if (!lx->is_real && !rx->is_real) return;
1881
1882 /* case 2: at least one operand is real */
1883 opip = &(__opinfo[xrhs->optyp]);
1884 if (!opip->realop)
1885 {
1886 __sgferr(815, "binary operator %s cannot have real operand(s)",
1887 __to_opname(xrhs->optyp));
1888 return;
1889 }
1890 /* know legal real binary op */
1891 /* notice dependent on real represented with len WBITS using b part */
1892 wclass = __get_widthclass(xrhs);
1893 if (wclass != WIDENONE && wclass != WIDONE)
1894 {
1895 /* normal real (allowed subset) operators result is real */
1896 xrhs->is_real = TRUE;
1897 xrhs->has_sign = TRUE;
1898 xrhs->szu.xclen = REALBITS;
1899 switch ((byte) xrhs->optyp) {
1900 case PLUS: xrhs->optyp = REALPLUS; break;
1901 case MINUS: xrhs->optyp = REALMINUS; break;
1902 case TIMES: xrhs->optyp = REALTIMES; break;
1903 case DIV: xrhs->optyp = REALDIV; break;
1904 /* for nest real function calls may already have been converted */
1905 case REALPLUS: break;
1906 case REALMINUS: break;
1907 case REALTIMES: break;
1908 case REALDIV: break;
1909 default: __case_terr(__FILE__, __LINE__);
1910 }
1911 }
1912 else
1913 {
1914 /* if 1 bit result (comparison or &&/|| result is not real) */
1915 switch ((byte) xrhs->optyp) {
1916 case RELGT: xrhs->optyp = REALRELGT; break;
1917 case RELGE: xrhs->optyp = REALRELGE; break;
1918 case RELLT: xrhs->optyp = REALRELLT; break;
1919 case RELLE: xrhs->optyp = REALRELLE; break;
1920 case RELEQ: xrhs->optyp = REALRELEQ; break;
1921 case RELNEQ: xrhs->optyp = REALRELNEQ; break;
1922 case BOOLAND: xrhs->optyp = REALBOOLAND; break;
1923 case BOOLOR: xrhs->optyp = REALBOOLOR; break;
1924 /* for nest real function calls may already have been converted */
1925 case REALRELGT: break;
1926 case REALRELGE: break;
1927 case REALRELLT: break;
1928 case REALRELLE: break;
1929 case REALRELEQ: break;
1930 case REALRELNEQ: break;
1931 case REALBOOLAND: break;
1932 case REALBOOLOR: break;
1933 default: __case_terr(__FILE__, __LINE__);
1934 }
1935 }
1936 /* mark either non real for conversion to real */
1937 if (!lx->is_real) lx->cnvt_to_real = TRUE;
1938 else if (!rx->is_real) rx->cnvt_to_real = TRUE;
1939 return;
1940 }
1941
1942 /* SJM 10/16/00 - other part of expr. can be real if unary arg not real */
1943 /* nothing to do here */
1944
1945 /* if non real ok, unless under relational err caught higher in expr tree */
1946 /* here operand must be real since only one and result real */
1947 if (!lx->is_real) return;
1948
1949 /* unary real case (only unary - and ! legal) */
1950 if (xrhs->optyp != MINUS && xrhs->optyp != NOT)
1951 {
1952 __sgferr(878, "unary operator %s cannot have real operand",
1953 __to_opname(xrhs->optyp));
1954 return;
1955 }
1956
1957 if (xrhs->optyp == MINUS)
1958 {
1959 xrhs->optyp = REALMINUS;
1960 xrhs->is_real = TRUE;
1961 xrhs->has_sign = TRUE;
1962 xrhs->szu.xclen = REALBITS;
1963 }
1964 /* result is 1 bit but not real - if arg. not real do not change */
1965 else if (xrhs->optyp == NOT) xrhs->optyp = REALNOT;
1966 }
1967
1968 /*
1969 * set is real and check real ?:
1970 *
1971 * LOOKATME - converting : part of ?: to real if one real
1972 */
real_setchk_quest(struct expr_t * xrhs)1973 static void real_setchk_quest(struct expr_t *xrhs)
1974 {
1975 struct expr_t *lx, *rx;
1976
1977 /* according to lrm - selector can be real (0.0 F else T) */
1978 setchk_real_expr(xrhs->lu.x);
1979 lx = xrhs->ru.x->lu.x;
1980 setchk_real_expr(lx);
1981 rx = xrhs->ru.x->ru.x;
1982 setchk_real_expr(rx);
1983
1984 /* must change operators - this is most complicated case */
1985 /* know expr. correct and either both or no operators real */
1986 if (!xrhs->lu.x->is_real)
1987 {
1988 /* if either : expression real, convert other to real */
1989 if (lx->is_real || rx->is_real)
1990 {
1991 /* notice QUEST top (not QCOL) is changed */
1992 xrhs->optyp = REGREALQCOL;
1993 xrhs->is_real = TRUE;
1994 xrhs->has_sign = TRUE;
1995 /* real is WBITS since no x value */
1996 xrhs->szu.xclen = WBITS;
1997 xrhs->ru.x->is_real = TRUE;
1998 xrhs->ru.x->has_sign = TRUE;
1999 /* QCOL ? is real and has real width */
2000 xrhs->ru.x->szu.xclen = WBITS;
2001 /* set bit so if either non real will get converted */
2002 if (!lx->is_real) lx->cnvt_to_real = TRUE;
2003 else if (!rx->is_real) rx->cnvt_to_real = TRUE;
2004 }
2005 /* can be non real subexpression of real */
2006 return;
2007 }
2008 /* know cond. real */
2009 if (lx->is_real || rx->is_real)
2010 {
2011 xrhs->optyp = REALREALQUEST;
2012 xrhs->ru.x->is_real = TRUE;
2013 xrhs->ru.x->has_sign = TRUE;
2014 xrhs->ru.x->szu.xclen = WBITS;
2015 xrhs->szu.xclen = WBITS;
2016 xrhs->is_real = TRUE;
2017 xrhs->has_sign = TRUE;
2018 /* set bit so if either non real will get converted */
2019 if (!lx->is_real) lx->cnvt_to_real = TRUE;
2020 else if (!rx->is_real) rx->cnvt_to_real = TRUE;
2021 return;
2022 }
2023 /* notice here nothing marked as real except cond. sub expr */
2024 xrhs->optyp = REALREGQUEST;
2025 }
2026
2027 /*
2028 * recursively check expression special operators - still structural
2029 * cannot do anything that requires any folding
2030 * also empty illegal here - will have been caught
2031 */
chk_specialop_rhsexpr(struct expr_t * ndp)2032 static void chk_specialop_rhsexpr(struct expr_t *ndp)
2033 {
2034 switch ((byte) ndp->optyp) {
2035 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
2036 return;
2037 case ID: case GLBREF: chk_rhs_id(ndp); return;
2038 case LSB:
2039 chk_specialop_rhsexpr(ndp->ru.x);
2040 chk_srcbsel(ndp, TRUE);
2041 return;
2042 case PARTSEL:
2043 chk_specialop_rhsexpr(ndp->ru.x->lu.x);
2044 chk_specialop_rhsexpr(ndp->ru.x->ru.x);
2045 chk_srcpsel(ndp, TRUE);
2046 return;
2047 case LCB:
2048 {
2049 register struct expr_t *catndp;
2050
2051 for (catndp = ndp->ru.x; catndp != NULL; catndp = catndp->ru.x)
2052 {
2053 chk_specialop_rhsexpr(catndp->lu.x);
2054 catndp->has_sign = FALSE;
2055 }
2056 ndp->has_sign = FALSE;
2057 }
2058 return;
2059 case FCALL:
2060 chkspecop_fcall(ndp);
2061 return;
2062 case QUEST:
2063 chk_specialop_rhsexpr(ndp->lu.x);
2064 /* SJM 05/21/04 - these just sets the nd rel sign eval bit */
2065 /* signed set elsewhere */
2066 chk_specialop_rhsexpr(ndp->ru.x->lu.x);
2067 chk_specialop_rhsexpr(ndp->ru.x->ru.x);
2068 return;
2069 case REALREGQUEST: case REALREALQUEST: case REGREALQCOL:
2070 /* SJM 10/17/99 - now real's allowed in expressions - need to check */
2071 chk_specialop_rhsexpr(ndp->lu.x);
2072 chk_specialop_rhsexpr(ndp->ru.x->lu.x);
2073 chk_specialop_rhsexpr(ndp->ru.x->ru.x);
2074 return;
2075 case OPEVOR: case OPEVCOMMAOR: case OPPOSEDGE: case OPNEGEDGE:
2076 __sgferr(818,
2077 "event expression operator %s illegal in right hand side expression",
2078 __to_opname(ndp->optyp));
2079 return;
2080 }
2081 /* if real already checked */
2082 /* ??? if (ndp->is_real) return; */
2083
2084 /* know ndp some kind of arith operator to fall thru to here */
2085 /* know parsing made sure binaries have 2 ops and unaries 1 */
2086 if (ndp->lu.x != NULL) chk_specialop_rhsexpr(ndp->lu.x);
2087 if (ndp->ru.x != NULL) chk_specialop_rhsexpr(ndp->ru.x);
2088 if (ndp->ru.x == NULL && ndp->lu.x == NULL) __arg_terr(__FILE__, __LINE__);
2089
2090 /* SJM 10/06/03 - now have separate proc to set sign but set rel sign eval */
2091 if (ndp->szu.xclen == 1)
2092 {
2093 /* SJM 05/13/04 - relationals always binary */
2094 if (ndp->lu.x != NULL && ndp->ru.x != NULL)
2095 {
2096 if (ndp->lu.x->has_sign && ndp->ru.x->has_sign)
2097 {
2098 /* for reals, always signed and this flag not used */
2099 switch ((byte) ndp->optyp) {
2100 case RELGE: case RELGT: case RELLE: case RELLT:
2101 case RELNEQ: case RELEQ: case RELCEQ: case RELCNEQ:
2102 ndp->rel_ndssign = TRUE;
2103 }
2104 }
2105 }
2106 }
2107 }
2108
2109 /*
2110 * check a known constant bit select for in range and non-z/x
2111 * no lhs/rhs distinction here
2112 *
2113 * this can be called during source reading - 2nd part checks range
2114 * that requires parameters to have fixed values
2115 *
2116 * return F on error or x/z number - caller decides if error needed
2117 * will never get here for event since illegal in rhs or lhs expressions
2118 */
chk_srcbsel(struct expr_t * ndp,int32 is_rhs)2119 static int32 chk_srcbsel(struct expr_t *ndp, int32 is_rhs)
2120 {
2121 struct expr_t *idndp, *rconx;
2122 struct sy_t *syp;
2123 struct net_t *np;
2124
2125 idndp = ndp->lu.x;
2126 syp = idndp->lu.sy;
2127 rconx = ndp->ru.x;
2128 if (syp == NULL) __arg_terr(__FILE__, __LINE__);
2129 if (syp->sytyp != SYM_N)
2130 {
2131 __sgferr(819,
2132 "bit select or array index from non wire/reg \"%s\" type %s",
2133 __to_idnam(idndp), __to_sytyp(__xs, syp->sytyp));
2134 return(FALSE);
2135 }
2136 np = syp->el.enp;
2137 if (!np->n_isavec && !np->n_isarr)
2138 {
2139 __sgferr(820, "bit select or array index of non memory and non vector %s",
2140 __to_idnam(idndp));
2141 return(FALSE);
2142 }
2143 /* selects from real params already removed - LOOKATME ?? */
2144 if (np->ntyp == N_REAL && !np->n_isarr)
2145 {
2146 __sgferr(821, "bit select from real %s illegal", __to_idnam(idndp));
2147 return(FALSE);
2148 }
2149 /* bit and part selects from parameters in normal rhs exprs supported */
2150 if (np->n_isarr && (np->ntyp < NONWIRE_ST || np->ntyp == N_EVENT))
2151 {
2152 __sgferr(823, "array index of %s illegal for %s", __to_idnam(idndp),
2153 __to_wtnam(__xs, np));
2154 return(FALSE);
2155 }
2156 if (np->nrngrep == NX_CT)
2157 {
2158 if (is_rhs)
2159 {
2160 np->nu.ct->n_onrhs = TRUE;
2161 if (!__expr_rhs_decl) np->n_onprocrhs = TRUE;
2162 }
2163 else
2164 {
2165 if (np->nu.ct->n_onlhs) np->nu.ct->n_2ndonlhs = TRUE;
2166 else np->nu.ct->n_onlhs = TRUE;
2167 }
2168 }
2169
2170 /* can also do real checking now */
2171 switch ((byte) rconx->optyp) {
2172 case NUMBER: break;
2173 case ISNUMBER:
2174 if (rconx->is_real) goto bs_real;
2175 break;
2176 case ISREALNUM:
2177 bs_real:
2178 __sgferr(824,
2179 "bit select or array index of %s cannot be real", __to_idnam(idndp));
2180 return(FALSE);
2181 default:
2182 /* for procedural expr. checking done and simplied index expr by here */
2183 if (rconx->is_real) goto bs_real;
2184 if (rconx->szu.xclen > WBITS)
2185 {
2186 __sgfinform(455,
2187 "select index variable expression %s wider than %d - high bits ignored",
2188 __msgexpr_tostr(__xs, rconx), WBITS);
2189 }
2190 return(TRUE);
2191 }
2192 /* but must fold and normalize later */
2193 return(TRUE);
2194 }
2195
2196 /*
2197 * check a part select for in range and non-x/z
2198 * no lhs/rhs distinction here
2199 * part select values non x/z numbers and cannot be variable
2200 * returns F on error
2201 */
chk_srcpsel(struct expr_t * ndp,int32 is_rhs)2202 static int32 chk_srcpsel(struct expr_t *ndp, int32 is_rhs)
2203 {
2204 struct net_t *np;
2205 struct expr_t *idndp;
2206 struct sy_t *syp;
2207
2208 idndp = ndp->lu.x;
2209 syp = idndp->lu.sy;
2210 if (syp == NULL)
2211 {
2212 __sgferr(830, "part select from parameter %s illegal", __to_idnam(idndp));
2213 return(FALSE);
2214 }
2215 if (syp->sytyp != SYM_N)
2216 {
2217 __sgferr(831, "part select from non net or register \"%s\" type %s illegal",
2218 __to_idnam(idndp), __to_sytyp(__xs, syp->sytyp));
2219 return(FALSE);
2220 }
2221 np = syp->el.enp;
2222 if (!np->n_isavec)
2223 {
2224 __sgferr(832, "part select of non vector %s illegal", __to_idnam(idndp));
2225 return(FALSE);
2226 }
2227 /* ??? REAL ARRAYS LEGAL
2228 if (np->n_isarr)
2229 {
2230 __sgferr(833, "part select of array %s illegal", __to_idnam(idndp));
2231 return(FALSE);
2232 }
2233 --- */
2234 if (np->ntyp == N_REAL)
2235 {
2236 __sgferr(834, "part select of real %s illegal", __to_idnam(idndp));
2237 return(FALSE);
2238 }
2239 if (np->nrngrep == NX_CT)
2240 {
2241 if (is_rhs)
2242 {
2243 np->nu.ct->n_onrhs = TRUE;
2244 if (!__expr_rhs_decl) np->n_onprocrhs = TRUE;
2245 }
2246 else
2247 {
2248 if (np->nu.ct->n_onlhs) np->nu.ct->n_2ndonlhs = TRUE;
2249 else np->nu.ct->n_onlhs = TRUE;
2250 }
2251 }
2252 return(TRUE);
2253 }
2254
2255 /*
2256 * source (before expr. widths known) structural check of 1 function call
2257 * must be call of function with right number of args
2258 * argument checking elsewhere
2259 */
chkspecop_fcall(struct expr_t * ndp)2260 static void chkspecop_fcall(struct expr_t *ndp)
2261 {
2262 register struct expr_t *fandp, *andp;
2263 struct sy_t *syp;
2264 struct expr_t *idndp;
2265
2266 /* when translating iact stmt, func. call requires scheduled thread */
2267 /* since may have break in it */
2268 idndp = ndp->lu.x;
2269 syp = idndp->lu.sy;
2270 if (syp->sytyp != SYM_F && syp->sytyp != SYM_SF)
2271 {
2272 __sgferr(835, "call of non function %s", __to_idnam(idndp));
2273 return;
2274 }
2275 /* SJM 09/28/01 - set flag so can indicate func has user fcall */
2276 if (syp->sytyp == SYM_F)
2277 { __iact_must_sched = TRUE; __func_has_fcall = TRUE; }
2278 else
2279 {
2280 /* for system function (maybe PLI) - unindex array legal */
2281 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
2282 {
2283 andp = fandp->lu.x;
2284 /* only for PLI 2.0 system functions, unindex array legal */
2285 if (syp->el.esyftbp->syfnum > __last_veriusertf
2286 && (andp->optyp == ID || andp->optyp == GLBREF))
2287 {
2288 if (andp->lu.sy->el.enp->n_isarr) continue;
2289 }
2290 chk_specialop_rhsexpr(andp);
2291 }
2292 return;
2293 }
2294
2295 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
2296 chk_specialop_rhsexpr(fandp->lu.x);
2297 }
2298
2299 /*
2300 * emit warning for word32 relationals
2301 * return T if fold word32 so only 1 warning emitted
2302 */
chk_mixedsign_relops(struct expr_t * ndp)2303 static int32 chk_mixedsign_relops(struct expr_t *ndp)
2304 {
2305 register struct expr_t *xp;
2306
2307 switch ((byte) ndp->optyp) {
2308 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM:
2309 case ID: case GLBREF:
2310 break;
2311 case LSB:
2312 if (chk_mixedsign_relops(ndp->ru.x)) return(TRUE);
2313 break;
2314 case PARTSEL:
2315 if (chk_mixedsign_relops(ndp->ru.x->lu.x)) return(TRUE);
2316 if (chk_mixedsign_relops(ndp->ru.x->ru.x)) return(TRUE);
2317 break;
2318 case LCB:
2319 {
2320 for (xp = ndp->ru.x; xp != NULL; xp = xp->ru.x)
2321 if (chk_mixedsign_relops(xp->lu.x)) return(TRUE);
2322 }
2323 break;
2324 case FCALL:
2325 {
2326 /* even if consts in concatenate, entire thing is not */
2327 for (xp = ndp->ru.x; xp != NULL; xp = xp->ru.x)
2328 if (chk_mixedsign_relops(xp->lu.x)) return(TRUE);
2329 }
2330 break;
2331 default:
2332 if (ndp->lu.x != NULL) if (chk_mixedsign_relops(ndp->lu.x)) return(TRUE);
2333 if (ndp->ru.x != NULL) if (chk_mixedsign_relops(ndp->ru.x)) return(TRUE);
2334 switch ((byte) ndp->optyp) {
2335 case RELGE: case RELGT: case RELLE: case RELLT:
2336 /* if either but not both or neither signed, emit warning */
2337 if (ndp->lu.x->has_sign ^ ndp->ru.x->has_sign)
2338 {
2339 __sgfinform(440,
2340 "relational operator has mixed signed and word32 operands");
2341 return(TRUE);
2342 }
2343 }
2344 }
2345 return(FALSE);
2346 }
2347
2348 /*
2349 * COMPILE TIME CONSTANT FOLDING ROUTINES
2350 */
2351
2352 /*
2353 * fold any normal rhs expression including specify section
2354 * where know only specparams used
2355 */
fold_subexpr(struct expr_t * ndp)2356 static void fold_subexpr(struct expr_t *ndp)
2357 {
2358 int32 isform;
2359
2360 /* notice any opempty will be marked as folded */
2361 if (!ndp->folded)
2362 {
2363 mark_constnd(ndp, &isform);
2364 fold_const(ndp);
2365 ndp->folded = TRUE;
2366 }
2367 }
2368
2369 /*
2370 * mark all constant nodes
2371 * if evaluates to constant, root will have consubxpr turned on
2372 * all node width's must be set before calling this
2373 * any expr. that is ID but really param changed here to constant
2374 *
2375 * notice ISNUMBER and ISREAL are not foldable and places that need number
2376 * must be split ranges or module port header selects, or must be inst by
2377 * by inst. (creation of dependent param substituted exprs.) or are
2378 * illegal (concatenate repeat counts)
2379 *
2380 * all selects from parameters (legal in normal but not param define rhs)
2381 * converted to number or IS number before here because must set width
2382 *
2383 * for unary if operand is IS so is result
2384 * for binary if either is IS, so is result, no reduction operators
2385 */
mark_constnd(register struct expr_t * ndp,int32 * has_isform)2386 static int32 mark_constnd(register struct expr_t *ndp, int32 *has_isform)
2387 {
2388 register struct net_t *np;
2389 int32 const_subtree, cat_isform;
2390 int32 is1, is2, is3, wlen, nwid, wsiz;
2391 double d1;
2392 word32 *wp;
2393 double *dp;
2394 struct xstk_t *xsp;
2395
2396 *has_isform = FALSE;
2397 switch ((byte) ndp->optyp) {
2398 case NUMBER: case REALNUM:
2399 ndp->consubxpr = TRUE;
2400 return(TRUE);
2401 case ISNUMBER: case ISREALNUM:
2402 ndp->consubxpr = TRUE;
2403 ndp->consub_is = TRUE;
2404 *has_isform = TRUE;
2405 return(TRUE);
2406 /* do not mark empty as constant */
2407 case OPEMPTY: break;
2408 case ID:
2409 /* LOOKATME - can this be fcall that is not const */
2410 if (ndp->lu.sy->sytyp != SYM_N) break;
2411
2412 np = ndp->lu.sy->el.enp;
2413 cnvt_gref_param:
2414 if (!np->n_isaparam) return(FALSE);
2415 else
2416 {
2417 /* must convert to ID's that are really params to number type */
2418 /* wire converted - must convert expr that points to wire here */
2419 /* since parameter can be used more than once, must copy value */
2420
2421 /* DBG - remove */
2422 nwid = __get_netwide(np);
2423 if (nwid != ndp->szu.xclen) __misc_terr(__FILE__, __LINE__);
2424 /* --- */
2425 wlen = wlen_(nwid);
2426 wsiz = 0;
2427 if (np->ntyp != N_REAL)
2428 {
2429 if (np->srep == SR_PISNUM)
2430 {
2431 ndp->optyp = ISNUMBER;
2432 ndp->consub_is = TRUE;
2433 *has_isform = TRUE;
2434 wsiz = wlen*__inst_mod->flatinum;
2435 }
2436 else if (np->srep == SR_PNUM)
2437 {
2438 ndp->optyp = NUMBER;
2439 ndp->consubxpr = TRUE;
2440 wsiz = wlen;
2441 }
2442 else __case_terr(__FILE__, __LINE__);
2443
2444 if (np->n_signed) ndp->has_sign = TRUE;
2445 if (np->nu.ct->pstring) ndp->is_string = TRUE;
2446 ndp->ibase = np->nu.ct->pbase;
2447
2448 if (ndp->optyp == NUMBER && nwid <= WBITS)
2449 {
2450 wp = np->nva.wp;
2451 ndp->ru.xvi = __alloc_shareable_cval(wp[0], wp[1], nwid);
2452 }
2453 else
2454 {
2455 /* IS forms can't be shared because are changed after added */
2456 if (*has_isform)
2457 {
2458 ndp->ru.xvi = __alloc_is_cval(wsiz);
2459 /* SJM 02/23/05 - IS const alloc no longer also sets the values */
2460 memcpy(&(__contab[ndp->ru.xvi]), np->nva.wp, 2*wsiz*WRDBYTES);
2461 }
2462 else
2463 {
2464 ndp->ru.xvi = __allocfill_cval_new(np->nva.wp, &(np->nva.wp[wsiz]),
2465 wsiz);
2466 }
2467 }
2468 }
2469 else
2470 {
2471 /* for real xclen is 32 which produces 8 bytes object (no b part) */
2472 /* but need to add to real con tab */
2473 if (np->srep == SR_PISNUM)
2474 {
2475 ndp->optyp = ISREALNUM;
2476 ndp->consub_is = TRUE;
2477 *has_isform = TRUE;
2478 /* word size is 1 since reals take 2 words but no b part */
2479 ndp->ru.xvi = __allocfill_cval_new(np->nva.wp, &(np->nva.wp[wsiz]),
2480 __inst_mod->flatinum);
2481
2482 /* LOOKATME - does this work ??? */
2483 dp = (double *) &(__contab[ndp->ru.xvi]);
2484 /* copy from param (aka net) form to constant value table */
2485
2486 /* copy from param (aka net) form to constant value table */
2487 /* SJM 02/20/04 - copy every inst with real size */
2488 memcpy(dp, np->nva.dp, sizeof(double)*__inst_mod->flatinum);
2489 }
2490 else if (np->srep == SR_PNUM)
2491 {
2492 ndp->optyp = REALNUM;
2493 ndp->consubxpr = TRUE;
2494 memcpy(&d1, np->nva.wp, sizeof(double));
2495 ndp->ru.xvi = __alloc_shareable_rlcval(d1);
2496 /* notice because of different byte ordering must cast word32 form */
2497 }
2498 else __case_terr(__FILE__, __LINE__);
2499 ndp->is_real = TRUE;
2500 ndp->has_sign = TRUE;
2501 }
2502 }
2503 return(TRUE);
2504 case GLBREF:
2505 /* SJM - 04/21/00 - allowing simple form of xmr param ref. */
2506 /* can't be IS - non loc - i.e. param that is assigned to */
2507 if (ndp->lu.sy->sytyp != SYM_N) break;
2508
2509 np = ndp->lu.sy->el.enp;
2510 if (!np->n_isaparam) break;
2511
2512 if (np->srep != SR_PNUM)
2513 {
2514 __sgferr(3411,
2515 "heirarchical reference %s of non local parameter set by defparam or pound param illegal",
2516 ndp->ru.grp->gnam);
2517
2518 ndp->optyp = NUMBER;
2519 ndp->consubxpr = TRUE;
2520 /* value is same width x */
2521 if (np->nwid <= WBITS)
2522 {
2523 ndp->ru.xvi = __alloc_shareable_cval(ALL1W, ALL1W, WBITS);
2524 }
2525 else
2526 {
2527 push_xstk_(xsp, np->nwid);
2528 one_allbits_(xsp->ap, np->nwid);
2529 one_allbits_(xsp->bp, np->nwid);
2530 ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, wlen_(np->nwid));
2531 __pop_xstk();
2532 }
2533 return(TRUE);
2534 }
2535 goto cnvt_gref_param;
2536 case LSB:
2537 /* must fold select expressions separately - but node never a const. */
2538 mark_constnd(ndp->ru.x, has_isform);
2539 break;
2540 case PARTSEL:
2541 mark_constnd(ndp->ru.x->lu.x, has_isform);
2542 mark_constnd(ndp->ru.x->ru.x, has_isform);
2543 break;
2544 case FCALL:
2545 /* must mark const. args as foldable but not fcall node */
2546 {
2547 register struct expr_t *fandp;
2548
2549 /* even if consts in concatenate, entire thing is not */
2550 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
2551 mark_constnd(fandp->lu.x, &is1);
2552 }
2553 break;
2554 case LCB:
2555 /* top concatentate left field unused */
2556 /* mark top for folding if all components constants */
2557 {
2558 register struct expr_t *ctndp;
2559 int32 canfold;
2560
2561 cat_isform = FALSE;
2562 canfold = TRUE;
2563 for (ctndp = ndp->ru.x; ctndp != NULL;)
2564 {
2565 if (ctndp->optyp == CATCOM)
2566 {
2567 if (!mark_constnd(ctndp->lu.x, &is1)) canfold = FALSE;
2568 else { if (is1) cat_isform = TRUE; }
2569 ctndp = ctndp->ru.x;
2570 }
2571 else
2572 {
2573 if (!mark_constnd(ctndp, &is1)) canfold = FALSE;
2574 else { if (is1) cat_isform = TRUE; }
2575 break;
2576 }
2577 }
2578 if (canfold)
2579 {
2580 ndp->consubxpr = TRUE;
2581 if (cat_isform) { ndp->consub_is = TRUE; *has_isform = TRUE; }
2582 return(TRUE);
2583 }
2584 }
2585 break;
2586 case QUEST:
2587 {
2588 int32 m1, m2, m3;
2589
2590 /* only mark if all 3 constants - but really only need selector const */
2591 m1 = mark_constnd(ndp->lu.x, &is1);
2592 m2 = mark_constnd(ndp->ru.x->ru.x, &is2);
2593 m3 = mark_constnd(ndp->ru.x->lu.x, &is3);
2594 /* for now only folding if all 3 expressions constants */
2595 if (m1 && m2 && m3)
2596 {
2597 ndp->consubxpr = TRUE;
2598 /* if any IS then entire expression must eval to IS because selects */
2599 /* can differ - SJM 10/17/99 */
2600 if (is1 || is2 || is3 ) { ndp->consub_is = TRUE; *has_isform = TRUE; }
2601 return(TRUE);
2602 }
2603 }
2604 break;
2605 case CATREP:
2606 /* know left must be a constant */
2607 mark_constnd(ndp->ru.x, &is1);
2608 /* cat repeat value not simple number */
2609 if (is1) __misc_terr(__FILE__, __LINE__);
2610 break;
2611 default:
2612 /* know op. node to get here */
2613 is2 = FALSE;
2614 const_subtree = mark_constnd(ndp->lu.x, &is1);
2615 if (ndp->ru.x != NULL && !mark_constnd(ndp->ru.x, &is2))
2616 const_subtree = FALSE;
2617 ndp->consubxpr = (const_subtree) ? TRUE : FALSE;
2618 /* SJM 10/17/99 - must set has isform to propagate up tree */
2619 if (is1 || is2) { ndp->consub_is = TRUE; *has_isform = TRUE; }
2620 return(const_subtree);
2621 }
2622 /* return for normal non constant case */
2623 ndp->consubxpr = FALSE;
2624 return(FALSE);
2625 }
2626
2627 /*
2628 * eval all constant subnodes in tree - constant reduces to number node
2629 *
2630 * requires expr. node widths to be set before here
2631 * also __sfnam_ind must be set
2632 *
2633 * bit or part selects from parameters in rhs expressions are legal consts
2634 * but such selects cannot be used in param rhs defining expressions
2635 */
fold_const(struct expr_t * ndp)2636 static void fold_const(struct expr_t *ndp)
2637 {
2638 register int32 iti;
2639 int32 wlen, xreal, base, xwi, sav_xclen, xsign;
2640 word32 *wp;
2641 double *dp, d1;
2642 struct xstk_t *xsp;
2643
2644 wp = NULL;
2645 /* leaves already folded unless parameter */
2646 if (__isleaf(ndp))
2647 {
2648 if (ndp->optyp != ID) return;
2649 if (idnd_var(ndp->lu.sy)) return;
2650 }
2651 xsp = NULL;
2652 ndp->folded = TRUE;
2653 /* know sub expr. evaluates to constant */
2654 if (ndp->consubxpr)
2655 {
2656 /* --- DBG */
2657 if (__debug_flg)
2658 __dbg_msg("## folding constant expression %s\n",
2659 __msgexpr_tostr(__xs, ndp));
2660 /* --- */
2661 wlen = wlen_(ndp->szu.xclen);
2662 if (ndp->is_real) { xreal = TRUE; base = BDBLE; }
2663 else
2664 {
2665 xreal = FALSE;
2666 if (is_signed_decimal(ndp)) base = BDEC; else base = BHEX;
2667 }
2668
2669
2670 /* case: foldable expression that does not contain or result in IS form */
2671 /* notice do not need current itree place here - will crash if problem */
2672 if (!ndp->consub_is)
2673 {
2674 xsp = __eval_xpr(ndp);
2675
2676 is_1inst:
2677 /* for constants at least need to change width of expression */
2678 /* SJM 09/29/03 - change to handle sign extension and separate types */
2679 if (xsp->xslen > ndp->szu.xclen) __narrow_sizchg(xsp, ndp->szu.xclen);
2680 else if (xsp->xslen < ndp->szu.xclen)
2681 {
2682 if (ndp->has_sign) __sgn_xtnd_widen(xsp, ndp->szu.xclen);
2683 else __sizchg_widen(xsp, ndp->szu.xclen);
2684 }
2685
2686 /* AIV 09/29/04 - need to save the sign for a folded expr */
2687 xsign = ndp->has_sign;
2688 __free2_xtree(ndp);
2689 __init_xnd(ndp);
2690 ndp->szu.xclen = xsp->xslen;
2691 ndp->has_sign = xsign;
2692
2693 /* if real know value will be real - no need for conversion */
2694 if (xreal)
2695 {
2696 memcpy(&d1, xsp->ap, sizeof(double));
2697 ndp->ru.xvi = __alloc_shareable_rlcval(d1);
2698 ndp->optyp = REALNUM;
2699 ndp->is_real = TRUE;
2700 ndp->has_sign = TRUE;
2701 ndp->ibase = BDBLE;
2702 }
2703 else
2704 {
2705 /* anything value set here must be (becomes) sized number */
2706 if (ndp->szu.xclen <= WBITS)
2707 {
2708 ndp->ru.xvi = __alloc_shareable_cval(xsp->ap[0], xsp->bp[0],
2709 ndp->szu.xclen);
2710 }
2711 else
2712 {
2713 ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, wlen);
2714 }
2715 /* must set standard after folded expr. node flags */
2716 ndp->optyp = NUMBER;
2717 if (base == BDEC) { ndp->ibase = BDEC; ndp->has_sign = TRUE; }
2718 }
2719 __pop_xstk();
2720 ndp->consubxpr = TRUE;
2721 ndp->folded = TRUE;
2722
2723 /* --- DBG --
2724 if (__debug_flg)
2725 __dbg_msg("## result is %s\n", __msgnumexpr_tostr(__xs, ndp, 0));
2726 --- */
2727 return;
2728 }
2729 /* for IS form only indication of real is is_real flag - and expr. and */
2730 /* replaced constant will have same value */
2731 if (xreal) xwi = __alloc_is_cval(__inst_mod->flatinum);
2732 else
2733 {
2734 xwi = __alloc_is_cval(wlen*__inst_mod->flatinum);
2735 wp = &(__contab[xwi]);
2736 }
2737 sav_xclen = ndp->szu.xclen;
2738
2739 for (iti = 0; iti < __inst_mod->flatinum; iti++)
2740 {
2741 __inst_ptr->itinum = iti;
2742 __inum = iti;
2743 /* 1 value per instance number */
2744 xsp = __eval_xpr(ndp);
2745
2746 /* know if expr real all instances will eval to real */
2747 if (xreal)
2748 {
2749 memcpy(&d1, xsp->ap, sizeof(double));
2750 /* AIV 05/30/07 - if expression is real need to 2*__inum reals use */
2751 /* two words not one */
2752 dp = (double *) &(__contab[xwi + (2*__inum)]);
2753 *dp = d1;
2754 }
2755 else
2756 {
2757 /* SJM 09/29/03 - change to handle sign extension and separate types */
2758 if (xsp->xslen > ndp->szu.xclen) __narrow_sizchg(xsp, ndp->szu.xclen);
2759 else if (xsp->xslen < ndp->szu.xclen)
2760 {
2761 if (ndp->has_sign) __sgn_xtnd_widen(xsp, ndp->szu.xclen);
2762 else __sizchg_widen(xsp, ndp->szu.xclen);
2763 }
2764
2765 memcpy(&(wp[2*wlen*__inum]), xsp->ap, 2*WRDBYTES*wlen);
2766 }
2767
2768 /* this may no longer be IS form if only 1 inst - xstk popped at 1 inst */
2769 /* FIXME is this case possible - if so, memory leak */
2770 if (__inst_mod->flatinum == 1) { __pop_itstk(); goto is_1inst; }
2771 __pop_xstk();
2772 }
2773
2774 __free2_xtree(ndp);
2775 __init_xnd(ndp);
2776 /* notice this eliminates width - so must be set from saved */
2777 ndp->szu.xclen = sav_xclen;
2778 ndp->ru.xvi = xwi;
2779 if (xreal)
2780 {
2781 ndp->optyp = ISREALNUM;
2782 /* AIV 05/30/07 - need to mark expression real if folded to real value */
2783 ndp->is_real = TRUE;
2784 }
2785 else ndp->optyp = ISNUMBER;
2786 ndp->consubxpr = TRUE;
2787 ndp->consub_is = TRUE;
2788 ndp->folded = TRUE;
2789
2790 if (__debug_flg)
2791 {
2792 for (iti = 0; iti < __inst_mod->flatinum; iti++)
2793 {
2794 __force_base = BDEC;
2795 __dbg_msg("## IS form result for inst. no. %d is %s (width %d)\n", iti,
2796 __msgnumexpr_tostr(__xs, ndp, iti), ndp->szu.xclen);
2797 __force_base = BNONE;
2798 }
2799 }
2800 __inst_ptr->itinum = 0;
2801 __inum = 0;
2802 return;
2803 }
2804
2805 /* must fold select expressions separately */
2806 /* but work is done in above part of this routine */
2807 switch ((byte) ndp->optyp) {
2808 case LSB:
2809 fold_const(ndp->ru.x);
2810 return;
2811 case PARTSEL:
2812 fold_const(ndp->ru.x->lu.x);
2813 fold_const(ndp->ru.x->ru.x);
2814 return;
2815 case QUEST:
2816 /* SJM 04/26/04 - must also catch real ?: cases and check leaves only */
2817 case REALREALQUEST:
2818 case REALREGQUEST:
2819 case REGREALQCOL:
2820 /* will not get here if all 3 constants - could fold if cond. const */
2821 /* if all 3 constants will not get here */
2822 fold_const(ndp->lu.x);
2823 fold_const(ndp->ru.x->lu.x);
2824 fold_const(ndp->ru.x->ru.x);
2825 return;
2826 case FCALL:
2827 {
2828 register struct expr_t *fandp;
2829
2830 /* notice width already set for these arguments */
2831 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
2832 {
2833 if (__debug_flg)
2834 __dbg_msg("## folding fcall argument expression %s\n",
2835 __msgexpr_tostr(__xs, fandp->lu.x));
2836 fold_const(fandp->lu.x);
2837 }
2838 }
2839 return;
2840 case LCB:
2841 /* for folding elements of concatenate when not all constants */
2842 {
2843 register struct expr_t *ctndp;
2844
2845 for (ctndp = ndp->ru.x; ctndp != NULL; ctndp = ctndp->ru.x)
2846 {
2847 /* --- DBG
2848 if (__debug_flg && ctndp->lu.x->optyp != ID)
2849 {
2850 __dbg_msg("## folding non all constant concatenate expression %s\n",
2851 __msgexpr_tostr(__xs, ctndp->lu.x));
2852 }
2853 --- */
2854 fold_const(ctndp->lu.x);
2855 }
2856 /* now know all components are numbers */
2857 }
2858 break;
2859 case CATREP:
2860 /* concatenate repeat form expansion error */
2861 __misc_sgfterr(__FILE__, __LINE__);
2862 break;
2863 default:
2864 /* may be subexpressions of normal bin. or un. that can be folded */
2865 /* pass global context down - operators may change */
2866 /* know this is not leaf node */
2867 if (ndp->ru.x != NULL) fold_const(ndp->ru.x);
2868 if (ndp->lu.x != NULL) fold_const(ndp->lu.x);
2869 }
2870 }
2871
2872 /*
2873 * check if constant signed decimal expression
2874 */
is_signed_decimal(struct expr_t * xp)2875 static int32 is_signed_decimal(struct expr_t *xp)
2876 {
2877 switch ((byte) xp->optyp) {
2878 case MINUS: case PLUS: case TIMES: case DIV: case MOD:
2879 if (xp->lu.x != NULL) if (!is_signed_decimal(xp->lu.x)) return(FALSE);
2880 if (xp->ru.x != NULL) return(is_signed_decimal(xp->ru.x));
2881 return(TRUE);
2882 case NUMBER: case ISNUMBER:
2883 if (xp->szu.xclen == 1 || xp->szu.xclen > WBITS || xp->ibase != BDEC
2884 || !xp->has_sign) return(FALSE);
2885 break;
2886 default: return(FALSE);
2887 }
2888 return(TRUE);
2889 }
2890
2891 /*
2892 * ROUTINES TO CHECK AND NORMALIZE SELECT CONSTANT EXPRESIONS
2893 */
2894
2895 /*
2896 * check any psel or bsel constant index for in range and also
2897 * normalize
2898 */
chk_ndfolded_specops(struct expr_t * ndp)2899 static void chk_ndfolded_specops(struct expr_t *ndp)
2900 {
2901 switch ((byte) ndp->optyp) {
2902 /* error for these already caught */
2903 case ID: case GLBREF: case NUMBER: case ISNUMBER:
2904 case REALNUM: case ISREALNUM: case OPEMPTY:
2905 break;
2906 case LSB:
2907 /* know real number error already caught */
2908 /* but only call if constant - caller must check for required constant */
2909 if (ndp->ru.x->optyp == NUMBER || ndp->ru.x->optyp == ISNUMBER)
2910 chk_inrng_bsel(ndp);
2911 /* can have embedded selects */
2912 else chk_ndfolded_specops(ndp->ru.x);
2913 break;
2914 case PARTSEL:
2915 /* here - know selects must be numbers by here */
2916 chk_inrng_psel(ndp);
2917 break;
2918 case FCALL:
2919 /* this handles embedded special things like selects */
2920 chk_folded_fargs(ndp);
2921 break;
2922 default:
2923 if (ndp->lu.x != NULL) chk_ndfolded_specops(ndp->lu.x);
2924 if (ndp->ru.x != NULL) chk_ndfolded_specops(ndp->ru.x);
2925 }
2926 }
2927
2928 /*
2929 * check a constant bit select for in range - if non constant must
2930 * check at run time and this routine not called
2931 * know index expression already checked and folded
2932 * return F on error
2933 *
2934 * 2nd part of bit select checking - requires pass 2 all parameter
2935 * substitution and splitting done
2936 */
chk_inrng_bsel(struct expr_t * ndp)2937 static int32 chk_inrng_bsel(struct expr_t *ndp)
2938 {
2939 int32 err;
2940 int32 ri1, ri2, obwid;
2941 struct expr_t *idndp, *rconx;
2942 struct net_t *np;
2943 char s1[RECLEN];
2944
2945 idndp = ndp->lu.x;
2946 np = idndp->lu.sy->el.enp;
2947 rconx = ndp->ru.x;
2948
2949 /* even if not number will be converted to 32 bit x */
2950 /* register bit select of x ok, means make it x on rhs and all x's on lhs */
2951 err = FALSE;
2952
2953 ri1 = ri2 = -1;
2954 if (np->n_isarr) __getarr_range(np, &ri1, &ri2, &obwid);
2955 else if (np->n_isavec) __getwir_range(np, &ri1, &ri2);
2956 else __arg_terr(__FILE__, __LINE__);
2957
2958 /* case 1: reg/real that can be array */
2959 if (np->ntyp >= NONWIRE_ST)
2960 {
2961 /* case 1b: array */
2962 if (np->n_isarr)
2963 {
2964 sprintf(s1, "array index of %s", np->nsym->synam);
2965 if (!chknorm_range(rconx, ri1, ri2, s1, FALSE)) err = TRUE;
2966 }
2967 /* 2b: reg */
2968 else
2969 {
2970 sprintf(s1, "register bit select of %s", np->nsym->synam);
2971 if (!__nd_ndxnum(rconx, s1, FALSE)) err = TRUE;
2972 else if (!chknorm_range(rconx, ri1, ri2, s1, FALSE))
2973 err = TRUE;
2974 }
2975 }
2976 /* case 2: wire */
2977 else
2978 {
2979 sprintf(s1, "wire bit select of %s", np->nsym->synam);
2980 /* declarative either side select index must be non x/z */
2981 if (!__nd_ndxnum(rconx, s1, TRUE)) err = TRUE;
2982 /* if out of range, changed to end */
2983 else if (!chknorm_range(rconx, ri1, ri2, s1, FALSE)) err = TRUE;
2984 }
2985 return(!err);
2986 }
2987
2988 /*
2989 * check and emit error for out of range condition
2990 * also normalize if no error
2991 *
2992 * for all selects - string of type passed
2993 * know value number or is number or will not be passed
2994 */
chknorm_range(struct expr_t * rconx,int32 ri1,int32 ri2,char * emsg,int32 emit_err)2995 static int32 chknorm_range(struct expr_t *rconx, int32 ri1, int32 ri2,
2996 char *emsg, int32 emit_err)
2997 {
2998 register int32 iti, iti2;
2999 int32 err, indval, newindval, errindval, alloc_new_con;
3000 word32 *wp, *wp2;
3001
3002 if (rconx->optyp == NUMBER)
3003 {
3004 /* err/warn already emitted for this case */
3005 if (__contab[rconx->ru.xvi + 1] != 0) return(FALSE);
3006
3007 indval = (int32) __contab[rconx->ru.xvi];
3008 /* ---
3009 if (__debug_flg)
3010 __dbg_msg("$$$ in range check of %d in [%d:%d] - line %d\n",
3011 indval, ri1, ri2, __slin_cnt);
3012 --- */
3013 if (!in_range(indval, ri1, ri2, &errindval))
3014 {
3015 if (emit_err)
3016 __sgferr(836, "%s %d out of range [%d:%d] - end used", emsg, indval,
3017 ri1, ri2);
3018 else __sgfwarn(547, "%s %d out of range [%d:%d] - end used", emsg,
3019 indval, ri1, ri2);
3020
3021 indval = errindval;
3022 rconx->ru.xvi = __alloc_shareable_cval((word32) indval, 0, WBITS);
3023 }
3024 /* normalize */
3025 newindval = normalize_ndx_(indval, ri1, ri2);
3026 if (newindval != indval)
3027 {
3028 rconx->ru.xvi = __alloc_shareable_cval((word32) newindval, 0, WBITS);
3029 rconx->ind_noth0 = TRUE;
3030 }
3031 return(TRUE);
3032 }
3033 err = FALSE;
3034 alloc_new_con = FALSE;
3035 wp = &(__contab[rconx->ru.xvi]);
3036 wp2 = NULL;
3037 for (iti = 0; iti < __inst_mod->flatinum; iti++)
3038 {
3039 /* must normal any that are good */
3040 if (wp[2*iti + 1] != 0L) continue;
3041 indval = (int32) wp[2*iti];
3042 if (!in_range(indval, ri1, ri2, &errindval))
3043 {
3044 if (emit_err)
3045 __sgferr(837, "%s %d out of range [%d:%d] (inst. %d)", emsg,
3046 indval, ri1, ri2, iti);
3047 else __sgfwarn(548, "%s %d out of range [%d:%d] (inst %d)", emsg,
3048 indval, ri1, ri2, iti);
3049 if (!alloc_new_con)
3050 {
3051 /* allocate new and copy up to current */
3052 rconx->ru.xvi = __alloc_is_cval(__inst_mod->flatinum);
3053 wp2 = &(__contab[rconx->ru.xvi]);
3054 alloc_new_con = TRUE;
3055 for (iti2 = 0; iti2 < iti; iti2++)
3056 {
3057 wp2[2*iti2] = wp[2*iti2];
3058 wp2[2*iti2 + 1] = wp[iti2 + 1];
3059 }
3060 }
3061
3062 wp2[2*iti] = indval = errindval;
3063 /* SJM 12/22/03 - on error use end of range but b part must be set to 0 */
3064 wp2[2*iti + 1] = 0;
3065 err = TRUE;
3066 }
3067 /* know range are always non is form numbers - will have split if needed */
3068 /* normalize */
3069 newindval = normalize_ndx_(indval, ri1, ri2);
3070 /* notice if any not h:0 form all will be */
3071 if (alloc_new_con)
3072 {
3073 /* once any changed all must be copied */
3074 wp2[2*iti] = newindval;
3075 wp2[2*iti + 1] = 0;
3076 /* SJM 12/22/03 - if out of rng caused alloc new this may chg h:0 */
3077 if (newindval != indval) rconx->ind_noth0 = TRUE;
3078 }
3079 else if (newindval != indval)
3080 {
3081 /* allocate new and copy up to current */
3082 rconx->ru.xvi = __alloc_is_cval(__inst_mod->flatinum);
3083 wp2 = &(__contab[rconx->ru.xvi]);
3084 alloc_new_con = TRUE;
3085 for (iti2 = 0; iti2 < iti; iti2++)
3086 {
3087 wp2[2*iti2] = wp[2*iti2];
3088 wp2[2*iti2 + 1] = wp[iti2 + 1];
3089 }
3090 /* SJM 12/22/03 - must fill and set only when allocating new */
3091 /* this was wrongly out of loop so if same, wp2 was nil */
3092 wp2[2*iti] = newindval;
3093 wp2[2*iti + 1] = 0;
3094 rconx->ind_noth0 = TRUE;
3095 }
3096 }
3097 return(!err);
3098 }
3099
3100 /*
3101 * return T if value av between v1a and v2a
3102 * if F, sets newv1a and newv2a to new extrema
3103 */
in_range(int32 ai,int32 v1a,int32 v2a,int32 * newai)3104 static int32 in_range(int32 ai, int32 v1a, int32 v2a, int32 *newai)
3105 {
3106 /* case 1 low to high */
3107 if (v1a < v2a)
3108 {
3109 if (ai < v1a) { *newai = v1a; return(FALSE); }
3110 if (ai > v2a) { *newai = v2a; return(FALSE); }
3111 return(TRUE);
3112 }
3113 /* case 2 - normal high to low */
3114 if (ai > v1a) { *newai = v1a; return(FALSE); }
3115 if (ai < v2a) { *newai = v2a; return(FALSE); }
3116 return(TRUE);
3117 }
3118
3119 /*
3120 * check a part select for in range - must always be constant
3121 * know index expression already checked and folded
3122 * but need to convert to WBITS
3123 *
3124 * 2nd part of bit select checking - requires pass 2 all parameter
3125 * substitution and splitting done
3126 */
chk_inrng_psel(struct expr_t * ndp)3127 static int32 chk_inrng_psel(struct expr_t *ndp)
3128 {
3129 int32 err, ri1, ri2, pseli1, pseli2;
3130 struct expr_t *idndp, *rcon1, *rcon2;
3131 struct net_t *np;
3132 char s1[RECLEN];
3133
3134 idndp = ndp->lu.x;
3135 np = idndp->lu.sy->el.enp;
3136 rcon1 = ndp->ru.x->lu.x;
3137 rcon2 = ndp->ru.x->ru.x;
3138
3139 /* even if not number will be converted to 32 bit x */
3140 /* always error for part select range x/z - what does x in range mean */
3141 err = FALSE;
3142 sprintf(s1, "1st part select index of %s", np->nsym->synam);
3143 if (!__nd_ndxnum(rcon1, s1, TRUE)) err = TRUE;
3144 sprintf(s1, "2nd part select index of %s", np->nsym->synam);
3145 if (!__nd_ndxnum(rcon2, s1, TRUE)) err = TRUE;
3146
3147 /* parts selects of arrays not in language */
3148 __getwir_range(np, &ri1, &ri2);
3149 /* check psel direction and wire direction same */
3150 /* if errror (x/z for example) in range, cannot check direction */
3151 if (!err)
3152 {
3153 pseli1 = (int32) __contab[rcon1->ru.xvi];
3154 pseli2 = (int32) __contab[rcon2->ru.xvi];
3155 if ((ri1 < ri2 && pseli1 > pseli2) || (ri1 > ri2 && pseli1 < pseli2))
3156 {
3157 __sgferr(879,
3158 "part select %s range direction conflicts with net %s[%d:%d]",
3159 __msgexpr_tostr(__xs, ndp), __to_idnam(ndp->lu.x), ri1, ri2);
3160 err = TRUE;
3161 }
3162 }
3163 /* even if error - try to check and normalize - ignores any x's */
3164 sprintf(s1, "1st part select index of %s", np->nsym->synam);
3165 if (!chknorm_range(rcon1, ri1, ri2, s1, FALSE))
3166 err = TRUE;
3167 sprintf(s1, "2nd part select index of %s", np->nsym->synam);
3168 if (!chknorm_range(rcon2, ri1, ri2, s1, FALSE))
3169 err = TRUE;
3170 /* since will change out of range to top - need to reset widths */
3171 /* if no change will be same */
3172 pseli1 = (int32) __contab[rcon1->ru.xvi];
3173 pseli2 = (int32) __contab[rcon2->ru.xvi];
3174 ndp->szu.xclen = pseli1 - pseli2 + 1;
3175 return(!err);
3176 }
3177
3178 /*
3179 * check function call arguments after folding
3180 * mainly for checking the various special system function arguments
3181 * but also check actual and formal argument number
3182 */
chk_folded_fargs(struct expr_t * ndp)3183 static void chk_folded_fargs(struct expr_t *ndp)
3184 {
3185 register struct expr_t *fandp;
3186 register struct task_pin_t *tpp;
3187 int32 pwid;
3188 struct sy_t *syp;
3189 struct expr_t *idndp;
3190 struct task_t *tskp;
3191
3192 idndp = ndp->lu.x;
3193 syp = idndp->lu.sy;
3194
3195 /* SJM 10/08/04 - LOOKATME - think never need new ver 2001 x/z widening? */
3196 /* this checks system function arguments */
3197 if (syp->sytyp == SYM_SF) { chk_sysfargs_syntax(ndp); return; }
3198
3199 /* can have embedded fcalls and selects - check before arg no. match */
3200 /* notice checking these even for undeclared function */
3201 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
3202 chk_ndfolded_specops(fandp->lu.x);
3203
3204 /* if funcdef error, will not be declard and also cannot check params */
3205 /* but undeclared error already emitted */
3206 if (!syp->sydecl) return;
3207
3208 /* final check is formal and actual number must match for user functions */
3209 /* for now allowing conversions of any arg real or reg to any other */
3210 /* in apl sense - yes, semantics allows assignments in both directions */
3211
3212 tskp = syp->el.etskp;
3213 /* first pin is dummy return type */
3214 tpp = tskp->tskpins->tpnxt;
3215 /* point 1 past extra first argument - not part of source call */
3216 fandp = ndp->ru.x;
3217 for (; tpp != NULL; tpp = tpp->tpnxt, fandp = fandp->ru.x)
3218 {
3219 /* move to next actual argument */
3220 if (fandp == NULL)
3221 {
3222 __sgferr(840,
3223 "function %s called with too few arguments", __to_idnam(idndp));
3224 return;
3225 }
3226
3227 /* notice x/z widening does not effect num arg checking */
3228
3229
3230 /* nwid field not set yet */
3231 pwid = __get_netwide(tpp->tpsy->el.enp);
3232 /* SJM 10/08/04 - for Ver 2001 because WBITS can be 64 - must widen */
3233 /* unsized constant (unsiznum bit in expr rec on) to lhs width */
3234 /* folded bit not set for these but will be folded to number */
3235
3236 if (fandp->lu.x->optyp == NUMBER && fandp->lu.x->unsiznum
3237 && fandp->lu.x->szu.xclen < pwid)
3238 {
3239 fandp->lu.x = __widen_unsiz_rhs_assign(fandp->lu.x, pwid);
3240 }
3241 }
3242 if (fandp != NULL)
3243 __sgferr(841, "function %s called with too many arguments",
3244 __to_idnam(idndp));
3245 }
3246
3247 /*
3248 * ROUTINE TO CHECK AND CONVERT NUMBERS THAT MUST BE INDEXES
3249 */
3250
3251 /*
3252 * convert a number (non real) to 32 bit non x/z constant
3253 * if possible - else error or warn - return F on error
3254 *
3255 * called after structural checking and constant folding
3256 * always converts but returns FALSE if losing something
3257 * and make value WBIT wide x and emits error
3258 * for indices and ranges - can never be real and no scaling
3259 *
3260 * must be called with itree loc (inst and mod set)
3261 */
__nd_ndxnum(struct expr_t * ndp,char * emsg,int32 emit_err)3262 extern int32 __nd_ndxnum(struct expr_t *ndp, char *emsg, int32 emit_err)
3263 {
3264 int32 wlen, err;
3265 word32 *ap, *bp;
3266 word32 av, bv;
3267
3268 switch ((byte) ndp->optyp) {
3269 case ISNUMBER: return(nd_ndxisnum(ndp, emsg, emit_err));
3270 case NUMBER:
3271 wlen = wlen_(ndp->szu.xclen);
3272 ap = &(__contab[ndp->ru.xvi]);
3273 bp = &(ap[wlen]);
3274 if (ndp->szu.xclen > WBITS)
3275 {
3276 /* here always free-alloc to work constant */
3277 __free2_xtree(ndp);
3278 __init_xnd(ndp);
3279 ndp->optyp = NUMBER;
3280 ndp->szu.xclen = WBITS;
3281
3282
3283 if (!vval_is0_(&(ap[1]), ndp->szu.xclen - WBITS)
3284 || !vval_is0_(bp, ndp->szu.xclen))
3285 {
3286 av = bv = ALL1W;
3287 __force_base = BDEC;
3288 __msgexpr_tostr(__xs, ndp);
3289 __force_base = BNONE;
3290 err = TRUE;
3291 }
3292 else { av = ap[0]; bv = 0L; err = FALSE; }
3293 /* know this is WBITS */
3294 ndp->ru.xvi = __alloc_shareable_cval(av, bv, WBITS);
3295
3296 if (err) goto wr_err;
3297 return(TRUE);
3298 }
3299 ndp->szu.xclen = WBITS;
3300 if (bp[0] == 0L) return(TRUE);
3301 __force_base = BDEC;
3302 __msgexpr_tostr(__xs, ndp);
3303 __force_base = BNONE;
3304 ndp->ru.xvi = __alloc_shareable_cval(ALL1W, ALL1W, WBITS);
3305 goto wr_err;
3306 }
3307 /* SJM 05/22/00 - need to save expr for error message before cnv to x */
3308 __force_base = BDEC;
3309 __msgexpr_tostr(__xs, ndp);
3310 __force_base = BNONE;
3311
3312 /* normal expr - must convert to x */
3313 __free2_xtree(ndp);
3314 __init_xnd(ndp);
3315 ndp->optyp = NUMBER;
3316 ndp->szu.xclen = WBITS;
3317 ndp->ru.xvi = __alloc_shareable_cval(ALL1W, ALL1W, WBITS);
3318
3319 wr_err:
3320 if (emit_err)
3321 __sgferr(902, "%s value %s not required %d bit non x/z number",
3322 emsg, __xs, WBITS);
3323 else __sgfwarn(582, "%s value %s not required %d bit non x/z number",
3324 emsg, __xs, WBITS);
3325 return(FALSE);
3326 }
3327
3328 /*
3329 * need an index form number that fits in 32 or 64 for delays bits
3330 * know type is ISNUMBER or will not be called
3331 * return F on error (not good)
3332 *
3333 * always converts but returns FALSE if losing something
3334 * and make value WBIT x
3335 * assumes itree loc pushed
3336 */
nd_ndxisnum(struct expr_t * ndp,char * emsg,int32 emit_err)3337 static int32 nd_ndxisnum(struct expr_t *ndp, char *emsg, int32 emit_err)
3338 {
3339 register int32 iti;
3340 int32 good, wlen;
3341 word32 *wp, *wp2, *ap, *bp;
3342
3343 /* first do the checking */
3344 good = TRUE;
3345 wlen = wlen_(ndp->szu.xclen);
3346 wp = &(__contab[ndp->ru.xvi]);
3347
3348 for (iti = 0; iti < __inst_mod->flatinum; iti++)
3349 {
3350 ap = &(wp[2*wlen*iti]);
3351 bp = &(ap[wlen]);
3352 if (ndp->szu.xclen > WBITS)
3353 {
3354 if (!vval_is0_(&(ap[1]), ndp->szu.xclen - WBITS)
3355 || !vval_is0_(bp, ndp->szu.xclen)) goto x_err;
3356 continue;
3357 }
3358 if (bp[0] == 0L) continue;
3359
3360 x_err:
3361 __cur_sofs = 0;
3362 __force_base = BDEC;
3363 __msgnumexpr_tostr(__xs, ndp, iti);
3364 __force_base = BNONE;
3365 if (emit_err)
3366 __sgferr(902, "%s value %s not required %d bit non x/z number (inst. %d)",
3367 emsg, __xs, WBITS, iti);
3368 else
3369 __sgfwarn(582, "%s value %s not required %d bit non x/z number (inst. %d)",
3370 emsg, __xs, WBITS, iti);
3371 good = FALSE;
3372 ndp->ru.xvi = __alloc_shareable_cval(ALL1W, ALL1W, WBITS);
3373 }
3374 /* next convert if needed */
3375 if (ndp->szu.xclen > WBITS)
3376 {
3377 /* must access old expression constant value before freeing */
3378 wp = &(__contab[ndp->ru.xvi]);
3379
3380 __free2_xtree(ndp);
3381 __init_xnd(ndp);
3382 ndp->optyp = ISNUMBER;
3383 ndp->szu.xclen = WBITS;
3384 /* arg is words */
3385 ndp->ru.xvi = __alloc_is_cval(__inst_mod->flatinum);
3386 wp2 = &(__contab[ndp->ru.xvi]);
3387
3388 for (iti = 0; iti < __inst_mod->flatinum; iti++)
3389 {
3390 ap = &(wp[2*wlen*iti]);
3391 bp = &(ap[wlen]);
3392 wp2[2*iti] = ap[0];
3393 wp2[2*iti + 1] = bp[0];
3394 }
3395 }
3396 else ndp->szu.xclen = WBITS;
3397 return(good);
3398 }
3399
3400 /*
3401 * SYSTEM FUNCTION ARGUMENT CHECKING ROUTINES
3402 */
3403
3404 /*
3405 * check system functions call according to specific task argument
3406 * requirements not needed for user funcs, type mismatches just fixed
3407 * with copy there
3408 *
3409 * this routine must call chk rhsexpr for every argument
3410 * except know global and param substitution done
3411 * ndp is expr. node (i.e. left node is func name and right is args)
3412 *
3413 * here few special sys func. arg lists cause net to not be deleteable
3414 * but not called for all non special
3415 */
chk_sysfargs_syntax(struct expr_t * ndp)3416 static void chk_sysfargs_syntax(struct expr_t *ndp)
3417 {
3418 register struct expr_t *fandp;
3419 int32 anum, special_syntax;
3420 struct sy_t *syp;
3421 struct sysfunc_t *syfp;
3422 struct expr_t *fax;
3423 struct net_t *np;
3424
3425 syp = ndp->lu.x->lu.sy;
3426 syfp = syp->el.esyftbp;
3427 anum = __cnt_tfargs(ndp->ru.x);
3428
3429 /* special check for 1 arg. */
3430 if (anum == 1 && ndp->ru.x->lu.x->optyp == OPEMPTY)
3431 {
3432 __sgfwarn(633,
3433 "system function call: %s(); has one empty argument - for no arguments omit the ()",
3434 syp->synam);
3435 }
3436
3437 special_syntax = FALSE;
3438 switch (syfp->syfnum) {
3439 /* functions that require special handling */
3440 case STN_ITOR:
3441 if (anum != 1) { sf_errifn(syp, 1); break; }
3442 fax = ndp->ru.x->lu.x;
3443 /* 32 bit width dependendent */
3444 /* this should probably allow 64 bit integers */
3445 __chk_rhsexpr(fax, WBITS);
3446 if (fax->szu.xclen > WBITS || fax->is_real)
3447 __sgferr(859,
3448 "%s system function call argument %s not required width %d integer or reg",
3449 syp->synam, __msgexpr_tostr(__xs, fax), WBITS);
3450 special_syntax = TRUE;
3451 break;
3452 case STN_BITSTOREAL:
3453 if (anum != 1) { sf_errifn(syp, 1); break; }
3454 fax = ndp->ru.x->lu.x;
3455 /* must set arg. rhs expression width using 64 bit context */
3456 /* just overwrites one that is there */
3457 __chk_rhsexpr(fax, REALBITS);
3458 /* 64 bit width dependendent */
3459 if (fax->szu.xclen != 64 || fax->is_real)
3460 __sgfwarn(634,
3461 "%s system function call argument %s should be 64 bit wide non real",
3462 syp->synam, __msgexpr_tostr(__xs, fax));
3463 special_syntax = TRUE;
3464 break;
3465 case STN_RTOI:
3466 case STN_REALTOBITS:
3467 if (anum != 1) { sf_errifn(syp, 1); break; }
3468 fax = ndp->ru.x->lu.x;
3469 __chk_rhsexpr(fax, 0);
3470 if (!fax->is_real)
3471 __sgferr(843,
3472 "%s system function call argument %s is not required real expression",
3473 syp->synam, __msgexpr_tostr(__xs, fax));
3474 special_syntax = TRUE;
3475 break;
3476 case STN_SIGNED:
3477 if (anum != 1) { sf_errifn(syp, 1); break; }
3478 fax = ndp->ru.x->lu.x;
3479 /* no context for this special case sys func that does nothing */
3480 /* and whose return value width is same as arg width */
3481 __chk_rhsexpr(fax, 0);
3482 if (fax->has_sign)
3483 __sgfinform(3007,
3484 "argment %s to new 2001 $signed system task already signed",
3485 __msgexpr_tostr(__xs, fax));
3486 special_syntax = TRUE;
3487 break;
3488 case STN_UNSIGNED:
3489 if (anum != 1) { sf_errifn(syp, 1); break; }
3490 fax = ndp->ru.x->lu.x;
3491 /* no context for this special case sys func that does nothing */
3492 /* and whose return value width is same as arg width */
3493 __chk_rhsexpr(fax, 0);
3494 if (!fax->has_sign)
3495 __sgfinform(3007,
3496 "argment %s to new 2001 $word32 system task already unsigned",
3497 __msgexpr_tostr(__xs, fax));
3498 special_syntax = TRUE;
3499 break;
3500 case STN_COUNT_DRIVERS:
3501 chksf_count_drivers(ndp, anum);
3502 special_syntax = TRUE;
3503 break;
3504 case STN_GETPATTERN:
3505 __rhs_isgetpat = TRUE;
3506 chksf_getpattern(syp, ndp, anum);
3507 special_syntax = TRUE;
3508 break;
3509 case STN_SCALE:
3510 /* this takes one module value (cannot be expr.) that should be time */
3511 special_syntax = TRUE;
3512 if (anum != 1) { sf_errifn(syp, 1); break; }
3513 fax = ndp->ru.x->lu.x;
3514 if (fax->optyp != GLBREF)
3515 {
3516 __sgferr(844,
3517 "$scale system function argument %s must be cross module hierarchical reference",
3518 __msgexpr_tostr(__xs, fax));
3519 break;
3520 }
3521 syp = fax->lu.sy;
3522 if (syp->sytyp == SYM_M || syp->sytyp == SYM_I)
3523 __arg_terr(__FILE__, __LINE__);
3524 np = syp->el.enp;
3525 if (__get_netwide(np) > TIMEBITS)
3526 __sgfwarn(637,
3527 "$scale argument %s value wider than %d bits - will be truncated",
3528 fax->ru.grp->gnam, TIMEBITS);
3529 break;
3530 case STN_Q_FULL:
3531 chksf_q_full(ndp, anum);
3532 special_syntax = TRUE;
3533 break;
3534 case STN_RANDOM:
3535 /* various dist. of random number generators - all params ins, ret. int32 */
3536 chksf_rand(ndp, 1, anum);
3537 special_syntax = TRUE;
3538 break;
3539 case STN_DIST_CHI_SQUARE:
3540 case STN_DIST_EXPONENTIAL:
3541 case STN_DIST_POISSON:
3542 case STN_DIST_T:
3543 chksf_rand(ndp, 2, anum);
3544 special_syntax = TRUE;
3545 break;
3546 case STN_DIST_UNIFORM:
3547 case STN_DIST_NORMAL:
3548 case STN_DIST_ERLANG:
3549 chksf_rand(ndp, 3, anum);
3550 special_syntax = TRUE;
3551 break;
3552
3553 /* functions that must not have any arguments */
3554 case STN_REALTIME: case STN_STIME: case STN_TIME:
3555 case STN_STICKSTIME: case STN_TICKSTIME:
3556 case STN_RESET_COUNT: case STN_RESET_VALUE:
3557 if (anum != 0)
3558 {
3559 /* needs to be warning and throw away arguments */
3560 __sgferr(846,
3561 "%s system function has %d arguments but no arguments allowed",
3562 syp->synam, anum);
3563 ndp->ru.x = NULL;
3564 }
3565 break;
3566
3567 /* functions that take exactly one argument */
3568 case STN_FOPEN:
3569 /* AIV 09/08/03 - changed now can take one or 2 args */
3570 /* $fopen([filename]) (mcd form) or $fopen([filename], [open type str]) */
3571 if (anum !=1 && anum !=2)
3572 {
3573 __sgferr(851,
3574 "%s system function illegal number of arguments (%d) - 1 or 2 legal",
3575 syp->synam, anum);
3576 }
3577 break;
3578 /* AIV 09/08/03 - new fileio system functions */
3579 case STN_FGETC: case STN_FTELL: case STN_REWIND:
3580 /* code = $fgetc([fd]), code = $ftell([fd]), code = $rewind([fd]) */
3581 if (anum != 1) sf_errifn(syp, 1);
3582 break;
3583 case STN_UNGETC:
3584 /* code = $ungetc([char], [fd]) - [fd] has high bit on */
3585 if (anum != 2) sf_errifn(syp, 2);
3586 break;
3587 case STN_FSEEK:
3588 /* code = $fseek([fd], [offset], [operation]) - [fd] has high bit on */
3589 /* $fseek([fd], [offset], [operation]) */
3590 if (anum != 3) sf_errifn(syp, 3);
3591 break;
3592 case STN_FGETS:
3593 /* code = $fgets([proc lhs], [fd]) */
3594 /* this inhibits normal rhs checking of args */
3595 special_syntax = TRUE;
3596 if (anum != 2) { sf_errifn(syp, 2); break; }
3597 fax = ndp->ru.x;
3598 __chk_lhsexpr(fax->lu.x, LHS_PROC);
3599 fax = fax->ru.x;
3600 __chk_rhsexpr(fax->lu.x, 32);
3601 break;
3602 case STN_FERROR:
3603 /* [user errno] = $ferror([fd], [proc lhs]) */
3604 /* this inhibits normal rhs checking of args */
3605 if (anum != 2) { sf_errifn(syp, 3); return; }
3606 fax = ndp->ru.x;
3607 __chk_rhsexpr(fax->lu.x, 32);
3608 fax = fax->ru.x;
3609 __chk_lhsexpr(fax->lu.x, LHS_PROC);
3610 special_syntax = TRUE;
3611 break;
3612 case STN_FSCANF: case STN_SSCANF:
3613 /* $fscanf([fd], ...) or $sscanf([proc lhs], ...) */
3614 if (anum < 3)
3615 {
3616 __sgferr(851, "%s system function does not have required three arguments",
3617 syp->synam);
3618 return;
3619 }
3620 fax = ndp->ru.x;
3621 /* width self determined */
3622 __chk_rhsexpr(fax->lu.x, 0);
3623 fax = fax->ru.x;
3624 fax = fax->ru.x;
3625 /* width self determined */
3626 __chk_rhsexpr(fax->lu.x, 0);
3627 for (fandp = fax->ru.x; fandp != NULL; fandp = fandp->ru.x)
3628 {
3629 __chk_lhsexpr(fandp->lu.x, LHS_PROC);
3630 }
3631 special_syntax = TRUE;
3632 break;
3633 case STN_FREAD:
3634 /* for reg: code = $fgets([proc lhs], [fd]) - size from [proc lhs] size */
3635 /* for mem $fgets(mem, [fd], {[start], [count] optional}) */
3636 if (anum < 2 || anum > 4)
3637 {
3638 __sgferr(851,
3639 "%s system function illegal number of arguments (%d) - 2, 3, or 4 legal",
3640 syp->synam, anum);
3641 }
3642 fax = ndp->ru.x;
3643 /* if first arg is memory and not indexed ok */
3644 if (fax->lu.x->optyp == ID || fax->lu.x->optyp == GLBREF)
3645 {
3646 if (fax->lu.x->lu.sy->el.enp->n_isarr) goto first_arg_ok;
3647 }
3648 __chk_lhsexpr(fax->lu.x, LHS_PROC);
3649 first_arg_ok:
3650 /* check rest of args as normal rhs */
3651 for (fandp = fax->ru.x; fandp != NULL; fandp = fandp->ru.x)
3652 {
3653 fax = fandp->lu.x;
3654 /* next 3 are 32 bits numbers and optional */
3655 __chk_rhsexpr(fax, WBITS);
3656 }
3657 special_syntax = TRUE;
3658 break;
3659 case STN_TESTPLUSARGS:
3660 if (anum != 1) sf_errifn(syp, 1);
3661 break;
3662 case STN_SCANPLUSARGS:
3663 case STN_VALUEPLUSARGS:
3664 if (anum != 2) sf_errifn(syp, 2);
3665 fandp = ndp->ru.x;
3666 if (anum >= 1) { fax = fandp->lu.x; __chk_rhsexpr(fax, 0); }
3667 if (anum >= 2)
3668 { fandp = fandp->ru.x; fax = fandp->lu.x; __chk_lhsexpr(fax, LHS_PROC); }
3669 special_syntax = TRUE;
3670 break;
3671 /* SJM 03/09/00 - added built-in math functins and can be used with */
3672 /* constant args in parameter expressions */
3673 case STN_COS: case STN_SIN: case STN_TAN: case STN_ACOS: case STN_ASIN:
3674 case STN_ATAN: case STN_COSH: case STN_SINH: case STN_TANH:
3675 case STN_INT: case STN_SGN:
3676 case STN_LN: case STN_LOG10: case STN_ABS: case STN_SQRT: case STN_EXP:
3677 case STN_HSQRT: case STN_HLOG: case STN_HLOG10:
3678 case STN_ATANH: case STN_ACOSH: case STN_ASINH:
3679 if (anum != 1) sf_errifn(syp, 1);
3680 break;
3681 case STN_POW: case STN_MIN: case STN_MAX:
3682 case STN_HPOW: case STN_HPWR: case STN_HSIGN: case STN_HDB:
3683 case STN_HYPOT: case STN_ATAN2:
3684 if (anum != 2) sf_errifn(syp, 2);
3685 break;
3686 default:
3687 if (syfp->syfnum >= BASE_VERIUSERTFS && (int32) syfp->syfnum <= __last_systf)
3688 {
3689 /* chk and bld user tf_ or systf vpi_ pli function or real function */
3690 chkbld_pli_func(ndp, (int32) syfp->syfnum);
3691 return;
3692 }
3693 /* fall through on built-in system function */
3694 }
3695 if (special_syntax) return;
3696
3697 /* if this is not executed width not check for wrong array/event usage */
3698 /* or bit/part select problems */
3699 /* this checks all of argument as rhs expr. - prev. chk rhsexpr stopped */
3700 /* when hit system function */
3701 for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
3702 {
3703 fax = fandp->lu.x;
3704 __chk_rhsexpr(fax, 0);
3705 }
3706 }
3707
3708 /*
3709 * check build tf rec for pli function
3710 *
3711 * this is passed top of fcall expr. node
3712 * know this is called with __cur task and __cur mod set
3713 * do everything but call user checktf even if errors
3714 * will probably crash here if user pointers bad
3715 */
chkbld_pli_func(struct expr_t * fcallx,int32 sfnum)3716 static void chkbld_pli_func(struct expr_t *fcallx, int32 sfnum)
3717 {
3718 int32 sav_errcnt, anum;
3719 struct tfrec_t *tfrp;
3720 struct expr_t *cpfcallx;
3721
3722 sav_errcnt = __pv_err_cnt;
3723
3724 /* also check syntax of argument list */
3725 /* this sets tf_rw flags */
3726 if (fcallx->ru.x != NULL)
3727 {
3728 chk_pli_arglist(fcallx->ru.x, sfnum);
3729 anum = __cnt_tfargs(fcallx->ru.x);
3730 }
3731 else anum = 0;
3732
3733 /* need separate routine for vpi_ systfs compiletf and maybe sizetf */
3734 if (sfnum > __last_veriusertf)
3735 {
3736 __chkbld_vpi_systf_func(fcallx);
3737 return;
3738 }
3739
3740 /* need both direction links */
3741 /* SJM 04/06/07 since free del list expr calls after delay must make */
3742 /* copy here to handle case of tf sysfunc that is delay expr */
3743 cpfcallx = __copy_expr(fcallx);
3744
3745 /* allocate the tf aux d.s. and link on to func. name expr unused len fld */
3746 /* every call of tf_ system function needs d.s. chges (pvc flags etc) */
3747 /* AIV 05/17/07 - need to pass the new copied expression - not the actual */
3748 tfrp = chkalloc_tfrec(cpfcallx->ru.x, anum);
3749 tfrp->tf_func = TRUE;
3750 tfrp->tfu.callx = cpfcallx;
3751 /* need to set the xfrec for the copied expression as well */
3752 cpfcallx->lu.x->szu.xfrec = tfrp;
3753
3754 fcallx->lu.x->szu.xfrec = tfrp;
3755 if (__tfrec_hdr == NULL) __tfrec_hdr = __tfrec_end = tfrp;
3756 else { __tfrec_end->tfrnxt = tfrp; __tfrec_end = tfrp; }
3757
3758 /* cannot call tf routines if errors */
3759 if (__pv_err_cnt != sav_errcnt) return;
3760
3761 /* call the sizetf - this sets the func. return width in tf rec */
3762 /* must he called or cannot check rhs exprs */
3763 __pli_func_sizetf(fcallx);
3764 /* AIV 05/17/07 - need to set size of copied function as well */
3765 __pli_func_sizetf(cpfcallx);
3766 }
3767
3768 /*
3769 * check PLI _tf and vpi_ systf routine argument syntax
3770 * notice build aux. d.s. and call checktf routine during prep for tf_
3771 */
chk_pli_arglist(register struct expr_t * argxp,int32 stfnum)3772 static void chk_pli_arglist(register struct expr_t *argxp, int32 stfnum)
3773 {
3774 int32 lhstyp;
3775 struct expr_t *xp;
3776 struct sy_t *syp;
3777
3778 /* right offspring is first argument */
3779 for (; argxp != NULL; argxp = argxp->ru.x)
3780 {
3781 xp = argxp->lu.x;
3782 /* XMR task and inst scope arguments legal and are not checked */
3783 /* PLI deals with argument */
3784 /* if expr. can't contain scope object - i.e. this is special form */
3785 if (xp->optyp == GLBREF)
3786 {
3787 syp = xp->lu.sy;
3788 /* LOOKATME - why are top level modules SYM M not SYM I? */
3789 if (syp->sytyp == SYM_M) continue;
3790
3791 if (syp->sytyp == SYM_I || syp->sytyp == SYM_TSK
3792 || syp->sytyp == SYM_LB) continue;
3793
3794 /* function scope object illegal - will be converted to fcall */
3795 /* DBG remove --- */
3796 if (syp->sytyp == SYM_F) __misc_terr(__FILE__, __LINE__);
3797 /* --- */
3798 /* fall through normal XMR */
3799 }
3800
3801 /* for vpi_ system tasks or functions, entire array legal */
3802 if (stfnum > __last_veriusertf)
3803 {
3804 if ((xp->optyp == ID || xp->optyp == GLBREF) && xp->lu.sy->sytyp == SYM_N
3805 && xp->lu.sy->el.enp->n_isarr) continue;
3806 }
3807 /* can be assigned to must be treated as lhs expr */
3808 if (tfexpr_isrw(xp))
3809 {
3810 if (lhs_is_decl(xp)) lhstyp = LHS_DECL; else lhstyp = LHS_PROC;
3811 __chk_lhsexpr(xp, lhstyp);
3812 xp->tf_isrw = TRUE;
3813 }
3814 else __chk_rhsexpr(xp, 0);
3815 }
3816 }
3817
3818 /*
3819 * for user tf (task or func.) args - set tf_isrw if expr can be assigned to
3820 * concatenates are legal Verilog but not PLI tf_ lvalues
3821 */
tfexpr_isrw(struct expr_t * ndp)3822 static int32 tfexpr_isrw(struct expr_t *ndp)
3823 {
3824 struct net_t *np;
3825
3826 /* only simplify/check bit and part select expressions (not lvals) */
3827 switch ((byte) ndp->optyp) {
3828 case ID: case GLBREF:
3829 /* notice even for global lu.x actual symbol set */
3830 if (ndp->lu.sy->sytyp != SYM_N) return(FALSE);
3831 np = ndp->lu.sy->el.enp;
3832 /* possible for unexpanded parameters here */
3833 if (np->n_isaparam) return(FALSE);
3834 return(TRUE);
3835 /* this include array index */
3836 case LSB: case PARTSEL: return(TRUE);
3837 }
3838 return(FALSE);
3839 }
3840
3841 /*
3842 * return T if lhs rw expr. is declarative else F is procedural
3843 */
lhs_is_decl(struct expr_t * xp)3844 static int32 lhs_is_decl(struct expr_t *xp)
3845 {
3846 struct net_t *np;
3847
3848 if (xp->optyp == LSB || xp->optyp == PARTSEL)
3849 np = xp->lu.x->lu.sy->el.enp;
3850 else np = xp->lu.sy->el.enp;
3851 if (np->ntyp >= NONWIRE_ST) return(FALSE);
3852 return(TRUE);
3853 }
3854
3855 /*
3856 * alloc and initialize a tf_ auxialiary record
3857 * always set 0th arg. (for tf_ func only) to nil here
3858 */
chkalloc_tfrec(struct expr_t * argxp,int32 anum)3859 static struct tfrec_t *chkalloc_tfrec(struct expr_t *argxp,
3860 int32 anum)
3861 {
3862 register int32 i;
3863 int32 insts;
3864 struct tfrec_t *tfrp;
3865
3866 if (__inst_mod == NULL) insts = 1;
3867 else insts = __inst_mod->flatinum;
3868 tfrp = (struct tfrec_t *) __my_malloc(sizeof(struct tfrec_t));
3869 tfrp->tf_func = FALSE;
3870 tfrp->fretreal = FALSE;
3871 tfrp->tffnam_ind = __sfnam_ind;
3872 tfrp->tflin_cnt = __slin_cnt;
3873 tfrp->tfu.callx = NULL;
3874 /* this is number - 1 since 0th is unused for task ret. val for func. */
3875 tfrp->tfanump1 = anum + 1;
3876 tfrp->fretsiz = -1;
3877 tfrp->tf_inmdp = __inst_mod;
3878 tfrp->tf_intskp = __cur_tsk;
3879 tfrp->tfargs = alloc_tfarg(argxp, anum + 1, insts);
3880
3881 tfrp->asynchon = (byte *) __my_malloc(insts);
3882 memset(tfrp->asynchon, 0, insts);
3883 /* some save area for user between calls but rather pointless */
3884 tfrp->savwrkarea = (char **) __my_malloc(insts*sizeof(char *));
3885 tfrp->pvcdcep = (struct dceauxlst_t **)
3886 __my_malloc(insts*sizeof(struct dceauxlst_t *));
3887 tfrp->sync_tevp = (i_tev_ndx *) __my_malloc(insts*sizeof(i_tev_ndx));
3888 tfrp->rosync_tevp = (i_tev_ndx *) __my_malloc(insts*sizeof(i_tev_ndx));
3889 tfrp->setd_telst = (struct tevlst_t **)
3890 __my_malloc(insts*sizeof(struct tevlst_t *));
3891 for (i = 0; i < insts; i++)
3892 {
3893 tfrp->savwrkarea[i] = NULL;
3894 tfrp->pvcdcep[i] = NULL;
3895 tfrp->sync_tevp[i] = -1;
3896 tfrp->rosync_tevp[i] = -1;
3897 tfrp->setd_telst[i] = NULL;
3898 }
3899 tfrp->tfrnxt = NULL;
3900 return(tfrp);
3901 }
3902
3903 /*
3904 * allocate and initialize the tf argument record array
3905 * notice this is an array not an array of ptrs to the records
3906 */
alloc_tfarg(register struct expr_t * argxp,int32 anump1,int32 insts)3907 static struct tfarg_t *alloc_tfarg(register struct expr_t *argxp,
3908 int32 anump1, int32 insts)
3909 {
3910 register int32 i, pi;
3911 register struct expr_t *xp;
3912 struct tfarg_t *tfatab, *tfap;
3913
3914 /* notice if no args still will allocate 1 even if tf_ task */
3915 tfatab = (struct tfarg_t *) __my_malloc(anump1*sizeof(struct tfarg_t));
3916 tfap = &(tfatab[0]);
3917 tfap->arg.awp = NULL;
3918 tfap->old_pvc_flgs = NULL;
3919 tfap->sav_pvc_flgs = NULL;
3920 tfap->sav_xinfos = NULL;
3921 tfap->tfdrv_wp.wp = NULL;
3922
3923 for (pi = 1; argxp != NULL; argxp = argxp->ru.x, pi++)
3924 {
3925 tfap = &(tfatab[pi]);
3926 xp = argxp->lu.x;
3927 tfap->arg.axp = xp;
3928 tfap->old_pvc_flgs = (byte *) __my_malloc(insts);
3929 memset(tfap->old_pvc_flgs, 0, insts);
3930 tfap->sav_pvc_flgs = (byte *) __my_malloc(insts);
3931 memset(tfap->sav_pvc_flgs, 0, insts);
3932 tfap->dputp_tedlst = (struct dltevlst_t **)
3933 __my_malloc(insts*sizeof(struct dltevlst_t *));
3934 for (i = 0; i < insts; i++) tfap->dputp_tedlst[i] = NULL;
3935 tfap->sav_xinfos = (char **) __my_malloc(insts*sizeof(char *));
3936 for (i = 0; i < insts; i++) tfap->sav_xinfos[i] = NULL;
3937
3938 if (xp->tf_isrw)
3939 {
3940 if (xp->optyp == ID || xp->optyp == GLBREF)
3941 tfap->anp = xp->lu.sy->el.enp;
3942 else if (xp->optyp == LSB || xp->optyp == PARTSEL)
3943 tfap->anp = xp->lu.x->lu.sy->el.enp;
3944 else __case_terr(__FILE__, __LINE__);
3945 tfap->tfdrv_wp.bp = NULL;
3946 /* only have node infos if expr. rw */
3947 }
3948 /* SJM 04/20/00 - must allo set drive to nil if not rw */
3949 else { tfap->anp = NULL; tfap->tfdrv_wp.bp = NULL; }
3950 }
3951 return(tfatab);
3952 }
3953
3954 /*
3955 * count no. of function arguments
3956 */
__cnt_tfargs(register struct expr_t * argndp)3957 extern int32 __cnt_tfargs(register struct expr_t *argndp)
3958 {
3959 int32 anum;
3960
3961 for (anum = 0; argndp != NULL; argndp = argndp->ru.x) anum++;
3962 return(anum);
3963 }
3964
3965 /*
3966 * check count drivers system function arguments (lhs)
3967 */
chksf_count_drivers(struct expr_t * ndp,int32 anum)3968 static void chksf_count_drivers(struct expr_t *ndp, int32 anum)
3969 {
3970 register struct expr_t *fandp;
3971
3972 if (anum > 6 || anum < 1)
3973 {
3974 __sgferr(847,
3975 "$countdrivers system function call must have from 1 to 6 arguments - has %d",
3976 anum);
3977 return;
3978 }
3979
3980 /* first argument must be good declarative lhs and 1 bit form */
3981 fandp = ndp->ru.x;
3982 __chk_lhsexpr(fandp->lu.x, LHS_DECL);
3983 if (!is_1bwire(fandp->lu.x))
3984 {
3985 __sgferr(903,
3986 "$count_drivers system function first argument %s not scalar or constant bit select",
3987 __msgexpr_tostr(__xs, fandp->lu.x));
3988 }
3989
3990 /* rest of arguments must be procedural lhs since output params */
3991 /* ,, common and legal lhs - these do not effect gate eater must be reg */
3992 for (fandp = fandp->ru.x; fandp != NULL; fandp = fandp->ru.x)
3993 __chk_lhsexpr(fandp->lu.x, LHS_PROC);
3994 }
3995
3996 /*
3997 * return T if expression is a scalar wire or a bit select of scalared wire
3998 * also if bit select index x
3999 */
is_1bwire(struct expr_t * ndp)4000 static int32 is_1bwire(struct expr_t *ndp)
4001 {
4002 int32 rv;
4003 struct net_t *np;
4004 struct expr_t *idndp;
4005 struct xstk_t *xsp;
4006
4007 if (ndp->optyp == LSB)
4008 {
4009 idndp = ndp->lu.x;
4010 if (ndp->ru.x->optyp != NUMBER && ndp->ru.x->optyp != ISNUMBER)
4011 return(FALSE);
4012 np = idndp->lu.sy->el.enp;
4013 if (np->nrngrep == NX_CT)
4014 {
4015 if ((__no_expand && np->nu.ct->n_spltstate != SPLT_SCAL)
4016 || np->nu.ct->n_spltstate == SPLT_VECT) return(FALSE);
4017 }
4018 else if (!np->vec_scalared) return(FALSE);
4019
4020 xsp = __eval_xpr(ndp->ru.x);
4021 /* if out of range or constant x index still error here */
4022 if (!vval_is0_(xsp->bp, xsp->xslen)) rv = FALSE; else rv = TRUE;
4023 __pop_xstk();
4024 return(rv);
4025 }
4026 else
4027 {
4028 np = ndp->lu.sy->el.enp;
4029 if (ndp->optyp != ID && ndp->optyp != GLBREF) return(FALSE);
4030 np = ndp->lu.sy->el.enp;
4031 }
4032 if (np->ntyp >= NONWIRE_ST) return(FALSE);
4033 return(TRUE);
4034 }
4035
4036 /*
4037 * check getpattern system function arguments - checks very limited usage
4038 */
chksf_getpattern(struct sy_t * syp,struct expr_t * ndp,int32 anum)4039 static void chksf_getpattern(struct sy_t *syp, struct expr_t *ndp,
4040 int32 anum)
4041 {
4042 struct net_t *np;
4043 struct expr_t *fax;
4044
4045 if (anum != 1)
4046 {
4047 sf_errifn(syp, 1);
4048 if (anum > 1) ndp->ru.x->ru.x = NULL;
4049 else return;
4050 }
4051 if (!__chking_conta)
4052 __sgferr(849,
4053 "$getpattern system function call not on right hand side of continuous assignment");
4054 fax = ndp->ru.x->lu.x;
4055 if (fax->optyp == LSB)
4056 {
4057 np = fax->lu.x->lu.sy->el.enp;
4058 if (np->n_isarr)
4059 {
4060 /* getpattern result is same width as arg. */
4061 /* must make sure constant folding done */
4062 __chk_rhsexpr(fax, 0);
4063 if (fax->ru.x->optyp != ID) goto gpat_err;
4064 ndp->szu.xclen = fax->lu.x->szu.xclen;
4065 return;
4066 }
4067 }
4068 gpat_err:
4069 __sgferr(850,
4070 "argument to $getpattern system function not variable indexed array");
4071 }
4072
4073 /*
4074 * system function wrong number of arguments error
4075 */
sf_errifn(struct sy_t * syp,int32 expn)4076 static void sf_errifn(struct sy_t *syp, int32 expn)
4077 {
4078 __sgferr(851, "system function %s call does not have required %d arguments",
4079 syp->synam, expn);
4080 }
4081
4082 /*
4083 * check the $q_full system function
4084 * if final argument not needed can be left out
4085 */
chksf_q_full(struct expr_t * ndp,int32 anum)4086 static void chksf_q_full( struct expr_t *ndp, int32 anum)
4087 {
4088 struct expr_t *fax;
4089
4090 /* but for now making it an error */
4091 if (anum > 2 || anum < 1)
4092 __sgferr(847,
4093 "$q_full system function must have either 1 or 2 arguments not %d", anum);
4094
4095 fax = ndp->ru.x;
4096 /* context here must be WBITS and also must change width during exec */
4097 __chk_rhsexpr(fax->lu.x, WBITS);
4098 if (anum == 2) { fax = fax->ru.x; __chk_lhsexpr(fax->lu.x, LHS_PROC); }
4099 }
4100
4101 /*
4102 * check a random number generator type system function
4103 *
4104 * know first argument if present is always seed lvalue
4105 */
chksf_rand(struct expr_t * ndp,int32 maxanum,int32 anum)4106 static void chksf_rand(struct expr_t *ndp, int32 maxanum, int32 anum)
4107 {
4108 struct sy_t *syp;
4109 struct expr_t *fax;
4110
4111 syp = ndp->lu.x->lu.sy;
4112 if (anum > maxanum)
4113 {
4114 __sgferr(847,
4115 "%s system function must have less than %d arguments - has %d",
4116 syp->synam, maxanum + 1, anum);
4117 return;
4118 }
4119 if (anum == 0) return;
4120 fax = ndp->ru.x;
4121 if (fax->lu.x->optyp != OPEMPTY)
4122 {
4123 /* seed argument can be any procedural lhs including ,, - OPEMPTY */
4124 __chk_lhsexpr(fax->lu.x, LHS_PROC);
4125 if (fax->lu.x->szu.xclen != WBITS)
4126 __sgferr(877, "%s system function first argument %s must be 32 bits",
4127 syp->synam, __msgexpr_tostr(__xs, fax->lu.x));
4128 }
4129 /* check from 2nd on - must be rvalue not lvalue */
4130 for (fax = fax->ru.x; fax != NULL; fax = fax->ru.x)
4131 __chk_rhsexpr(fax->lu.x, 0);
4132 }
4133
4134 /*
4135 * PASS 2 LHS EXPRESSION CHECKING ROUTINES
4136 */
4137
4138 /*
4139 * check a lhs expression
4140 * needs __sfnam_ind to be set before called
4141 * convention is to mark all ID and GLBIDs that are lhs expr and top
4142 * expr. as lhs expr.
4143 */
__chk_lhsexpr(struct expr_t * ndp,int32 lhstyp)4144 extern int32 __chk_lhsexpr(struct expr_t *ndp, int32 lhstyp)
4145 {
4146 if (ndp->optyp == LCB)
4147 {
4148 unwind_lhsconcats(ndp);
4149 }
4150 if (!chksyn_lhsexpr(ndp, TRUE, lhstyp)) return(FALSE);
4151 /* even if error try to set */
4152 __set_lhswidth(ndp);
4153 ndp->x_islhs = TRUE;
4154 return(TRUE);
4155 }
4156
4157 /*
4158 * check syntax of lhs lvalue expression
4159 * also marks lhs expression nodes and wires
4160 * needs __sfnam_ind to be set before called
4161 * return FALSE on error
4162 */
chksyn_lhsexpr(struct expr_t * ndp,int32 is_top,int32 lhstyp)4163 static int32 chksyn_lhsexpr(struct expr_t *ndp, int32 is_top, int32 lhstyp)
4164 {
4165 struct expr_t *erndp;
4166 struct net_t *np;
4167 struct sy_t *syp;
4168
4169 /* only simplify/check bit and part select expressions (not lvals) */
4170 switch ((byte) ndp->optyp) {
4171 case ID: case GLBREF:
4172 syp = ndp->lu.sy;
4173 if (syp->sytyp != SYM_N)
4174 {
4175 __sgferr(1046, "symbol %s of type %s illegal left hand side value",
4176 syp->synam, __to_sytyp(__xs, syp->sytyp));
4177 return(FALSE);
4178 }
4179
4180 ndp->szu.xclen = __get_netwide(syp->el.enp);
4181 ndp->x_islhs = TRUE;
4182 erndp = ndp;
4183
4184 /* unindexed array illegal on lhs */
4185 np = syp->el.enp;
4186 if (np->n_isarr)
4187 {
4188 __sgferr(1046, "entire (unindexed) array %s illegal left hand side value",
4189 np->nsym->synam);
4190 return(FALSE);
4191 }
4192
4193 chk_id:
4194 np = syp->el.enp;
4195 if (np->n_isaparam)
4196 {
4197 __sgferr(854, "assignment to parameter illegal");
4198 return(FALSE);
4199 }
4200 if (np->nrngrep == NX_CT)
4201 {
4202 if (np->nu.ct->n_onlhs) np->nu.ct->n_2ndonlhs = TRUE;
4203 else np->nu.ct->n_onlhs = TRUE;
4204 }
4205
4206 if (np->ntyp == N_REAL) { ndp->is_real = TRUE; ndp->has_sign = TRUE; }
4207 if (lhstyp == LHS_DECL)
4208 {
4209 if (np->n_stren) ndp->x_stren = TRUE;
4210 return(__nd_wire(erndp));
4211 }
4212 else return(nd_reg(erndp));
4213 case LSB:
4214 erndp = ndp->lu.x;
4215 syp = erndp->lu.sy;
4216 /* this does not need to be a constant */
4217 /* lhs decl. bit selects must be constants see lrm 5-1, 12-16 (rule 2) */
4218 if (lhstyp == LHS_DECL)
4219 {
4220 /* this must convert to bit index constant (maybe IS form) */
4221 if (!chk_srcbsel(ndp, FALSE)) return(FALSE);
4222 if (!__chk_rhsexpr(ndp->ru.x, 0)) return(FALSE);
4223 chk_inrng_bsel(ndp);
4224 /* even if error, check decl. scalared */
4225 if (!__chk_lhsdecl_scalared(erndp)) return(FALSE);
4226 }
4227 /* procedural lhs can be non constant */
4228 else
4229 {
4230 if (!chk_srcbsel(ndp, FALSE)) return(FALSE);
4231 if (!__chk_rhsexpr(ndp->ru.x, 0)) return(FALSE);
4232 /* here either constant or expr. ok */
4233 if (ndp->ru.x->optyp == NUMBER || ndp->ru.x->optyp == ISNUMBER)
4234 {
4235 /* for procedural number lhs warn if out of range but gets assigned */
4236 if (!chk_inrng_bsel(ndp)) return(FALSE);
4237 }
4238 }
4239 goto chk_id;
4240 case PARTSEL:
4241 syp = ndp->lu.x->lu.sy;
4242 erndp = ndp->lu.x;
4243 if (!chk_srcpsel(ndp, FALSE)) return(FALSE);
4244 if (!__chk_rhsexpr(ndp->ru.x->lu.x, 0)) return(FALSE);
4245 if (!__chk_rhsexpr(ndp->ru.x->ru.x, 0)) return(FALSE);
4246 if (!chk_inrng_psel(ndp)) return(FALSE);
4247 if (lhstyp == LHS_DECL)
4248 {
4249 if (!__chk_lhsdecl_scalared(erndp)) return(FALSE);
4250 }
4251 goto chk_id;
4252 case LCB:
4253 /* DBG remove */
4254 if (!is_top) __misc_terr(__FILE__, __LINE__);
4255 /* --- */
4256 /* notice legal lhs concatenates element width self determined */
4257 {
4258 register struct expr_t *ndp2;
4259 int32 errind, has_stren, i;
4260
4261 errind = TRUE;
4262 has_stren = FALSE;
4263 for (ndp2 = ndp->ru.x, i = 1; ndp2 != NULL; ndp2 = ndp2->ru.x, i++)
4264 {
4265 /* widths get set after checking */
4266 if (!chksyn_lhsexpr(ndp2->lu.x, FALSE, lhstyp)) errind = FALSE;
4267 /* notice, setting lhs st for all components and also top */
4268 /* if has stren know will be wire */
4269 if (ndp2->lu.x->x_stren) { ndp2->x_stren = TRUE; has_stren = TRUE; }
4270 if (ndp2->lu.x->is_real)
4271 {
4272 __sgferr(900,
4273 "real variable illegal in lvalue concatenate (pos. %d)", i);
4274 }
4275 }
4276 if (has_stren) ndp->x_stren = TRUE;
4277 return(errind);
4278 }
4279 case CATREP:
4280 __sgferr(856, "lvalue concatenate repeat form illegal");
4281 break;
4282 /* if empty form already checked to have appeared in legal place */
4283 case OPEMPTY: return(TRUE);
4284 case NUMBER:
4285 /* number is wrong so needs to fall through */
4286 default:
4287 __sgferr(857, "expression %s is illegal lvalue element",
4288 __msgexpr_tostr(__xs, ndp));
4289 }
4290 return(FALSE);
4291 }
4292
4293 /*
4294 * check and unwind lhs concatenates
4295 *
4296 * repeat form concats and numbers illegal on lhs
4297 * when done concatenate is one level and checked
4298 *
4299 * notice this will unwind concatenates in fcall arguments
4300 */
unwind_lhsconcats(struct expr_t * ndp)4301 static void unwind_lhsconcats(struct expr_t *ndp)
4302 {
4303 if (__isleaf(ndp)) return;
4304
4305 /* DBG ---
4306 if (__debug_flg)
4307 __dbg_msg("## unwinding lhs concat %s\n", __msgexpr_tostr(__xs, ndp));
4308 --- */
4309
4310 /* concatenate unwinding must be done bottom up */
4311 if (ndp->lu.x != NULL)
4312 {
4313 /* DBG ---
4314 if (__debug_flg)
4315 __dbg_msg("## left side %s\n", __msgexpr_tostr(__xs, ndp->lu.x));
4316 --- */
4317 unwind_lhsconcats(ndp->lu.x);
4318 /* DBG ---
4319 if (__debug_flg) __dbg_msg("^^ left up.\n");
4320 --- */
4321 }
4322 if (ndp->ru.x != NULL)
4323 {
4324 /* DBG ---
4325 if (__debug_flg)
4326 __dbg_msg("## right side %s\n", __msgexpr_tostr(__xs, ndp->ru.x));
4327 --- */
4328 unwind_lhsconcats(ndp->ru.x);
4329 /* DBG ---
4330 if (__debug_flg) __dbg_msg("^^ right up.\n");
4331 --- */
4332 }
4333
4334 /* node is top of concatenate with all sub concatenates simplified */
4335 if (ndp->optyp == LCB)
4336 {
4337 register struct expr_t *ndp2;
4338 struct expr_t *last_ndp2, *end_ndp;
4339
4340 last_ndp2 = ndp;
4341 for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4342 {
4343 struct expr_t *lop;
4344
4345 lop = ndp2->lu.x;
4346 /* notice ,, form illegal in concatentate */
4347 switch ((byte) lop->optyp) {
4348 /* constants illegal but caught later */
4349 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM:
4350 break;
4351 case LCB:
4352 {
4353 /* nested concatenate - splice up one level */
4354 last_ndp2->ru.x = lop->ru.x;
4355 /* find rightmost element - know always there */
4356 end_ndp = __find_catend(lop);
4357
4358 /* DBG LINT remove -- */
4359 if (end_ndp == NULL) __misc_terr(__FILE__, __LINE__);
4360 /* -- */
4361
4362 /* if rightmost up one node will make null */
4363 end_ndp->ru.x = ndp2->ru.x;
4364 /* end of new chain is new last */
4365 last_ndp2 = end_ndp;
4366 }
4367 continue;
4368 case CATREP:
4369 /* error caught later */
4370 continue;
4371 }
4372 /* NUMBER or other means move last down tree one */
4373 last_ndp2 = ndp2;
4374 }
4375 }
4376 }
4377
4378 /*
4379 * check a declarative lhs bit or part select to make sure scalared
4380 *
4381 * notice wire name on conta lhs does not require scalared vector
4382 * unless bit or part select
4383 *
4384 * if this is a reg (error caught later) surpress this error
4385 */
__chk_lhsdecl_scalared(struct expr_t * idndp)4386 extern int32 __chk_lhsdecl_scalared(struct expr_t *idndp)
4387 {
4388 struct net_t *np;
4389
4390 np = idndp->lu.sy->el.enp;
4391 if (np->ntyp >= NONWIRE_ST) return(TRUE);
4392
4393 /* if no autoexpand, must explicitly declare as scalared or error */
4394 /* if autoexpand (the default), error if explicitly declared vectored */
4395 /* check only possible for non interact - should never happen in interact */
4396 if (np->nrngrep == NX_CT)
4397 {
4398 if ((__no_expand && np->nu.ct->n_spltstate != SPLT_SCAL)
4399 || np->nu.ct->n_spltstate == SPLT_VECT)
4400 {
4401 __sgferr(860, "vectored %s %s illegal in declarative lvalue",
4402 __to_wtnam(__xs, np), __to_idnam(idndp));
4403 return(FALSE);
4404 }
4405 }
4406 return(TRUE);
4407 }
4408
4409 /*
4410 * return T if is a variable - i.e. any SYM_N that is not a parameter
4411 * know object is an id
4412 */
idnd_var(struct sy_t * syp)4413 static int32 idnd_var(struct sy_t *syp)
4414 {
4415 struct net_t *np;
4416
4417 if (syp->sytyp != SYM_N) return(FALSE);
4418 np = syp->el.enp;
4419 if (!np->n_isaparam) return(TRUE);
4420 return(FALSE);
4421 }
4422
4423 /*
4424 * for declarative code, lhs must be a wire
4425 * this catches declarative lhs reals
4426 * needs __sfnam_ind to be set before called
4427 */
__nd_wire(struct expr_t * ndp)4428 extern int32 __nd_wire(struct expr_t *ndp)
4429 {
4430 struct net_t *np;
4431
4432 np = ndp->lu.sy->el.enp;
4433 if (np->ntyp >= NONWIRE_ST)
4434 {
4435 __sgferr(861, "declarative lvalue or port sink %s %s must be a wire",
4436 __to_wtnam(__xs, np), __to_idnam(ndp));
4437 return(FALSE);
4438 }
4439 return(TRUE);
4440 }
4441
4442 /*
4443 * return T if expression contains any register
4444 *
4445 * needed for force/release since if has reg, must be quasi-continuous assign
4446 * reg form else normal lhs
4447 * notice this must handle un converted globals since chk expressions
4448 * routine that replaces the global not yet called at this point
4449 */
__xhas_reg(struct expr_t * ndp)4450 extern int32 __xhas_reg(struct expr_t *ndp)
4451 {
4452 struct net_t *np;
4453
4454 switch ((byte) ndp->optyp) {
4455 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
4456 break;
4457 case ID: case GLBREF:
4458 np = ndp->lu.sy->el.enp;
4459 if (np->ntyp >= NONWIRE_ST) return(TRUE);
4460 break;
4461 default:
4462 if (ndp->lu.x != NULL) if (__xhas_reg(ndp->lu.x)) return(TRUE);
4463 if (ndp->ru.x != NULL) if (__xhas_reg(ndp->ru.x)) return(TRUE);
4464 break;
4465 }
4466 return(FALSE);
4467 }
4468
4469 /*
4470 * for procedural code, lhs must be a reg
4471 * know node is an id
4472 * needs __sfnam_ind to be set before called
4473 */
nd_reg(struct expr_t * ndp)4474 static int32 nd_reg(struct expr_t *ndp)
4475 {
4476 struct net_t *np;
4477
4478 np = ndp->lu.sy->el.enp;
4479 if (np->ntyp < NONWIRE_ST || np->ntyp == N_EVENT)
4480 {
4481 __sgferr(862, "procedural lvalue %s %s is not a reg",
4482 __to_wtnam(__xs, np), __to_idnam(ndp));
4483 return(FALSE);
4484 }
4485 if (np->n_isaparam)
4486 {
4487 __sgferr(863,
4488 "defparam %s use as register variable not supported", __to_idnam(ndp));
4489 return(FALSE);
4490 }
4491 return(TRUE);
4492 }
4493
4494 /*
4495 * compute the lhs width
4496 * know called in only 1 place after global substituted
4497 */
__set_lhswidth(struct expr_t * lhsx)4498 extern void __set_lhswidth(struct expr_t *lhsx)
4499 {
4500 int32 r1, r2, xwid;
4501 struct net_t *np;
4502 struct sy_t *syp;
4503
4504 switch ((byte) lhsx->optyp) {
4505 case ID: case GLBREF:
4506 lhsx->szu.xclen = __get_netwide(lhsx->lu.sy->el.enp);
4507 break;
4508 /* width of empty is 0 that matches anything */
4509 case OPEMPTY: break;
4510 case LSB:
4511 syp = lhsx->lu.x->lu.sy;
4512 lhsx->lu.x->szu.xclen = __get_netwide(syp->el.enp);
4513 /* this is bit select or array index */
4514 np = syp->el.enp;
4515 if (np->n_isarr && np->n_isavec) xwid = __get_netwide(np); else xwid = 1;
4516 lhsx->szu.xclen = xwid;
4517 break;
4518 case PARTSEL:
4519 syp = lhsx->lu.x->lu.sy;
4520 lhsx->lu.x->szu.xclen = __get_netwide(syp->el.enp);
4521 np = syp->el.enp;
4522 /* know these values always fit in 32 bits and never IS form */
4523 r1 = (int32) __contab[lhsx->ru.x->lu.x->ru.xvi];
4524 r2 = (int32) __contab[lhsx->ru.x->ru.x->ru.xvi];
4525 lhsx->szu.xclen = (r1 > r2) ? r1 - r2 + 1 : r2 - r1 + 1;
4526 break;
4527 case LCB:
4528 {
4529 register struct expr_t *ndp2;
4530
4531 /* know lhs concatenates never nested */
4532 for (xwid = 0, ndp2 = lhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4533 {
4534 __set_lhswidth(ndp2->lu.x);
4535 xwid += ndp2->lu.x->szu.xclen;
4536 }
4537 lhsx->szu.xclen = xwid;
4538 /* CAT COM op width is dist from high bit of this to low (right) end */
4539 for (ndp2 = lhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4540 {
4541 ndp2->szu.xclen = xwid;
4542 xwid -= ndp2->lu.x->szu.xclen;
4543 }
4544 if (xwid != 0) __misc_terr(__FILE__, __LINE__);
4545 break;
4546 }
4547 default: __case_terr(__FILE__, __LINE__);
4548 }
4549 }
4550
4551 /*
4552 * check an event expression
4553 * real numbers not allowed in event expressions
4554 */
__chk_evxpr(struct expr_t * ndp)4555 extern void __chk_evxpr(struct expr_t *ndp)
4556 {
4557 struct net_t *np;
4558
4559 switch ((byte) ndp->optyp) {
4560 /* any simple ID good - event versus variable change known from var type */
4561 case ID: case GLBREF:
4562 np = ndp->lu.sy->el.enp;
4563 if (np->ntyp == N_EVENT)
4564 {
4565 ndp->szu.xclen = 1;
4566 if (np->nrngrep == NX_CT) np->nu.ct->n_onrhs = TRUE;
4567 break;
4568 }
4569 /* any wire used in an event control is accessed as on rhs */
4570 if (np->nrngrep == NX_CT) np->nu.ct->n_onrhs = TRUE;
4571 goto chk_expr;
4572 case OPEVOR: case OPEVCOMMAOR:
4573 __chk_evxpr(ndp->lu.x);
4574 __chk_evxpr(ndp->ru.x);
4575 break;
4576 case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM:
4577 /* SJM 05/22/00 - per XL, real ev exprs (non edge) legal - just chg op */
4578 is_num:
4579 __sgfwarn(551, "event expression constant - event cannot occur");
4580 break;
4581 case OPPOSEDGE: case OPNEGEDGE:
4582 chk_edge_expr(ndp);
4583 break;
4584 default:
4585 /* change of any rhs expressions */
4586 chk_expr:
4587 __chk_rhsexpr(ndp, 0);
4588 if (ndp->optyp == NUMBER) goto is_num;
4589 /* SJM 05/22/00 - per XL, real ev exprs (non edge) legal - just chg op */
4590 if (xpr_hasfcall(ndp))
4591 __sgfinform(414, "event expression %s has function call that can have side effects",
4592 __msgexpr_tostr(__xs, ndp));
4593 }
4594 }
4595
4596 /*
4597 * return T if expression has a function call
4598 */
xpr_hasfcall(struct expr_t * ndp)4599 static int32 xpr_hasfcall(struct expr_t *ndp)
4600 {
4601 if (ndp->optyp == FCALL) return(TRUE);
4602 if (__isleaf(ndp)) return(FALSE);
4603 if (ndp->lu.x != NULL) { if (xpr_hasfcall(ndp->lu.x)) return(TRUE); }
4604 if (ndp->ru.x != NULL) { if (xpr_hasfcall(ndp->ru.x)) return(TRUE); }
4605 return(FALSE);
4606 }
4607
4608 /*
4609 * return T if expression has a user function call
4610 * built-in $ starting system functions legal
4611 *
4612 */
xpr_has_nonsys_fcall(struct expr_t * ndp)4613 static int32 xpr_has_nonsys_fcall(struct expr_t *ndp)
4614 {
4615 int32 anum;
4616 struct sy_t *syp;
4617 struct sysfunc_t *syfp;
4618
4619 if (ndp->optyp == FCALL)
4620 {
4621 syp = ndp->lu.x->lu.sy;
4622 if (syp->sytyp != SYM_SF) return(TRUE);
4623
4624 syfp = syp->el.esyftbp;
4625 if (syfp->tftyp != SYSF_BUILTIN) return(TRUE);
4626 anum = __cnt_tfargs(ndp->ru.x);
4627
4628 /* SJM 09/04/01 - must check arg num here since can't fold - also */
4629 /* exec assumes right no. of args without check */
4630 /* only some built-in system functions allowed in const exprs */
4631 switch (syfp->syfnum) {
4632 case STN_ITOR: case STN_BITSTOREAL: case STN_RTOI: case STN_REALTOBITS:
4633 case STN_SIGNED: case STN_UNSIGNED:
4634 case STN_COS: case STN_SIN: case STN_TAN: case STN_ACOS: case STN_ASIN:
4635 case STN_ATAN: case STN_COSH: case STN_SINH: case STN_TANH:
4636 case STN_ATANH: case STN_ACOSH: case STN_ASINH:
4637 case STN_INT: case STN_SGN:
4638 case STN_LN: case STN_LOG10: case STN_ABS: case STN_SQRT: case STN_EXP:
4639 case STN_HSQRT: case STN_HLOG: case STN_HLOG10:
4640 if (anum != 1) { sf_errifn(syp, 1); return(TRUE); }
4641 break;
4642
4643 case STN_POW: case STN_MIN: case STN_MAX:
4644 /* hspice special too */
4645 case STN_HPOW: case STN_HPWR: case STN_HSIGN: case STN_HDB:
4646 case STN_HYPOT: case STN_ATAN2:
4647 if (anum != 2) { sf_errifn(syp, 2); return(TRUE); }
4648 break;
4649 default:
4650 /* illegal built-in system function in constant expression */
4651 return(TRUE);
4652 }
4653 /* fall thru - because must check args */
4654 }
4655 if (__isleaf(ndp)) return(FALSE);
4656
4657 if (ndp->lu.x != NULL) { if (xpr_has_nonsys_fcall(ndp->lu.x)) return(TRUE); }
4658 if (ndp->ru.x != NULL) { if (xpr_has_nonsys_fcall(ndp->ru.x)) return(TRUE); }
4659 return(FALSE);
4660 }
4661
4662 /*
4663 * any expression legal here but warning if wider than 1 bit (use low bit)
4664 * LRM requires using low bit for any wider than 1 bit
4665 *
4666 * allowing any expression including array index - have separate expr
4667 * old value and eval to filter for anything but scalared variable and
4668 * constant bit select of scalared
4669 */
chk_edge_expr(struct expr_t * endp)4670 static void chk_edge_expr(struct expr_t *endp)
4671 {
4672 struct expr_t *ndp;
4673
4674 ndp = endp->lu.x;
4675 /* this will catch any event variable */
4676 __chk_rhsexpr(ndp, 0);
4677 /* SJM 05/22/00 - real edge expressions still illegal */
4678 if (ndp->is_real)
4679 {
4680 __sgferr(864, "edge event control expression %s cannot be real",
4681 __msgexpr_tostr(__xs, endp));
4682 return;
4683 }
4684 if (ndp->szu.xclen != 1)
4685 {
4686 __sgfwarn(677,
4687 "edge control %s expression width %d wider than 1 bit - low bit used",
4688 __msgexpr_tostr(__xs, endp), ndp->szu.xclen);
4689 }
4690 }
4691
4692 /*
4693 * PASS 2 (AFTER ALL SOURCE READ) FUNCTION AND TASK CHECKING ROUTINES
4694 */
4695
4696 /*
4697 * check a task enable statement
4698 */
__chk_tskenable(struct st_t * stp)4699 extern void __chk_tskenable(struct st_t *stp)
4700 {
4701 register struct expr_t *xp;
4702 register struct task_pin_t *tpp;
4703 int32 pwid, pi;
4704 struct task_t *tskp;
4705 struct sy_t *syp;
4706 struct expr_t *tkxp;
4707 struct tskcall_t *tkcp;
4708
4709 tkcp = &(stp->st.stkc);
4710 /* cannot check number of widths (assuming 0 context of system tasks) */
4711 tkxp = tkcp->tsksyx;
4712 if (tkxp->optyp == ID && *(tkxp->lu.sy->synam) == '$')
4713 {
4714 /* system task args do not have type or width - take what is there */
4715 chk_systskenable(stp, tkcp);
4716 return;
4717 }
4718
4719 /* task call symbol missing or not declared as task */
4720 if (tkxp == NULL || (tkxp->optyp != GLBREF && tkxp->optyp != ID)
4721 || (syp = tkxp->lu.sy) == NULL) __misc_sgfterr(__FILE__, __LINE__);
4722
4723 /* if error will be left as global ID */
4724 syp = tkcp->tsksyx->lu.sy;
4725 tskp = syp->el.etskp;
4726 tpp = tskp->tskpins;
4727 pi = 1;
4728 for (xp = tkcp->targs; xp != NULL; xp = xp->ru.x, tpp = tpp->tpnxt, pi++)
4729 {
4730 if (tpp == NULL)
4731 {
4732 __sgferr(871, "task %s enable has more arguments (%d) than declaration",
4733 __to_idnam(tkcp->tsksyx), pi);
4734 return;
4735 }
4736 /* decl. argumen cannot be global - declared symbol */
4737 pwid = __get_netwide(tpp->tpsy->el.enp);
4738 /* but expression is normal either right or left sides */
4739 if (tpp->trtyp == IO_IN)
4740 {
4741 __chk_rhsexpr(xp->lu.x, pwid);
4742
4743 /* SJM 10/08/04 - for Ver 2001 because WBITS can be 64 - must widen */
4744 /* unsized constant (unsiznum bit in expr rec on) to lhs width */
4745 if (xp->lu.x->optyp == NUMBER && xp->lu.x->unsiznum
4746 && xp->lu.x->szu.xclen < pwid)
4747 {
4748 xp->lu.x = __widen_unsiz_rhs_assign(xp->lu.x, pwid);
4749 }
4750 }
4751 else
4752 {
4753 __chk_lhsexpr(xp->lu.x, LHS_PROC);
4754 if (tpp->trtyp == IO_BID) __set_expr_onrhs(xp->lu.x);
4755 }
4756 /* no inform for bit width changes (they are common) */
4757 /* but inform for arg. real and value non real or opposite */
4758 if (tpp->tpsy->el.enp->ntyp == N_REAL && !(xp->lu.x->is_real))
4759 {
4760 __sgfinform(485,
4761 "task %s argument pos. %d declared real - non real expression %s converted",
4762 __to_idnam(tkcp->tsksyx), pi, __msgexpr_tostr(__xs, xp->lu.x));
4763 }
4764 else if (tpp->tpsy->el.enp->ntyp != N_REAL && xp->lu.x->is_real)
4765 {
4766 __sgfinform(485,
4767 "task %s argument pos. %d declared non real - real expression %s converted",
4768 __to_idnam(tkcp->tsksyx), pi, __msgexpr_tostr(__xs, xp->lu.x));
4769 }
4770 }
4771 if (tpp != NULL)
4772 __sgferr(872, "task %s enable has fewer arguments than declaration",
4773 __to_idnam(tkcp->tsksyx));
4774 tskp->t_used = TRUE;
4775 }
4776
4777 /*
4778 * check a system task enable
4779 *
4780 * notice there is no task structure and symbol in special symbol table
4781 * any number with any type argument list just passed on
4782 */
chk_systskenable(struct st_t * stp,struct tskcall_t * tkcp)4783 static void chk_systskenable(struct st_t *stp, struct tskcall_t *tkcp)
4784 {
4785 register struct expr_t *xp;
4786 int32 anum, special_syntax, is_disp_typ, is_monit_typ, nbytes, ii;
4787 struct sy_t *syp;
4788 struct expr_t *tkxp, *sav_xp;
4789 struct systsk_t *stbp;
4790 struct expr_t *ndp;
4791 struct sy_t *tsyp;
4792 byte *monit_argtyps;
4793
4794 tkxp = tkcp->tsksyx;
4795 syp = tkxp->lu.sy;
4796 stbp = syp->el.esytbp;
4797
4798 /* system task number inconsistent */
4799 if (stbp->stsknum == 0) __misc_sgfterr(__FILE__, __LINE__);
4800
4801 special_syntax = FALSE;
4802 /* notice for system tasks no special first arg. return type */
4803 /* assume start checking expressions with 1st arg. */
4804 xp = tkcp->targs;
4805 anum = __cnt_tfargs(tkcp->targs);
4806 is_disp_typ = FALSE;
4807 is_monit_typ = FALSE;
4808 if (anum == 1 && xp->lu.x->optyp == OPEMPTY)
4809 {
4810 __sgfwarn(633,
4811 "system task enable: %s(); has one empty argument - for no arguments omit the ()",
4812 syp->synam);
4813 }
4814
4815 /* dumpvars is special case because xmr's may not resolve to wire */
4816 /* if pli system task supercedes normal, will never see its task number */
4817 switch (stbp->stsknum) {
4818 case STN_FFLUSH:
4819 /* $fflush([optional op]) - op can be missing, then all, [mcd] or [fd] */
4820 if (anum != 0 && anum !=1)
4821 {
4822 __sgferr(851,
4823 "%s system task illegal number of arguments (%d) - 0 or 1 legal",
4824 syp->synam, anum);
4825 }
4826 break;
4827 case STN_SWRITE: case STN_SWRITEB: case STN_SWRITEH: case STN_SWRITEO:
4828 is_disp_typ = TRUE;
4829 if (anum < 2)
4830 {
4831 __sgferr(882,
4832 "%s system task required output reg and one argument missing",
4833 syp->synam);
4834 return;
4835 }
4836 ndp = xp->lu.x;
4837 /* SJM 05/17/04 - LOOKATME this can be any width string - why 32? */
4838 __chk_lhsexpr(ndp, 32);
4839 /* move to 2nd argument */
4840 xp = xp->ru.x;
4841 break;
4842 case STN_SFORMAT:
4843 is_disp_typ = TRUE;
4844 if (anum < 2)
4845 {
4846 __sgferr(882,
4847 "%s system task required output reg and format argument(s) missing",
4848 syp->synam);
4849 special_syntax = TRUE;
4850 break;
4851 }
4852 ndp = xp->lu.x;
4853 /* width self determined for lhs string written into */
4854 __chk_lhsexpr(ndp, 0);
4855 /* move to 2nd format argument */
4856 xp = xp->ru.x;
4857 /* again width self determined */
4858 __chk_rhsexpr(xp->lu.x, 0);
4859
4860 /* if format arg is literal string - can check format */
4861 if (xp->lu.x->is_string) is_disp_typ = TRUE;
4862 else special_syntax = TRUE;
4863
4864 xp = xp->ru.x;
4865 /* if variable fmt, can only check the rhs fmt args */
4866 if (special_syntax)
4867 {
4868 for (sav_xp = xp; xp != NULL; xp = xp->ru.x)
4869 {
4870 __chk_rhsexpr(xp->lu.x, 0);
4871 }
4872 }
4873 break;
4874 /* task requires special argument processing */
4875 case STN_DUMPVARS:
4876 chkst_dumpvars_enable(tkcp, anum);
4877
4878 /* SJM 01/27/03 - error if compiled sim and try to call dumpvars */
4879 /* from interactive mode because need source preprocessing */
4880 if (__iact_state && __optimized_sim)
4881 {
4882 __sgferr(876,
4883 "%s system task call from interactive debugger illegal - move to module ssource or run without -O",
4884 syp->synam);
4885 /* error will inhibit interactive execution but need rest of checking */
4886 }
4887 special_syntax = TRUE;
4888 break;
4889 case STN_READMEMB: case STN_READMEMH:
4890 chkst_readmem(syp, anum, tkcp);
4891 special_syntax = TRUE;
4892 break;
4893 case STN_SREADMEMB: case STN_SREADMEMH:
4894 chkst_sreadmem(syp, anum, tkcp);
4895 special_syntax = TRUE;
4896 break;
4897 case STN_TIMEFORMAT:
4898 /* set how %t displayed and sets interactive time unit interpretation */
4899 /* (units, precision, suffix, minimum width) */
4900 if (anum < 1 || anum > 4) st_errif_rng(syp, 1, 4, anum);
4901 if (!__des_has_timescales)
4902 {
4903 __sgfwarn(626,
4904 "%s system task ignored - design does not use timescales", syp->synam);
4905 }
4906 /* args are just string or numeric expressions - from interp. in Ver */
4907 break;
4908 case STN_PRINTTIMESCALE:
4909 /* this takes hierarchical xmr as name */
4910 if (anum > 1) st_errif_rng(syp, 0, 1, anum);
4911 /* 0 args - means use $scope() set module */
4912 if (anum == 1)
4913 {
4914 /* notice must not check as rhs expr since requires variables */
4915 ndp = xp->lu.x;
4916 /* this must always be xmr - already resolved */
4917 if (ndp->optyp != GLBREF || (ndp->lu.sy->sytyp != SYM_I
4918 && ndp->lu.sy->sytyp != SYM_M))
4919 {
4920 __sgferr(876,
4921 "%s system task argument %s is not required module instance reference",
4922 syp->synam, __msgexpr_tostr(__xs, ndp));
4923 }
4924 special_syntax = TRUE;
4925 }
4926 break;
4927 case STN_SCOPE:
4928 /* list can have 0 arguments but scope must have exactly one */
4929 if (anum != 1) { st_errifn(syp, 1, anum); break; }
4930 goto args_ok;
4931 case STN_LIST:
4932 /* this takes hierarchical xmr as name */
4933 if (anum > 1) st_errif_rng(syp, 0, 1, anum);
4934 /* no argument means use current scope for list */
4935 if (anum == 0) break;
4936 args_ok:
4937 ndp = xp->lu.x;
4938 /* any 1 component scope reference will still be global here */
4939 if (ndp->optyp != GLBREF)
4940 {
4941 if (ndp->optyp != ID) goto bad_scope;
4942 tsyp = ndp->lu.sy;
4943 /* local task/func/lb scope is legal - will not be seen as global */
4944 if (tsyp->sytyp == SYM_F || tsyp->sytyp == SYM_LB
4945 || tsyp->sytyp == SYM_TSK) { special_syntax = TRUE; break; }
4946 goto bad_scope;
4947 }
4948 else tsyp = ndp->lu.sy;
4949 /* know this is global - maybe 1 component */
4950 /* need error if try to $scope into udp or built in primitive */
4951 if (tsyp->sytyp == SYM_UDP || tsyp->sytyp == SYM_PRIM)
4952 {
4953 __sgferr(880, "%s system task argument %s %s illegal", syp->synam,
4954 __to_sytyp(__xs, syp->sytyp), syp->synam);
4955 special_syntax = TRUE;
4956 break;
4957 }
4958 /* only scope required here */
4959 if (!__is_scope_sym(tsyp))
4960 {
4961 bad_scope:
4962 __sgferr(881,
4963 "%s system task argument %s is not required scope identifier",
4964 syp->synam, __msgexpr_tostr(__xs, ndp));
4965 }
4966 special_syntax = TRUE;
4967 break;
4968 case STN_SHOWVARIABLES:
4969 /* for now just treating same as showvars - ignoring control argument */
4970 if (anum < 1)
4971 {
4972 __sgferr(883, "%s system task required first control argument missing",
4973 syp->synam);
4974 break;
4975 }
4976 /* move to 2nd argument */
4977 xp = xp->ru.x;
4978 /*FALLTHRU */
4979 case STN_SHOWVARS:
4980 /* any number of args ok - but can be var,glb,bsel or psel only */
4981 for (; xp != NULL; xp = xp->ru.x)
4982 {
4983 ndp = xp->lu.x;
4984 __chk_rhsexpr(ndp, 0);
4985 switch ((byte) ndp->optyp) {
4986 case ID: case GLBREF: case LSB: case PARTSEL: break;
4987 default:
4988 __sgferr(917,
4989 "%s system task argument %s: variable, global or select required",
4990 syp->synam, __msgexpr_tostr(__xs, ndp));
4991 }
4992 }
4993 special_syntax = TRUE;
4994 break;
4995 /* tasks that cannot have any arguments */
4996 case STN_MONITORON: case STN_MONITOROFF: case STN_DUMPON: case STN_DUMPOFF:
4997 case STN_DUMPALL: case STN_DUMPFLUSH:
4998 case STN_NOKEY: case STN_NOLOG: case STN_CLEARTRACE:
4999 case STN_SHOWALLINSTANCES: case STN_SETTRACE: case STN_SHOWEXPANDEDNETS:
5000 case STN_HISTORY: case STN_MEMUSE: case STN_FLUSHLOG:
5001 case STN_SETEVTRACE: case STN_CLEAREVTRACE:
5002 case STN_SETDEBUG: case STN_CLEARDEBUG:
5003 case STN_RESET:
5004 if (anum > 3) st_errif_rng(syp, 0, 3, anum);
5005 /* any arguments just evaluated for 32 bit values - sign bit may have */
5006 /* significance */
5007 break;
5008
5009 /* tasks that can have 0 or 1 arguments */
5010 /* notice these can appear in source - since just change files */
5011 case STN_KEY: case STN_LOG: case STN_INPUT:
5012 case STN_FINISH: case STN_STOP: case STN_SHOWSCOPES:
5013 case STN_SNAPSHOT: case STN_TRACEFILE: case STN_SYSTEM:
5014 case STN_DUMPFILE:
5015 if (anum > 1) st_errif_rng(syp, 0, 1, anum);
5016 break;
5017 /* tasks that require exactly 1 expr. type arg. (file name?) */
5018 case STN_DUMPLIMIT: case STN_SAVE: case STN_RESTART: case STN_INCSAVE:
5019 case STN_FCLOSE:
5020 if (anum != 1) st_errifn(syp, 1, anum);
5021 break;
5022 /* tasks that take a multichannel descriptor followed by anything */
5023 case STN_FMONITOR: case STN_FMONITORB: case STN_FMONITORH:
5024 case STN_FMONITORO:
5025 is_monit_typ = TRUE;
5026 /*FALLTHRU*/
5027 case STN_FDISPLAY: case STN_FDISPLAYB: case STN_FDISPLAYH:
5028 case STN_FDISPLAYO:
5029 case STN_FWRITE: case STN_FWRITEB: case STN_FWRITEH: case STN_FWRITEO:
5030 case STN_FSTROBE: case STN_FSTROBEB: case STN_FSTROBEH: case STN_FSTROBEO:
5031 is_disp_typ = TRUE;
5032 if (anum < 1)
5033 {
5034 __sgferr(882,
5035 "%s system task required file descriptor or MCD first argument missing",
5036 syp->synam);
5037 return;
5038 }
5039 ndp = xp->lu.x;
5040 __chk_rhsexpr(ndp, 32);
5041 if (ndp->szu.xclen != 32)
5042 {
5043 __sgfwarn(612,
5044 "file descriptor or MCD first argument has size %d should be 32",
5045 ndp->szu.xclen);
5046 }
5047 /* move to 2nd argument */
5048 xp = xp->ru.x;
5049 break;
5050 /* tasks that take any number of numeric arguments - checked later */
5051 case STN_SUPWARNS:
5052 case STN_ALLOWWARNS:
5053 /* could check constant arguments here */
5054 break;
5055 /* task that take any number of unchecked arguments */
5056 case STN_MONITOR: case STN_MONITORB: case STN_MONITORH: case STN_MONITORO:
5057 is_monit_typ = TRUE;
5058 /*FALLTHRU*/
5059 case STN_DISPLAY: case STN_DISPLAYB: case STN_DISPLAYH: case STN_DISPLAYO:
5060 case STN_WRITE: case STN_WRITEB: case STN_WRITEH: case STN_WRITEO:
5061 case STN_STROBE: case STN_STROBEB: case STN_STROBEH: case STN_STROBEO:
5062 is_disp_typ = TRUE;
5063 break;
5064 /* any number of reg/wire variables */
5065 /* all have four required arguments, last inout */
5066 case STN_Q_ADD:
5067 case STN_Q_INITIALIZE:
5068 /* LOOKATME - LRM says 4th arg. is required - but now old Gateway doc. */
5069 /* but maybe operator empty is arg (i.e. , required? */
5070 if (anum != 4) st_errifn(syp, 4, anum);
5071 /* first arg. is input int32 identifying the Q */
5072 if (anum >= 1) __chk_rhsexpr(xp->lu.x, 0);
5073 /* 2nd arg. is q_type for initialize and job_id (user num.) for add */
5074 if (anum >= 2) { xp = xp->ru.x; __chk_rhsexpr(xp->lu.x, 0); }
5075 /* 3rd arg is max q len for initialize and 2nd user num for add */
5076 if (anum >= 3) { xp = xp->ru.x; __chk_rhsexpr(xp->lu.x, 0); }
5077 /* 4th arg is output operation status value */
5078 if (anum >= 4) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5079 special_syntax = TRUE;
5080 break;
5081 case STN_Q_REMOVE:
5082 if (anum != 4) st_errifn(syp, 4, anum);
5083 /* first arg. is input int32 identifying the Q */
5084 if (anum >= 1) __chk_rhsexpr(xp->lu.x, 0);
5085 /* 2nd arg. is output job_id (user num. put in by add call) */
5086 if (anum >= 2) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5087 /* 3rd arg. is output inform_id (2nd user num. put in by add call) */
5088 if (anum >= 3) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5089 /* 4th arg is output operation status (completion value) value */
5090 if (anum >= 4) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5091 special_syntax = TRUE;
5092 break;
5093 case STN_Q_EXAM:
5094 if (anum != 4) st_errifn(syp, 4, anum);
5095 /* first arg. is input int32 identifying the Q */
5096 if (anum >= 1) __chk_rhsexpr(xp->lu.x, 0);
5097 /* 2nd arg. is input q_stat_code that selects information to return */
5098 if (anum >= 2) { xp = xp->ru.x; __chk_rhsexpr(xp->lu.x, 0); }
5099 /* 3rd arg. is output status value */
5100 if (anum >= 3) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5101 /* 4th arg is output operation status (completion code) value */
5102 if (anum >= 4) { xp = xp->ru.x; __chk_lhsexpr(xp->lu.x, LHS_PROC); }
5103 special_syntax = TRUE;
5104 break;
5105 case STN_SDF_ANNOTATE:
5106 chkst_sdfannotate_enable(tkcp, anum);
5107 special_syntax = TRUE;
5108 break;
5109
5110 case STN_GRREMOTE:
5111 case STN_PSWAVES:
5112 case STN_GRSYNCHON:
5113 case STN_GRREGS:
5114 case STN_GRWAVES:
5115 case STN_FREEZEWAVES:
5116 case STN_DEFINEGROUPWAVES:
5117 __sgfwarn(553,
5118 "group waves task %s not supported- executed as null statement",
5119 syp->synam);
5120 return;
5121
5122 default:
5123 /* check pli tf user task enable and build tf rec */
5124 if (stbp->stsknum >= BASE_VERIUSERTFS
5125 && (int32) stbp->stsknum <= __last_systf)
5126 {
5127 /* tf_ checktf called during prep after aux record built */
5128 /* for both tf_ and vpi_ systf */
5129 chkbld_pli_task(stp, (int32) stbp->stsknum);
5130 return;
5131 }
5132 }
5133 if (special_syntax) return;
5134
5135 /* fall through to normal anything legal - notice 0 (none) expr. context */
5136 for (sav_xp = xp; xp != NULL; xp = xp->ru.x)
5137 {
5138 ndp = xp->lu.x;
5139 __chk_rhsexpr(ndp, 0);
5140 /* if special syntax called if needed in that routine */
5141 /* width in bytes where bit sizes rounded up to next word32 */
5142 /* SJM 07/24/00 - no nu.ct when elaborated from iact state */
5143 if (is_monit_typ && !__iact_state)
5144 {
5145 mark_monit_in_src_nets(ndp);
5146 }
5147 }
5148 if (is_monit_typ)
5149 {
5150 /* must allocate 1 byte even if no args */
5151 nbytes = (anum != 0) ? anum : 1;
5152 /* monit type implies display type */
5153 monit_argtyps = (byte *) __my_malloc(nbytes);
5154 memset(monit_argtyps, 0, nbytes);
5155 __chk_fmt(sav_xp, monit_argtyps);
5156 /* will never get here for PLI task func that shares trec field */
5157 if (tkcp->tkcaux.mauxp == NULL)
5158 {
5159 tkcp->tkcaux.mauxp = (struct monaux_t *)
5160 __my_malloc(sizeof(struct monaux_t));
5161 tkcp->tkcaux.mauxp->dces_blt = FALSE;
5162 tkcp->tkcaux.mauxp->argisvtab = NULL;
5163 tkcp->tkcaux.mauxp->mon_dcehdr = (struct dceauxlst_t **)
5164 __my_malloc(__inst_mod->flatinum*sizeof(struct dceauxlst_t *));
5165 for (ii = 0; ii < __inst_mod->flatinum; ii++)
5166 tkcp->tkcaux.mauxp->mon_dcehdr[ii] = NULL;
5167 }
5168 tkcp->tkcaux.mauxp->argisvtab = monit_argtyps;
5169 return;
5170 }
5171 if (is_disp_typ) __chk_fmt(sav_xp, (byte *) NULL);
5172 }
5173
5174 /*
5175 * for optimizer, mark monit arg nets as having monit in src
5176 *
5177 * BEWARE - must not call this during iact elaboration but called
5178 * even for interpreter now
5179 */
mark_monit_in_src_nets(struct expr_t * xp)5180 static void mark_monit_in_src_nets(struct expr_t *xp)
5181 {
5182 struct net_t *np;
5183
5184 if (__isleaf(xp))
5185 {
5186 /* SJM 03/22/02 - XMR monits in source must also be marked */
5187 if ((xp->optyp == ID || xp->optyp == GLBREF) && xp->lu.sy->sytyp == SYM_N)
5188 {
5189 np = xp->lu.sy->el.enp;
5190 if (!np->n_isaparam) np->nu.ct->monit_in_src = TRUE;
5191 }
5192 return;
5193 }
5194 if (xp->lu.x != NULL) mark_monit_in_src_nets(xp->lu.x);
5195 if (xp->ru.x != NULL) mark_monit_in_src_nets(xp->ru.x);
5196 }
5197
5198 /*
5199 * return T if symbol can be scope
5200 */
__is_scope_sym(struct sy_t * syp)5201 extern int32 __is_scope_sym(struct sy_t *syp)
5202 {
5203 switch ((byte) syp->sytyp) {
5204 case SYM_I: case SYM_M: case SYM_LB: case SYM_TSK: case SYM_F: return(TRUE);
5205 }
5206 return(FALSE);
5207 }
5208
5209 /*
5210 * check and build vpi_ tf rec for pli task
5211 */
chkbld_pli_task(struct st_t * stp,int32 tfnum)5212 static void chkbld_pli_task(struct st_t *stp, int32 tfnum)
5213 {
5214 int32 anum;
5215 struct tskcall_t *tkcp;
5216 struct tfrec_t *tfrp;
5217
5218 tkcp = &(stp->st.stkc);
5219 /* this sets tf_rw flags for args */
5220 if (tkcp->targs != NULL)
5221 { chk_pli_arglist(tkcp->targs, tfnum); anum = __cnt_tfargs(tkcp->targs); }
5222 else anum = 0;
5223
5224 /* need separate routine for vpi_ systfs compiletf and checking */
5225 if (tfnum > __last_veriusertf)
5226 {
5227 __chkbld_vpi_systf_task(stp);
5228 return;
5229 }
5230
5231 /* allocate the tf rec and link on to func. name expr unused len fld */
5232 tfrp = chkalloc_tfrec(tkcp->targs, anum);
5233 tfrp->tf_func = FALSE;
5234 /* link together both directions */
5235 tfrp->tfu.tfstp = stp;
5236 tkcp->tkcaux.trec = tfrp;
5237
5238 if (__tfrec_hdr == NULL) __tfrec_hdr = __tfrec_end = tfrp;
5239 else { __tfrec_end->tfrnxt = tfrp; __tfrec_end = tfrp; }
5240 }
5241
5242 /*
5243 * system task number of arguments outside of legal range error
5244 */
st_errif_rng(struct sy_t * syp,int32 expl,int32 exph,int32 anum)5245 static void st_errif_rng(struct sy_t *syp, int32 expl, int32 exph, int32 anum)
5246 {
5247 __sgferr(884, "%s system task must have from %d to %d arguments - has %d",
5248 syp->synam, expl, exph, anum);
5249 }
5250
5251 /*
5252 * system task number of arguments not required number
5253 */
st_errifn(struct sy_t * syp,int32 expn,int32 anum)5254 static void st_errifn(struct sy_t *syp, int32 expn, int32 anum)
5255 {
5256 if (expn == 0)
5257 __sgferr(885, "%s system task cannot have any arguments - has %d",
5258 syp->synam, anum);
5259 else __sgferr(886, "%s system task %d argument(s) required - has %d",
5260 syp->synam, expn, anum);
5261 }
5262
5263 /*
5264 * check the $dumpvars system task enable - needs special processing
5265 * 1st arg. if present must be num. rhs expr. and rest must be vars.
5266 * does the following:
5267 * 1. make sure 1st expr. evaluates to rhs value
5268 * 2. must be simple scope or wire
5269 * case of wire and top mod. conflicts handled in global substitution
5270 *
5271 * SJM 07/15/00 - now 3. mark all all mod and one net dumpvars in src
5272 */
chkst_dumpvars_enable(struct tskcall_t * tkcp,int32 anum)5273 static void chkst_dumpvars_enable(struct tskcall_t *tkcp, int32 anum)
5274 {
5275 register struct expr_t *alxp;
5276 int32 levels;
5277 word32 *wp;
5278 double *dp;
5279 struct expr_t *dpthndp, *xp;
5280 struct gref_t *grp;
5281 struct net_t *np;
5282 struct sy_t *syp;
5283 struct mod_t *mdp;
5284
5285 alxp = tkcp->targs;
5286 /* special case of dump all variables in design */
5287 if (anum == 0)
5288 {
5289 /* SJM 07/15/00 - dumpvars with no args is dumpv all in src */
5290 __dv_allform_insrc = TRUE;
5291 /* must adjust so all net stores use chg form to trigger dumpvaring */
5292 if (__iact_state) set_iact_dmpv_all_nd_nchgstore();
5293 return;
5294 }
5295
5296 dpthndp = alxp->lu.x;
5297 __chk_rhsexpr(dpthndp, 0);
5298 if (dpthndp->optyp == OPEMPTY)
5299 __sgferr(918, "$dumpvars first argument () or (, empty form illegal");
5300
5301 /* SJM 08/08/03 - was not handling first level argument right */
5302 /* also must be constant expression or can't mark underneath levels */
5303 /* argument list form, know first is level */
5304 /* must be number by here since will be folded if possible */
5305
5306 /* NOTICE - works for -O vm gen even for non numeric expr since */
5307 /* just causes dmpv change forms to be emitted for all under */
5308 if (dpthndp->optyp == NUMBER)
5309 {
5310 wp = &(__contab[dpthndp->ru.xvi]);
5311 if (!vval_is0_(wp, dpthndp->szu.xclen)) goto non_const_expr;
5312 levels = (int32) wp[0];
5313 }
5314 else if (dpthndp->optyp == REALNUM)
5315 {
5316 dp = (double *) __contab[dpthndp->ru.xvi];
5317 levels = (int32) *dp;
5318 if (levels < 0.0) goto non_const_expr;
5319 }
5320 else
5321 {
5322 non_const_expr:
5323 /* if non constant expr set levels to 0 and do all underneath */
5324 levels = 0;
5325 }
5326
5327 for (alxp = alxp->ru.x; alxp != NULL; alxp = alxp->ru.x)
5328 {
5329 /* case 1 - identifier - must be wire */
5330 xp = alxp->lu.x;
5331 switch ((byte) xp->optyp) {
5332 case ID:
5333 np = xp->lu.sy->el.enp;
5334 if (np->n_isarr)
5335 {
5336 is_arr:
5337 __sgfwarn(541,
5338 "$dumpvars argument variable %s cannot be array - ignored",
5339 __to_idnam(xp));
5340 break;
5341 }
5342 np->nu.ct->dmpv_in_src = TRUE;
5343
5344 /* SJM 08/08/03 - for dumpvars sys task called from iact code */
5345 /* must set nd chg store form because only this net changed */
5346 if (__iact_state)
5347 {
5348 np->dmpv_in_src = TRUE;
5349 np->nchg_nd_chgstore = TRUE;
5350 }
5351 break;
5352 case GLBREF:
5353 grp = xp->ru.grp;
5354 syp = grp->targsyp;
5355 if (syp->sytyp == SYM_N)
5356 {
5357 np = syp->el.enp;
5358 if (np->n_isarr) goto is_arr;
5359 np->nu.ct->dmpv_in_src = TRUE;
5360
5361 /* SJM 08/08/03 - for dumpvars sys task called from iact code */
5362 /* must set nd chg store form because only this net changed */
5363 if (__iact_state)
5364 {
5365 np->dmpv_in_src = TRUE;
5366 np->nchg_nd_chgstore = TRUE;
5367 }
5368 break;
5369 }
5370 /* also cannot be udp or primitive - have no vars */
5371 /* here module is for top level modules (inst. name the same here) */
5372 if (syp->sytyp != SYM_I && syp->sytyp != SYM_M)
5373 {
5374 __sgferr(887,
5375 "$dumpvars scope form argument %s %s illegal - instance required",
5376 __to_sytyp(__xs, syp->sytyp), syp->synam);
5377 goto make_op_err;
5378 }
5379 /* distance under 1 is nothing under and 0 and is all under */
5380 /* SJM 08/08/03 - notice must mark wires for all insts of mod */
5381 /* even though only some under depending on where $dumpvars is */
5382 /* called from during sim */
5383 if (syp->sytyp == SYM_I) mdp = syp->el.eip->imsym->el.emdp;
5384 else mdp = syp->el.emdp;
5385
5386 if (levels == 1)
5387 {
5388 if (!mdp->mod_dvars_in_src)
5389 {
5390 mdp->mod_dvars_in_src = TRUE;
5391 /* can't be called from iact if vm compiler on */
5392 if (__iact_state) set_iact_dmpvmod_nd_nchgstore(mdp);
5393 }
5394 }
5395 else mark_mod_dvars_under(mdp, levels);
5396 break;
5397 case OPEMPTY:
5398 __sgferr(889, "$dumpvars argument cannot be empty (,,) form");
5399 goto make_op_err;
5400 default:
5401 __sgferr(888, "$dumpvars argument %s must be variable or scope path",
5402 __msgexpr_tostr(__xs, xp));
5403 make_op_err:
5404 __set_xtab_errval();
5405 __bld_xtree(0);
5406 alxp->lu.x = __root_ndp;
5407 }
5408 /* notice by here, if parameter will be substituted to number */
5409 }
5410 }
5411
5412 /*
5413 * mark all module instances up to level under as dumpvars
5414 * levels of 0 implies all
5415 */
mark_mod_dvars_under(struct mod_t * mdp,int32 levels)5416 static void mark_mod_dvars_under(struct mod_t *mdp, int32 levels)
5417 {
5418 register int32 ii;
5419 register struct inst_t *down_ip;
5420 if (!mdp->mod_dvars_in_src)
5421 {
5422 mdp->mod_dvars_in_src = TRUE;
5423 /* SJM 08/08/03 - must turn on assign chg processing for nets in mod */
5424 if (__iact_state) set_iact_dmpvmod_nd_nchgstore(mdp);
5425 }
5426 if (levels == 1) return;
5427
5428 for (ii = 0; ii < mdp->minum; ii++)
5429 {
5430 down_ip = &(mdp->minsts[ii]);
5431 mark_mod_dvars_under(down_ip->imsym->el.emdp,
5432 (levels != 0) ? levels - 1 : 0);
5433 }
5434 }
5435
5436
5437 /*
5438 * for all dumpvars from called from interactive need to turn on all
5439 * nd chg store bits in all modules or else dumpvars records will not happen
5440 *
5441 * SJM 08/08/03 - this fixes bug that caused iact dumpvars not to work
5442 */
set_iact_dmpv_all_nd_nchgstore(void)5443 static void set_iact_dmpv_all_nd_nchgstore(void)
5444 {
5445 register struct mod_t *mdp;
5446
5447 for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5448 {
5449 set_iact_dmpvmod_nd_nchgstore(mdp);
5450 }
5451 }
5452
5453 /*
5454 * set all nchg need chg store bits if dumpvars called from interactive
5455 * with module form
5456 *
5457 * this is same as nd nchg nchg nd chgstore adjustment when iact dces added
5458 * but the nchgaction bits will be set up right when iact dumpv stsk execed
5459 *
5460 * SJM - 08/08/03 - this is needed to make dumpvars from interactive code work
5461 * LOOKATME - maybe should not allow $dumpvars calls from iact mode
5462 */
set_iact_dmpvmod_nd_nchgstore(struct mod_t * mdp)5463 static void set_iact_dmpvmod_nd_nchgstore(struct mod_t *mdp)
5464 {
5465 register int32 ni;
5466 register struct net_t *np;
5467 register struct task_t *tskp;
5468
5469 for (ni = 0, np = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, np++)
5470 {
5471 /* can never dumpvar arrays */
5472 if (!np->n_isarr)
5473 {
5474 np->dmpv_in_src = TRUE;
5475 np->nchg_nd_chgstore = TRUE;
5476 }
5477 }
5478 for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
5479 {
5480 for (ni = 0, np = &(tskp->tsk_regs[0]); ni < tskp->trnum; ni++, np++)
5481 {
5482 if (!np->n_isarr)
5483 {
5484 np->dmpv_in_src = TRUE;
5485 np->nchg_nd_chgstore = TRUE;
5486 }
5487 }
5488 }
5489 }
5490
5491 /*
5492 * check $readmemb or $readmemh arguments
5493 */
chkst_readmem(struct sy_t * syp,int32 anum,struct tskcall_t * tkcp)5494 static void chkst_readmem(struct sy_t *syp, int32 anum,
5495 struct tskcall_t *tkcp)
5496 {
5497 struct expr_t *alxp, *ndp;
5498
5499 /* allow any expr that evaluates to string (i.e. treated as string) here */
5500 if (anum > 4 || anum < 2)
5501 {
5502 __sgferr(884,
5503 "%s system task has %d arguments not from 2 to 4", syp->synam, anum);
5504 /* leave since correct number will not be needed */
5505 return;
5506 }
5507 alxp = tkcp->targs;
5508 ndp = alxp->lu.x;
5509 __chk_rhsexpr(ndp, 0);
5510
5511 alxp = alxp->ru.x;
5512 ndp = alxp->lu.x;
5513 if (!nd_unind_arr(ndp))
5514 {
5515 __sgferr(891,
5516 "%s system task second argument %s must be an unindexed memory name",
5517 syp->synam, __msgexpr_tostr(__xs, ndp));
5518 return;
5519 }
5520 if (anum > 2) { alxp = alxp->ru.x; __chk_rhsexpr(alxp->lu.x, 0); }
5521 if (anum > 3) { alxp = alxp->ru.x; __chk_rhsexpr(alxp->lu.x, 0); }
5522 }
5523
5524 /*
5525 * return if expression is an unindexed array
5526 */
nd_unind_arr(struct expr_t * ndp)5527 static int32 nd_unind_arr(struct expr_t *ndp)
5528 {
5529 struct net_t *np;
5530
5531 if (ndp->optyp != ID && ndp->optyp != GLBREF) return(FALSE);
5532 np = ndp->lu.sy->el.enp;
5533 /* notice (s)readmem assigns to memory so it is lhs indirectly here */
5534 if (np->nrngrep == NX_CT) np->nu.ct->n_onlhs = TRUE;
5535 if (np->ntyp < NONWIRE_ST || np->ntyp == N_EVENT) return(FALSE);
5536 if (!np->n_isarr) return(FALSE);
5537 return(TRUE);
5538 }
5539
5540 /*
5541 * check $sreadmemb or $sreadmemh arguments
5542 */
chkst_sreadmem(struct sy_t * syp,int32 anum,struct tskcall_t * tkcp)5543 static void chkst_sreadmem(struct sy_t *syp, int32 anum,
5544 struct tskcall_t *tkcp)
5545 {
5546 register struct expr_t *alxp;
5547
5548 if (anum < 4)
5549 {
5550 __sgferr(884, "%s system task has %d arguments but at least 4 required",
5551 syp->synam, anum);
5552 /* leave since correct number will not be needed */
5553 return;
5554 }
5555 alxp = tkcp->targs;
5556 if (!nd_unind_arr(alxp->lu.x))
5557 {
5558 __sgferr(895,
5559 "%s system task first argument %s must be an unindexed memory name",
5560 syp->synam, __msgexpr_tostr(__xs, alxp->lu.x));
5561 return;
5562 }
5563 alxp = alxp->ru.x;
5564 __chk_rhsexpr(alxp->lu.x, 0);
5565 alxp = alxp->ru.x;
5566 __chk_rhsexpr(alxp->lu.x, 0);
5567 /* all remaiing only needs to eval (forced) to string need not be literal */
5568 for (alxp = alxp->ru.x; alxp != NULL; alxp = alxp->ru.x)
5569 __chk_rhsexpr(alxp->lu.x, 0);
5570 }
5571
5572 /*
5573 * check $sdf_annotate system tsk arguments
5574 */
chkst_sdfannotate_enable(struct tskcall_t * tkcp,int32 anum)5575 static void chkst_sdfannotate_enable(struct tskcall_t *tkcp, int32 anum)
5576 {
5577 register struct expr_t *alxp;
5578 register int32 argi;
5579 struct expr_t *ndp;
5580
5581 if (anum < 1 || anum > 7)
5582 {
5583 __sgferr(884,
5584 "$sdf_annotate system task must have from 1 to 7 arguments - has %d",
5585 anum);
5586 return;
5587 }
5588 alxp = tkcp->targs;
5589
5590 ndp = alxp->lu.x;
5591 /* allowing string expressions following other places in language */
5592 __chk_rhsexpr(ndp, 0);
5593 if (ndp->optyp == OPEMPTY)
5594 {
5595 __sgferr(918,
5596 "$sdf_annotate required first file name argument empty (, form illegal");
5597 return;
5598 }
5599 if (__iact_state)
5600 {
5601 __ia_err(1495,
5602 "$sdf_annotate system task call illegal as interactive command - must be added to source");
5603 return;
5604 }
5605 __has_sdfann_calls = TRUE;
5606 /* only first file name arg required */
5607 if (anum <= 1) return;
5608
5609 /* this must always be xmr instance scope reference - already resolved */
5610 alxp = alxp->ru.x;
5611 ndp = alxp->lu.x;
5612 /* because this must be scope - can not use chk rhs expr for this arg */
5613 /* scope reference can be empty ,, form */
5614 if (ndp->optyp != OPEMPTY)
5615 {
5616 if (ndp->optyp != GLBREF || (ndp->lu.sy->sytyp != SYM_I
5617 && ndp->lu.sy->sytyp != SYM_M))
5618 {
5619 __sgferr(876,
5620 "$sdf_annotate second argument %s illegal - must be module instance scope",
5621 __msgexpr_tostr(__xs, ndp));
5622 return;
5623 }
5624 }
5625 for (alxp = alxp->ru.x, argi = 3; alxp != NULL; alxp = alxp->ru.x, argi++)
5626 {
5627 ndp = alxp->lu.x;
5628 __chk_rhsexpr(ndp, 0);
5629 if (ndp->optyp == OPEMPTY) continue;
5630
5631 switch (argi) {
5632 case 3:
5633 __sgfwarn(664,
5634 "$sdf_annotate third config_file argument %s ignored - not in SDF standard",
5635 __msgexpr_tostr(__xs, ndp));
5636 break;
5637 /* SJM 07/08/01 - now supporting separate SDF log file */
5638 case 4: break;
5639 /* MTM to over-ride command line option supported */
5640 case 5: break;
5641 case 6:
5642 __sgfwarn(664,
5643 "$sdf_annotate sixth scale factors argument %s ignored - not in SDF standard",
5644 __msgexpr_tostr(__xs, ndp));
5645 break;
5646 case 7:
5647 __sgfwarn(664,
5648 "$sdf_annotate seventh scale type argument %s ignored - not in SDF standard",
5649 __msgexpr_tostr(__xs, ndp));
5650 break;
5651 default: __case_terr(__FILE__, __LINE__);
5652 }
5653 }
5654 }
5655
5656 /*
5657 * ROUTINES TO FIX UP AND CHECK SPECIFY SECTION
5658 */
5659
5660 /*
5661 * check specparams
5662 */
__chkfix_spfy(void)5663 extern void __chkfix_spfy(void)
5664 {
5665 register struct spcpth_t *pthp;
5666 register struct tchk_t *tcp;
5667 int32 spec_empty, saveobj;
5668 struct spfy_t *spfp;
5669 struct tchk_t *suptcp, *rectcp;
5670
5671 saveobj = __cur_declobj;
5672 __cur_declobj = SPECIFY;
5673 spec_empty = TRUE;
5674 spfp = __inst_mod->mspfy;
5675 /* make sure all specparams that were used are defined */
5676 /* unless all specparam values defined cannot check specify section */
5677 /* or determine specparam values */
5678 if (spfp->spfsyms->numsyms != 0)
5679 {
5680 spec_empty = FALSE;
5681 if (!chk_undef_specparams(spfp->spfsyms)) goto done;
5682 }
5683
5684 /* if top level module has paths - emit warning and ignore */
5685 if (__inst_mod->minstnum == 0)
5686 {
5687 if (spfp->spcpths != NULL)
5688 {
5689 __pv_warn(679,
5690 "specify paths in top level module %s ignored - should be in library",
5691 __inst_mod->msym->synam);
5692
5693 spec_empty = FALSE;
5694 free_spcpths(spfp->spcpths);
5695 spfp->spcpths = NULL;
5696 }
5697 }
5698 else
5699 {
5700 /* check pin to pin delays */
5701 for (pthp = spfp->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
5702 {
5703 spec_empty = FALSE;
5704 if (!chk_1spcpth(pthp)) { pthp->pth_gone = TRUE; continue; }
5705 if (pthp->pthtyp == PTH_FULL) chk_rep_in_fullpth(pthp);
5706 }
5707 /* use all module paths to check for sdpds multiple same paths withs conds */
5708 chk_rep_sdpds(spfp);
5709 }
5710
5711 /* check timing checks */
5712 for (tcp = spfp->tchks; tcp != NULL; tcp = tcp->tchknxt)
5713 {
5714 /* if marked gone because of error, do not split setuphold */
5715 spec_empty = FALSE;
5716 if (!chk_1tchk(tcp)) tcp->tc_gone = TRUE;
5717 else
5718 {
5719 if (tcp->tchktyp == TCHK_SETUPHOLD)
5720 {
5721 suptcp = bld_sup_of_suphld(tcp);
5722 /* insert after current and move pointer so not checked */
5723 suptcp->tchknxt = tcp->tchknxt;
5724 tcp->tchknxt = suptcp;
5725 tcp = tcp->tchknxt;
5726 }
5727 else if (tcp->tchktyp == TCHK_RECREM)
5728 {
5729 rectcp = bld_rec_of_recrem(tcp);
5730 /* insert after current and move pointer so not checked */
5731 rectcp->tchknxt = tcp->tchknxt;
5732 tcp->tchknxt = rectcp;
5733 tcp = tcp->tchknxt;
5734 }
5735 }
5736 }
5737 done:
5738 if (spec_empty)
5739 __pv_warn(559,
5740 "module %s specify section has no delay paths or timing checks",
5741 __inst_mod->msym->synam);
5742 __cur_declobj = saveobj;
5743 }
5744
5745 /*
5746 * check for undefined but used specparams
5747 *
5748 * if a variable is used in a delay expr. or tchk limit or specparam rhs
5749 * it is assumed to be an undeclared specparam - this makes sure it appears
5750 * in a specparam statement
5751 */
chk_undef_specparams(struct symtab_t * sytp)5752 static int32 chk_undef_specparams(struct symtab_t *sytp)
5753 {
5754 register int32 syi;
5755 int32 good;
5756 struct sy_t *syp;
5757
5758 __wrkstab = sytp->stsyms;
5759 for (good = TRUE, syi = 0; syi < (int32) sytp->numsyms; syi++)
5760 {
5761 syp = __wrkstab[syi];
5762 if (!syp->sydecl)
5763 {
5764 __gferr(777, syp->syfnam_ind, syp->sylin_cnt,
5765 "specparam or path element %s not defined or not wire", syp->synam);
5766 good = FALSE;
5767 }
5768 }
5769 return(good);
5770 }
5771
5772 /*
5773 * check 1 specify path
5774 * converts from expression to path else simple wire or select
5775 * will return F if error and path marked as gone
5776 *
5777 * any edge check at source input - will be correct by here or previous error
5778 * check cond. expr. here than can be any rhs expression
5779 * eval code handles selecting low bit if needed
5780 */
chk_1spcpth(struct spcpth_t * pthp)5781 static int32 chk_1spcpth(struct spcpth_t *pthp)
5782 {
5783 register struct exprlst_t *pxlp;
5784 register int32 pei;
5785 int32 num_peinels, num_peoutels, pi1, pi2, dnum, sav_errcnt;
5786 word32 badoptyp;
5787 struct exprlst_t *pxins, *pxouts, *pxlp2;
5788 struct net_t *np;
5789 struct pathel_t *pep;
5790 struct expr_t *cndx;
5791 struct paramlst_t *pmp, *dhdr;
5792 char s1[RECLEN];
5793
5794 sav_errcnt = __pv_err_cnt;
5795 __sfnam_ind = pthp->pthsym->syfnam_ind;
5796 __slin_cnt = pthp->pthsym->sylin_cnt;
5797
5798 /* first check input and output path expr. lists */
5799 pxlp = (struct exprlst_t *) pthp->peins;
5800 /* do not bother free error stuff here - if non I/O will need to support */
5801 for (num_peinels = 0; pxlp != NULL; pxlp = pxlp->xpnxt, num_peinels++)
5802 {
5803 if (num_peinels == 0 && pxlp->xpnxt == NULL) strcpy(s1, "");
5804 else sprintf(s1, " terminal %d", num_peinels + 1);
5805 chk_spterm(pxlp->xp, s1, "path input", IO_IN);
5806 }
5807 pxlp = (struct exprlst_t *) pthp->peouts;
5808 for (num_peoutels = 0; pxlp != NULL; pxlp = pxlp->xpnxt, num_peoutels++)
5809 {
5810 if (num_peoutels == 0 && pxlp->xpnxt == NULL) strcpy(s1, "");
5811 else sprintf(s1, " terminal %d", num_peoutels + 1);
5812 chk_spterm(pxlp->xp, s1, "path output", IO_OUT);
5813 }
5814 if (sav_errcnt != __pv_err_cnt) goto chk_pdels;
5815 /* paths must always have 1 element to get here */
5816 if (num_peinels < 1 || num_peoutels < 1) __misc_terr(__FILE__, __LINE__);
5817
5818 /* error for || paths to have lists - but continue checking */
5819 if (pthp->pthtyp == PTH_PAR && (num_peinels > 1 || num_peoutels > 1))
5820 {
5821 __sgferr(1085,
5822 "parallel (=>) path illegally has multiple sources (%d) and/or destinations (%d)",
5823 num_peinels, num_peoutels);
5824 }
5825
5826 /* convert to pathel form and mark wires that are specify srcs and dsts */
5827 pxins = (struct exprlst_t *) pthp->peins;
5828 pxouts = (struct exprlst_t *) pthp->peouts;
5829 /* must build the path tables and mark path source and dest. wires */
5830 pthp->peins = (struct pathel_t *)
5831 __my_malloc(num_peinels*sizeof(struct pathel_t));
5832 pthp->last_pein = num_peinels - 1;
5833 for (pei = 0, pxlp = pxins; pei < num_peinels; pei++)
5834 {
5835 pxlp2 = pxlp->xpnxt;
5836 __xtract_wirng(pxlp->xp, &np, &pi1, &pi2);
5837 pep = &(pthp->peins[pei]);
5838 pep->penp = np;
5839 pep->pthi1 = pi1;
5840 pep->pthi2 = pi2;
5841 np->n_isapthsrc = TRUE;
5842 __free_xtree(pxlp->xp);
5843 __my_free((char *) pxlp, sizeof(struct exprlst_t));
5844 pxlp = pxlp2;
5845 }
5846 pthp->peouts = (struct pathel_t *)
5847 __my_malloc(num_peoutels*sizeof(struct pathel_t));
5848 pthp->last_peout = num_peoutels - 1;
5849 for (pei = 0, pxlp = pxouts; pei < num_peoutels; pei++)
5850 {
5851 pxlp2 = pxlp->xpnxt;
5852 __xtract_wirng(pxlp->xp, &np, &pi1, &pi2);
5853 np->n_isapthdst = TRUE;
5854 pep = &(pthp->peouts[pei]);
5855 pep->penp = np;
5856 pep->pthi1 = pi1;
5857 pep->pthi2 = pi2;
5858 __free_xtree(pxlp->xp);
5859 __my_free((char *) pxlp, sizeof(struct exprlst_t));
5860 pxlp = pxlp2;
5861 }
5862 /* mark form of path expressions changed to range form */
5863 pthp->pth_as_xprs = FALSE;
5864
5865 chk_pdels:
5866 /* first check cond. expr if present */
5867 if ((cndx = pthp->pthcondx) != NULL)
5868 {
5869 __chk_rhsexpr(cndx, 0);
5870 /* normal expression except no xmr's and only path condition operators */
5871 if (__expr_has_glb(cndx))
5872 {
5873 __sgferr(1022,
5874 "global hierarchical reference illegal in state dependent path condition %s",
5875 __msgexpr_tostr(__xs, cndx));
5876 }
5877 if (expr_has_nonpth(cndx, &badoptyp))
5878 {
5879 __sgferr(1022,
5880 "state dependent path condition (%s) illegal operator(s) [one bad: %s]",
5881 __msgexpr_tostr(__xs, cndx), __to_opname(badoptyp));
5882 }
5883 }
5884 /* if ifnone, must be simple module path */
5885 if (pthp->pth_ifnone)
5886 {
5887 if (pthp->pthcondx != NULL || pthp->pthedge != NOEDGE)
5888 {
5889 __sgferr(1012, "ifnone path illegal - has edge or is state dependent");
5890 }
5891 }
5892
5893 /* next check and substitute numeric values for expressions */
5894 /* changed to sim form during prep */
5895 dhdr = __copy_dellst(pthp->pth_du.pdels);
5896 for (dnum = 0, pmp = dhdr; pmp != NULL; pmp = pmp->pmlnxt)
5897 {
5898 sprintf(s1, "path delay (element %d)", dnum + 1);
5899 __chk_spec_delay(pmp->plxndp, s1);
5900 dnum++;
5901 }
5902 __free_dellst(dhdr);
5903 if (dnum == 1 || dnum == 2 || dnum == 3 || dnum == 6 || dnum == 12)
5904 {
5905 if (sav_errcnt != __pv_err_cnt) return(FALSE);
5906 return(TRUE);
5907 }
5908 __sgferr(791, "path delay illegal number of delays %d", dnum);
5909 return(FALSE);
5910 }
5911
5912 /*
5913 * return T if expression has any illegal path cond. expr. operators
5914 * uses value from op info table
5915 */
expr_has_nonpth(struct expr_t * cndx,word32 * badop)5916 static int32 expr_has_nonpth(struct expr_t *cndx, word32 *badop)
5917 {
5918 struct opinfo_t *opip;
5919
5920 *badop = UNDEF;
5921 if (__isleaf(cndx)) return(FALSE);
5922 opip = &(__opinfo[cndx->optyp]);
5923 if (!opip->pthexpop)
5924 {
5925 *badop = cndx->optyp;
5926 return(TRUE);
5927 }
5928
5929 if (cndx->lu.x != NULL)
5930 {
5931 if (expr_has_nonpth(cndx->lu.x, badop)) return(TRUE);
5932 }
5933 if (cndx->ru.x != NULL)
5934 {
5935 if (expr_has_nonpth(cndx->ru.x, badop)) return(TRUE);
5936 }
5937 return(FALSE);
5938 }
5939
5940 /*
5941 * check all paths to make sure no same paths withing full (*>) list
5942 *
5943 * because duplicate entries for same sdpds need different conditions
5944 * error for repeated path in one statement
5945 *
5946 * only called for full *> paths
5947 */
chk_rep_in_fullpth(struct spcpth_t * pthp)5948 static void chk_rep_in_fullpth(struct spcpth_t *pthp)
5949 {
5950 register int32 pei, pei2;
5951 struct pathel_t *pep1, *pep2;
5952 char s1[RECLEN], s2[RECLEN];
5953
5954 /* first check for repeated ins - because full will be repeated */
5955 for (pei = 0; pei <= pthp->last_pein; pei++)
5956 {
5957 pep1 = &(pthp->peins[pei]);
5958 for (pei2 = pei + 1; pei2 <= pthp->last_pein; pei2++)
5959 {
5960 pep2 = &(pthp->peins[pei2]);
5961 if (pep1->penp != pep2->penp) continue;
5962 /* exactly same path repeated */
5963 if (pep1->pthi1 == pep2->pthi1 && pep1->pthi2 == pep2->pthi2)
5964 {
5965 __gferr(1059, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt,
5966 "full path input element %s repeated in one path",
5967 pthel_tostr(s1, pep1));
5968 continue;
5969 }
5970 /* overlapped path repeated */
5971 if (pth_overlap(pep1, pep2))
5972 {
5973 __gferr(1079, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt,
5974 "path path input element %s overlaps %s in one path",
5975 pthel_tostr(s1, pep1), pthel_tostr(s2, pep2));
5976 }
5977 }
5978 }
5979 /* next check for repeated outs - because full will be repeated */
5980 for (pei = 0; pei <= pthp->last_peout; pei++)
5981 {
5982 pep1 = &(pthp->peins[pei]);
5983 for (pei2 = pei + 1; pei2 <= pthp->last_pein; pei2++)
5984 {
5985 pep2 = &(pthp->peouts[pei2]);
5986 if (pep1->penp != pep2->penp) continue;
5987 /* exactly same path repeated */
5988 if (pep1->pthi1 == pep2->pthi1 && pep1->pthi2 == pep2->pthi2)
5989 {
5990 __gferr(1059, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt,
5991 "full path output element %s repeated in one path",
5992 pthel_tostr(s1, pep1));
5993 pthp->pth_gone = TRUE;
5994 continue;
5995 }
5996 /* overlapped path elements error */
5997 if (pth_overlap(pep1, pep2))
5998 {
5999 __gferr(1079, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt,
6000 "path output element %s overlaps %s in one path",
6001 pthel_tostr(s1, pep1), pthel_tostr(s2, pep2));
6002 pthp->pth_gone = TRUE;
6003 }
6004 }
6005 }
6006 }
6007
6008 /*
6009 * convert a simple (non list form) path to a string
6010 */
pth_tostr(char * s,struct spcpth_t * pthp,struct pathel_t * pep1,struct pathel_t * pep2)6011 static char *pth_tostr(char *s, struct spcpth_t *pthp,
6012 struct pathel_t *pep1, struct pathel_t *pep2)
6013 {
6014 char s1[RECLEN], s2[RECLEN], s3[RECLEN];
6015
6016 if (pthp->pthtyp == PTH_FULL) strcpy(s1, "*>"); else strcpy(s1, "=>");
6017 sprintf(s, "(%s %s %s)", pthel_tostr(s2, pep1), s1, pthel_tostr(s3, pep2));
6018 return(s);
6019 }
6020
6021 /*
6022 * convert path element to string
6023 */
pthel_tostr(char * s,struct pathel_t * pep)6024 static char *pthel_tostr(char *s, struct pathel_t *pep)
6025 {
6026 if (pep->pthi1 == -1) strcpy(s, pep->penp->nsym->synam);
6027 else if (pep->pthi1 == pep->pthi2) sprintf(s, "%s[%d]",
6028 pep->penp->nsym->synam, pep->pthi1);
6029 else sprintf(s, "%s[%d:%d]", pep->penp->nsym->synam, pep->pthi1, pep->pthi2);
6030 return(s);
6031 }
6032
6033 /*
6034 * return T if 2 path elements overlap - know not called if identical
6035 */
pth_overlap(struct pathel_t * pep1,struct pathel_t * pep2)6036 static int32 pth_overlap( struct pathel_t *pep1, struct pathel_t *pep2)
6037 {
6038 int32 i1, i2, o1, o2;
6039
6040 if (pep1->pthi1 >= pep1->pthi2) { i1 = pep1->pthi1; i2 = pep1->pthi2; }
6041 else { i1 = pep1->pthi2; i2 = pep1->pthi1; }
6042 if (pep2->pthi1 >= pep2->pthi2) { o1 = pep2->pthi1; o2 = pep2->pthi2; }
6043 else { o1 = pep2->pthi2; o2 = pep2->pthi1; }
6044 if (i2 > o1 || o2 > i1) return(FALSE);
6045 return(TRUE);
6046 }
6047
6048 /*
6049 * check repeated sdpd paths
6050 */
chk_rep_sdpds(struct spfy_t * spfp)6051 static void chk_rep_sdpds(struct spfy_t *spfp)
6052 {
6053 register struct xpnd_pthel_t *xpthp, *xpthp2;
6054 int32 numxpths, last_xpi, xpi, has_ifnone;
6055 struct xpnd_pthel_t *xpth_hdr, **xpth_equivs;
6056 struct spcpth_t *pthp, *pthp2;
6057 struct pathel_t *pep1s, *pep1e, *pep2s, *pep2e;
6058 char s1[RECLEN], s2[RECLEN], s3[RECLEN];
6059
6060 /* for paths that are gone, expanded elements not added */
6061 /* if none expanded, done */
6062 if ((xpth_hdr = xpnd_pths(spfp, &numxpths)) == NULL) return;
6063
6064 /* since as big as entire list know big enough */
6065 xpth_equivs = (struct xpnd_pthel_t **)
6066 __my_malloc(numxpths*sizeof(struct xpnd_pthel_t *));
6067
6068 for (xpthp = xpth_hdr; xpthp != NULL; xpthp = xpthp->xpthnxt)
6069 {
6070 if (xpthp->in_equiv_set) continue;
6071 xpth_equivs[0] = xpthp;
6072 /* since processing done, makr as in equiv. class (maybe size 1) */
6073 xpthp->in_equiv_set = TRUE;
6074 last_xpi = 0;
6075 pthp = xpthp->pthp;
6076 pep1s = &(pthp->peins[xpthp->peii]);
6077 pep1e = &(pthp->peouts[xpthp->peoi]);
6078 for (xpthp2 = xpthp->xpthnxt; xpthp2 != NULL; xpthp2 = xpthp2->xpthnxt)
6079 {
6080 if (xpthp2->in_equiv_set) continue;
6081
6082 pthp2 = xpthp2->pthp;
6083 pep2s = &(pthp2->peins[xpthp2->peii]);
6084 pep2e = &(pthp2->peouts[xpthp2->peoi]);
6085
6086 /* if both src or both dest nets differ, eliminate */
6087 if (pep1s->penp != pep2s->penp || pep1e->penp != pep2e->penp) continue;
6088
6089 /* range must be exact match */
6090 if (pep1s->pthi1 == pep2s->pthi1 && pep1s->pthi2 == pep2s->pthi2
6091 && pep1e->pthi1 == pep2e->pthi1 && pep1e->pthi2 == pep2e->pthi2)
6092 {
6093 xpth_equivs[++last_xpi] = xpthp2;
6094 xpthp2->in_equiv_set = TRUE;
6095 continue;
6096 }
6097
6098 /* probably same paths but not coded the same way - error */
6099 /* notice some source bit(s) to two different dest bit(s) ok */
6100 if (pth_overlap(pep1s, pep2s) && pth_overlap(pep1e, pep2e))
6101 {
6102 __gferr(1118, pthp2->pthsym->syfnam_ind, pthp2->pthsym->sylin_cnt,
6103 "path %s and path %s at %s overlap - multiple sdpds must have identical ranges",
6104 pth_tostr(s1, pthp2, pep2s, pep2e), pth_tostr(s2, pthp, pep1s, pep1e),
6105 __bld_lineloc(s3, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt));
6106 /* mark so will test for other overlap equivalences */
6107 xpthp2->in_equiv_set = TRUE;
6108 }
6109 }
6110 /* check equivalence class (even if only one element) */
6111 if (last_xpi == 0)
6112 {
6113 pthp2 = xpth_equivs[0]->pthp;
6114 if (pthp2->pth_ifnone)
6115 {
6116 pthp2->pth_ifnone = FALSE;
6117 __gfinform(482, pthp2->pthsym->syfnam_ind, pthp2->pthsym->sylin_cnt,
6118 "path has ifnone condition but no other sdpds for path - made simple");
6119 }
6120 continue;
6121 }
6122 /* real multiple path - only check makes sure either has cond or edge */
6123 /* LOOKATME - will not work if same expressions but can not check this */
6124 for (has_ifnone = FALSE, xpi = 0; xpi <= last_xpi; xpi++)
6125 {
6126 xpthp2 = xpth_equivs[xpi];
6127 pthp2 = xpthp2->pthp;
6128 /* if none must be simple - already check */
6129 if (pthp2->pth_ifnone)
6130 {
6131 if (has_ifnone)
6132 {
6133 __gferr(1125, pthp2->pthsym->syfnam_ind, pthp2->pthsym->sylin_cnt,
6134 "more than one ifnone path in sdpd same path group illegal");
6135 }
6136 else has_ifnone = TRUE;
6137 continue;
6138 }
6139 /* other in same path sdpd group must be non simple */
6140 if (pthp2->pthcondx == NULL && pthp2->pthedge == NOEDGE)
6141 {
6142 __gferr(1126, pthp2->pthsym->syfnam_ind, pthp2->pthsym->sylin_cnt,
6143 "path in sdpd same path group illegally simple - needs edge or conditon");
6144 }
6145 }
6146 }
6147
6148 /* free the expanded path list */
6149 __my_free((char *) xpth_equivs, numxpths*sizeof(struct xpnd_pthel_t *));
6150 for (xpthp = xpth_hdr; xpthp != NULL;)
6151 {
6152 xpthp2 = xpthp->xpthnxt;
6153 __my_free((char *) xpthp, sizeof(struct xpnd_pthel_t));
6154 xpthp = xpthp2;
6155 }
6156 }
6157
6158 /*
6159 * expand paths into list of simple (non list form) elements
6160 */
xpnd_pths(struct spfy_t * spfp,int32 * numxpths)6161 static struct xpnd_pthel_t *xpnd_pths(struct spfy_t *spfp,
6162 int32 *numxpths)
6163 {
6164 register int32 pii, poi;
6165 int32 numxps;
6166 struct spcpth_t *pthp;
6167 struct xpnd_pthel_t *xpth_hdr, *xpth_end, *xpthp;
6168
6169 xpth_hdr = xpth_end = NULL;
6170 numxps = 0;
6171 for (pthp = spfp->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
6172 {
6173 if (pthp->pth_gone) continue;
6174
6175 if (pthp->pthtyp == PTH_PAR)
6176 {
6177 xpthp = (struct xpnd_pthel_t *) __my_malloc(sizeof(struct xpnd_pthel_t));
6178 xpthp->in_equiv_set = FALSE;
6179 xpthp->pthp = pthp;
6180 xpthp->peii = xpthp->peoi = 0;
6181 xpthp->xpthnxt = NULL;
6182 if (xpth_hdr == NULL) xpth_hdr = xpth_end = xpthp;
6183 else { xpth_end->xpthnxt = xpthp; xpth_end = xpthp; }
6184 numxps++;
6185 continue;
6186 }
6187 /* harder full path case */
6188 for (pii = 0; pii <= pthp->last_pein; pii++)
6189 {
6190 for (poi = 0; poi <= pthp->last_peout; poi++)
6191 {
6192 xpthp = (struct xpnd_pthel_t *) __my_malloc(sizeof(struct xpnd_pthel_t));
6193 xpthp->in_equiv_set = FALSE;
6194 xpthp->pthp = pthp;
6195 xpthp->peii =pii;
6196 xpthp->peoi = poi;
6197 xpthp->xpthnxt = NULL;
6198 if (xpth_hdr == NULL) xpth_hdr = xpth_end = xpthp;
6199 else { xpth_end->xpthnxt = xpthp; xpth_end = xpthp; }
6200 numxps++;
6201 }
6202 }
6203 }
6204 *numxpths = numxps;
6205 return(xpth_hdr);
6206 }
6207
6208 /*
6209 * check a specify section delay value
6210 */
__chk_spec_delay(struct expr_t * ndp,char * emsg)6211 extern void __chk_spec_delay(struct expr_t *ndp, char *emsg)
6212 {
6213 /* first must be expr. of numbers and parameters only */
6214 if (!__chk_paramexpr(ndp, 0))
6215 {
6216 __sgferr(898, "%s must be specify constant expression", emsg);
6217 return;
6218 }
6219 /* then must fold */
6220 fold_subexpr(ndp);
6221 /* finally check to make sure number delay - prep code scales */
6222 __chk_numdelay(ndp, emsg);
6223 ndp->ibase = BDEC;
6224 }
6225
6226 /*
6227 * check specify terminal (path or timing check)
6228 * do not remove since will not get to prep. code
6229 */
chk_spterm(struct expr_t * spxp,char * spos,char * snam,int32 iodir)6230 static void chk_spterm(struct expr_t *spxp, char *spos, char *snam,
6231 int32 iodir)
6232 {
6233 struct net_t *np;
6234 struct expr_t *xp, *xp2;
6235
6236 /* if even path destination (could be rhs reg), here must be lhs wire */
6237 if (spxp->optyp == LCB)
6238 {
6239 __sgferr(914, "%s%s concatenate illegal", snam, spos);
6240 return;
6241 }
6242 if (spxp->optyp == GLBREF)
6243 {
6244 __sgferr(899, "%s%s hierarchical reference illegal", snam, spos);
6245 return;
6246 }
6247 /* exactly 3 things legal, port wire, bsel of port wire, psel of port wire */
6248 switch (spxp->optyp) {
6249 case ID:
6250 np = spxp->lu.sy->el.enp;
6251
6252 chk_iodir:
6253 /* timing check terminal can be any wire */
6254 if (iodir == NON_IO)
6255 {
6256 if (np->ntyp >= NONWIRE_ST)
6257 {
6258 __sgferr(901, "%s%s terminal %s %s must be a wire",
6259 snam, spos, __to_wtnam(__xs, np), np->nsym->synam);
6260 }
6261 return;
6262 }
6263
6264 /* check to make sure terminal is port */
6265 if (np->iotyp == NON_IO)
6266 {
6267 __sgferr(905, "%s%s %s %s must be a module I/O port",
6268 snam, spos, __to_wtnam(__xs, np), np->nsym->synam);
6269 return;
6270 }
6271 if (iodir == IO_IN)
6272 {
6273 if (np->iotyp != IO_IN && np->iotyp != IO_BID)
6274 {
6275 __sgferr(906, "%s%s port %s must be input or inout", snam, spos,
6276 np->nsym->synam);
6277 return;
6278 }
6279 }
6280 else
6281 {
6282 if (np->iotyp != IO_OUT && np->iotyp != IO_BID)
6283 {
6284 __sgferr(907, "%s%s port %s must be output or inout", snam, spos,
6285 np->nsym->synam);
6286 return;
6287 }
6288 }
6289 break;
6290 case LSB:
6291 np = spxp->lu.x->lu.sy->el.enp;
6292 xp = spxp->ru.x;
6293 /* index must only contain specparams and numbers */
6294 if (!__chk_paramexpr(xp, 0)) return;
6295 /* next must fold it */
6296 fold_subexpr(xp);
6297 /* result must be number (no IS form) or error */
6298 if (xp->optyp != NUMBER)
6299 {
6300 __sgferr(908,
6301 "%s%s port bit select %s must contain only numbers and specparams",
6302 snam, spos, __msgexpr_tostr(__xs, spxp));
6303 }
6304 /* finally check and normalize bit select */
6305 chk_inrng_bsel(spxp);
6306 goto chk_iodir;
6307 case PARTSEL:
6308 np = spxp->lu.x->lu.sy->el.enp;
6309 xp = spxp->ru.x->lu.x;
6310 xp2 = spxp->ru.x->ru.x;
6311 /* index must only contain specparams and numbers */
6312 if (!__chk_paramexpr(xp, 0) || !__chk_paramexpr(xp2, 0)) return;
6313 /* next must fold it */
6314 fold_subexpr(xp);
6315 fold_subexpr(xp2);
6316 /* result must be number (no IS form) or error */
6317 if (xp->optyp != NUMBER || xp2->optyp != NUMBER)
6318 {
6319 __sgferr(904,
6320 "%s%s port part select %s must contain only numbers and specparams",
6321 snam, spos, __msgexpr_tostr(__xs, spxp));
6322 }
6323 /* finally check and normalize bit select */
6324 chk_inrng_psel(spxp);
6325 goto chk_iodir;
6326 default:
6327 __sgferr(915, "%s%s illegal expression %s", snam, spos,
6328 __msgexpr_tostr(__xs, spxp));
6329 }
6330 }
6331
6332 /*
6333 * check 1 specify timing check
6334 *
6335 * notice only checking here - width/period event duplicated in prep code
6336 * limit evaluation routines must be recalled if specparams changed
6337 * any edges read and checking during source input but cond checked here
6338 */
chk_1tchk(struct tchk_t * tcp)6339 static int32 chk_1tchk(struct tchk_t *tcp)
6340 {
6341 int32 sav_errcnt;
6342 struct paramlst_t *dhdr;
6343 char s1[RECLEN], s2[RECLEN];
6344
6345 __sfnam_ind = tcp->tcsym->syfnam_ind;
6346 __slin_cnt = tcp->tcsym->sylin_cnt;
6347
6348 sav_errcnt = __pv_err_cnt;
6349 sprintf(s1, " %s timing check", __to_tcnam(s2, tcp->tchktyp));
6350 switch ((byte) tcp->tchktyp) {
6351 case TCHK_SETUP: case TCHK_HOLD: case TCHK_SKEW: case TCHK_SETUPHOLD:
6352 case TCHK_RECOVERY: case TCHK_REMOVAL: case TCHK_RECREM:
6353 /* SJM 01/16/04 - $removal has reversed terms to $recovery as setup/hold */
6354 chk_spterm(tcp->startxp, "first event", s1, NON_IO);
6355 if (tcp->startcondx != NULL) chk_tccond(tcp->startcondx, "first", s1);
6356 chk_spterm(tcp->chkxp, "second event", s1, NON_IO);
6357 if (tcp->chkcondx != NULL) chk_tccond(tcp->chkcondx, "second", s1);
6358 chk_notifier(tcp, s1);
6359
6360 /* this will find errors and if errors convert to 0 */
6361 /* notice leave 1st (setup) limit even though not used for hold part */
6362 dhdr = __copy_dellst(tcp->tclim_du.pdels);
6363 __chk_spec_delay(dhdr->plxndp, "timing check limit");
6364 __free_dellst(dhdr);
6365
6366 /* this is hold half limit but kept in original not added setup */
6367 if (tcp->tchktyp == TCHK_SETUPHOLD)
6368 {
6369 dhdr = __copy_dellst(tcp->tclim2_du.pdels);
6370 __chk_spec_delay(dhdr->plxndp, "setuphold second (hold) limit");
6371 __free_dellst(dhdr);
6372 }
6373 /* this is removal half limit but kept in original not added recovery */
6374 else if (tcp->tchktyp == TCHK_SETUPHOLD)
6375 {
6376 dhdr = __copy_dellst(tcp->tclim2_du.pdels);
6377 __chk_spec_delay(dhdr->plxndp, "recrem second (removal) limit");
6378 __free_dellst(dhdr);
6379 }
6380 break;
6381 case TCHK_WIDTH: case TCHK_PERIOD:
6382 /* one event, 2 limits for width but 2nd threshold is optional */
6383 chk_spterm(tcp->startxp, "first edge", s1, NON_IO);
6384 if (tcp->startcondx != NULL) chk_tccond(tcp->startcondx, "first edge", s1);
6385 chk_notifier(tcp, s1);
6386 /* check delay expr. */
6387 dhdr = __copy_dellst(tcp->tclim_du.pdels);
6388 __chk_spec_delay(dhdr->plxndp, "timing check limit");
6389 __free_dellst(dhdr);
6390
6391 if (tcp->tchktyp == TCHK_WIDTH)
6392 {
6393 dhdr = __copy_dellst(tcp->tclim2_du.pdels);
6394 __chk_spec_delay(dhdr->plxndp, "width second limit");
6395 __free_dellst(dhdr);
6396 }
6397 break;
6398 default: __case_terr(__FILE__, __LINE__);
6399 }
6400 /* if any errors, return fail (F) */
6401 if (sav_errcnt != __pv_err_cnt) return(FALSE);
6402 return(TRUE);
6403 }
6404
6405 /*
6406 * check the option condition
6407 * notice this is procedural rhs
6408 */
chk_tccond(struct expr_t * cndx,char * spos,char * snam)6409 static void chk_tccond(struct expr_t *cndx, char *spos, char *snam)
6410 {
6411 struct net_t *np;
6412
6413 /* this expr. needs to be one bit but width self determined */
6414 __chk_rhsexpr(cndx, 0);
6415 switch ((byte) cndx->optyp) {
6416 case ID:
6417 np = cndx->lu.sy->el.enp;
6418 chk_1bit:
6419 /* notice - wires ok here - just gets evaluated */
6420 if (np->n_isarr)
6421 {
6422 __sgferr(909, "%s %s &&& condition array %s illegal", spos, snam,
6423 np->nsym->synam);
6424 return;
6425 }
6426 if (cndx->szu.xclen > 1)
6427 {
6428 __sgfwarn(613,
6429 "%s %s &&& condition expression %s wider than 1 bit - low bit used",
6430 spos, snam, __msgexpr_tostr(__xs, cndx));
6431 }
6432 return;
6433 case BITNOT:
6434 if (cndx->lu.x->optyp != ID)
6435 __sgferr(910,
6436 "%s %s &&& condition ~ (bit not) operand too complicated (must be identifier)",
6437 spos, snam);
6438 np = cndx->lu.x->lu.sy->el.enp;
6439 goto chk_1bit;
6440 case RELCEQ:
6441 case RELCNEQ:
6442 case RELEQ:
6443 case RELNEQ:
6444 if (cndx->lu.x->optyp != ID)
6445 {
6446 __sgferr(912,
6447 "%s %s &&& condition left operand too complicated (must be identifier)",
6448 spos, snam);
6449 return;
6450 }
6451 np = cndx->lu.x->lu.sy->el.enp;
6452 if (cndx->ru.x->optyp != NUMBER || cndx->ru.x->szu.xclen > WBITS)
6453 {
6454 bad_const:
6455 __sgferr(911,
6456 "%s %s &&& condition right operand must be a scalar constant",
6457 spos, snam);
6458 goto chk_1bit;
6459 }
6460 if (cndx->ru.x->szu.xclen != 1)
6461 {
6462 word32 av, bv;
6463 word32 *wp;
6464
6465 wp = &(__contab[cndx->ru.x->ru.xvi]);
6466 av = wp[0];
6467 bv = wp[1];
6468 if ((av != 0L && av != 1L) || (bv != 0L && bv != 1L)) goto bad_const;
6469 cndx->ru.x->szu.xclen = 1;
6470 }
6471 goto chk_1bit;
6472 default:
6473 __sgferr(913,
6474 "%s %s &&& condition expression must be one operator scalar expression",
6475 spos, snam);
6476 }
6477 }
6478
6479 /*
6480 * check a notifier - must be register
6481 * this also changed coded symbol to wire or NULL
6482 */
chk_notifier(struct tchk_t * tcp,char * snam)6483 static void chk_notifier(struct tchk_t *tcp, char *snam)
6484 {
6485 struct sy_t *syp;
6486
6487 if (tcp->ntfy_np == NULL) return;
6488 syp = (struct sy_t *) tcp->ntfy_np;
6489 if (syp->sytyp != SYM_N || syp->el.enp->ntyp != N_REG
6490 || syp->el.enp->n_isavec)
6491 {
6492 __sgferr(916,
6493 "%s notify symbol %s is not a scalar register", snam, syp->synam);
6494 tcp->ntfy_np = NULL;
6495 return;
6496 }
6497 tcp->ntfy_np = syp->el.enp;
6498 }
6499
6500 /*
6501 * build setuphold new setup timing check
6502 *
6503 * setuphold contains hold half (ref. and data event orders match),
6504 * setup has reversed but uses 1st delay from hold referenced thru lim
6505 */
bld_sup_of_suphld(struct tchk_t * otcp)6506 static struct tchk_t *bld_sup_of_suphld(struct tchk_t *otcp)
6507 {
6508 struct tchk_t *ntcp;
6509
6510 ntcp = (struct tchk_t *) __my_malloc(sizeof(struct tchk_t));
6511 __init_tchk(ntcp, TCHK_SETUP);
6512 ntcp->tc_supofsuphld = TRUE;
6513 /* notice the 2 halves share symbol and handled specially in mod copy */
6514 ntcp->tcsym = otcp->tcsym;
6515 /* reverse edges */
6516 ntcp->startedge = otcp->chkedge;
6517 ntcp->chkedge = otcp->startedge;
6518
6519 /* copy start reference event expr. from check */
6520 if (otcp->startxp != NULL) ntcp->chkxp = __copy_expr(otcp->startxp);
6521 if (otcp->startcondx != NULL)
6522 ntcp->chkcondx = __copy_expr(otcp->startcondx);
6523
6524 /* copy start reference event expr. from check */
6525 if (otcp->chkxp != NULL) ntcp->startxp = __copy_expr(otcp->chkxp);
6526 if (otcp->chkcondx != NULL)
6527 ntcp->startcondx = __copy_expr(otcp->chkcondx);
6528 /* point first delay to master hold and get delay (1st) from there */
6529 ntcp->tclim_du.pdels = (struct paramlst_t *) otcp;
6530
6531 /* notice this is intra module so can just copy - becomes net */
6532 ntcp->ntfy_np = otcp->ntfy_np;
6533 return(ntcp);
6534 }
6535
6536 /*
6537 * build recrems new recovery timing check
6538 * SJM - 01/16/04 added to support new 2001 LRM $recrem
6539 *
6540 * recrem contains removal half (ref. and data event orders match),
6541 * recovery has reversed but uses 1st delay from removal referenced thru lim
6542 */
bld_rec_of_recrem(struct tchk_t * otcp)6543 static struct tchk_t *bld_rec_of_recrem(struct tchk_t *otcp)
6544 {
6545 struct tchk_t *ntcp;
6546
6547 ntcp = (struct tchk_t *) __my_malloc(sizeof(struct tchk_t));
6548 __init_tchk(ntcp, TCHK_RECOVERY);
6549 ntcp->tc_recofrecrem = TRUE;
6550 /* notice the 2 halves share symbol and handled specially in mod copy */
6551 ntcp->tcsym = otcp->tcsym;
6552 /* reverse edges */
6553 ntcp->startedge = otcp->chkedge;
6554 ntcp->chkedge = otcp->startedge;
6555
6556 /* copy start reference event expr. from check */
6557 if (otcp->startxp != NULL) ntcp->chkxp = __copy_expr(otcp->startxp);
6558 if (otcp->startcondx != NULL)
6559 ntcp->chkcondx = __copy_expr(otcp->startcondx);
6560
6561 /* copy start reference event expr. from check */
6562 if (otcp->chkxp != NULL) ntcp->startxp = __copy_expr(otcp->chkxp);
6563 if (otcp->chkcondx != NULL)
6564 ntcp->startcondx = __copy_expr(otcp->chkcondx);
6565 /* point first delay to master hold and get delay (1st) from there */
6566 ntcp->tclim_du.pdels = (struct paramlst_t *) otcp;
6567
6568 /* notice this is intra module so can just copy - becomes net */
6569 ntcp->ntfy_np = otcp->ntfy_np;
6570 return(ntcp);
6571 }
6572
6573 /*
6574 * emit unused informs for all parameters and specparams
6575 */
__emit_param_informs(void)6576 extern void __emit_param_informs(void)
6577 {
6578 register int32 pi;
6579 register struct net_t *np;
6580 register struct task_t *tskp;
6581
6582 for (pi = 0; pi < __inst_mod->mprmnum; pi++)
6583 {
6584 np = &(__inst_mod->mprms[pi]);
6585 if (!np->n_isaparam || np->nu.ct->n_onrhs) continue;
6586
6587 __gfinform(451, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
6588 "in %s: parameter %s unused", __inst_mod->msym->synam, np->nsym->synam);
6589 }
6590
6591 /* AIV 09/27/06 - also need to check the local params */
6592 for (pi = 0; pi < __inst_mod->mlocprmnum; pi++)
6593 {
6594 np = &(__inst_mod->mlocprms[pi]);
6595 if (!np->n_isaparam || !np->nu.ct->p_locparam || np->nu.ct->n_onrhs)
6596 continue;
6597
6598 __gfinform(451, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
6599 "in %s: localparam %s unused", __inst_mod->msym->synam, np->nsym->synam);
6600 }
6601
6602 for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
6603 {
6604 for (pi = 0; pi < tskp->tprmnum; pi++)
6605 {
6606 np = &(tskp->tsk_prms[pi]);
6607 if (!np->n_isaparam || np->nu.ct->n_onrhs) continue;
6608
6609 __gfinform(451, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
6610 "in %s.%s: parameter %s unused", __inst_mod->msym->synam,
6611 tskp->tsksyp->synam, np->nsym->synam);
6612 }
6613 for (pi = 0; pi < tskp->tlocprmnum; pi++)
6614 {
6615 np = &(tskp->tsk_locprms[pi]);
6616 if (!np->n_isaparam || !np->nu.ct->p_locparam || np->nu.ct->n_onrhs)
6617 continue;
6618
6619 __gfinform(451, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
6620 "in %s.%s: localparam %s unused", __inst_mod->msym->synam,
6621 tskp->tsksyp->synam, np->nsym->synam);
6622 }
6623 }
6624
6625 if (__no_specify || __inst_mod->mspfy == NULL) return;
6626 for (pi = 0; pi < __inst_mod->mspfy->sprmnum; pi++)
6627 {
6628 np = &(__inst_mod->mspfy->msprms[pi]);
6629 /* DBG remove --- */
6630 if (!np->n_isaparam) __misc_terr(__FILE__, __LINE__);
6631 /* --- */
6632 if (np->nu.ct->n_onrhs) continue;
6633
6634 __gfinform(452, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
6635 "in %s: specparam %s unused", __inst_mod->msym->synam, np->nsym->synam);
6636 }
6637 }
6638
6639 /*
6640 * free specify
6641 * this can only be called be prep of specify section called
6642 */
__free_specify(struct mod_t * mdp)6643 extern void __free_specify(struct mod_t *mdp)
6644 {
6645 struct spfy_t *spfp;
6646
6647 spfp = mdp->mspfy;
6648 if (spfp->spfsyms != NULL) free_frozen_symtab(spfp->spfsyms);
6649 if (spfp->spcpths != NULL) free_spcpths(spfp->spcpths);
6650 if (spfp->tchks != NULL) __free_tchks(spfp->tchks);
6651 if (spfp->msprms != NULL) free_spcparms(spfp->msprms, spfp->sprmnum);
6652 }
6653
6654 /*
6655 * free specify section paths
6656 */
free_spcpths(struct spcpth_t * pthp)6657 static void free_spcpths(struct spcpth_t *pthp)
6658 {
6659 register int32 pi;
6660 struct pathel_t *pep;
6661 struct spcpth_t *pthp2;
6662
6663 for (; pthp != NULL;)
6664 {
6665 pthp2 = pthp->spcpthnxt;
6666 /* normal case free as fixup to path elements */
6667 if (!pthp->pth_as_xprs)
6668 {
6669 /* first mark all path source and destination wires as non paths */
6670 for (pi = 0; pi <= pthp->last_pein; pi++)
6671 { pep = &(pthp->peins[pi]); pep->penp->n_isapthsrc = FALSE; }
6672 for (pi = 0; pi <= pthp->last_peout; pi++)
6673 { pep = &(pthp->peouts[pi]); pep->penp->n_isapthdst = FALSE; }
6674
6675 /* next delete the path range arrays */
6676 if (pthp->last_pein >= 0) __my_free((char *) pthp->peins,
6677 (pthp->last_pein + 1)*sizeof(struct pathel_t));
6678 if (pthp->last_peout >= 0) __my_free((char *) pthp->peouts,
6679 (pthp->last_peout + 1)*sizeof(struct pathel_t));
6680 }
6681 else
6682 {
6683 /* freeing before fixup must free expr. list */
6684 __free_xprlst((struct exprlst_t *) pthp->peins);
6685 __free_xprlst((struct exprlst_t *) pthp->peouts);
6686 }
6687 /* free does nothing if nil */
6688 __free_dellst(pthp->pth_du.pdels);
6689 __free_xtree(pthp->datasrcx);
6690 __free_xtree(pthp->pthcondx);
6691
6692 __my_free((char *) pthp, sizeof(struct spcpth_t));
6693 pthp = pthp2;
6694 }
6695 }
6696
6697 /*
6698 * free timing checks
6699 */
__free_tchks(struct tchk_t * tcp)6700 extern void __free_tchks(struct tchk_t *tcp)
6701 {
6702 struct tchk_t *tcp2;
6703
6704 for (; tcp != NULL;)
6705 {
6706 tcp2 = tcp->tchknxt;
6707 /* notice freeing null expr. is ok, does nothing */
6708 /* and for setup of setuphold and recovery of recrem these are copied */
6709 __free_xtree(tcp->startxp);
6710 __free_xtree(tcp->startcondx);
6711 __free_xtree(tcp->chkxp);
6712 __free_xtree(tcp->chkcondx);
6713 /* but delays shared (not copied) with hold of setup hold - can't free */
6714 if (!tcp->tc_supofsuphld && !tcp->tc_recofrecrem)
6715 {
6716 __free_dellst(tcp->tclim_du.pdels);
6717 __free_dellst(tcp->tclim2_du.pdels);
6718 }
6719 /* must not free symbol for ntfy_np */
6720 __my_free((char *) tcp, sizeof(struct tchk_t));
6721 tcp = tcp2;
6722 }
6723 }
6724
6725 /*
6726 * free specify parameters - passing spec param (net) table
6727 */
free_spcparms(struct net_t * nptab,int32 pnum)6728 static void free_spcparms(struct net_t *nptab, int32 pnum)
6729 {
6730 register int32 pi;
6731 struct net_t *np;
6732 struct ncomp_t *ncomp;
6733
6734 /* first free insides */
6735 for (pi = 0; pi < pnum; pi++)
6736 {
6737 np = &(nptab[pi]);
6738 /* nothing inside net but comp union to free (at fixup time) */
6739 ncomp = np->nu.ct;
6740 /* just free the expressions since if arg. nil does nothing */
6741 __free_xtree(ncomp->nx1);
6742 __free_xtree(ncomp->nx2);
6743 __free_xtree(ncomp->ax1);
6744 __free_xtree(ncomp->ax2);
6745 /* will free the ncomp in blocks later */
6746 /* SJM 03/29/99 - no list - only one value (maybe min:nom:max) */
6747 __free_xtree(ncomp->n_dels_u.d1x);
6748 }
6749 /* then free entire block */
6750 __my_free((char *) nptab, pnum*sizeof(struct net_t));
6751 }
6752
6753 /*
6754 * free 1 frozen symbol table
6755 */
free_frozen_symtab(struct symtab_t * sytp)6756 static void free_frozen_symtab(struct symtab_t *sytp)
6757 {
6758 register int32 syi;
6759 struct sy_t *syp;
6760
6761 /* may be dummy symbol table */
6762 if (sytp->numsyms == 0) return;
6763
6764 if (sytp->stsyms == NULL) __misc_terr(__FILE__, __LINE__);
6765 for (syi = 0; syi < (int32) sytp->numsyms; syi++)
6766 {
6767 /* frozen form is array of ptrs to symbols */
6768 syp = sytp->stsyms[syi];
6769 /* notice must leave symbol names even though not accessible */
6770 __my_free((char *) syp, sizeof(struct sy_t));
6771 }
6772 __my_free((char *) sytp->stsyms,
6773 (int32) (sytp->numsyms*sizeof(struct sy_t *)));
6774 __my_free((char *) sytp, sizeof(struct symtab_t));
6775 }
6776