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