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  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #ifdef __DBMALLOC__
37 #include "../malloc.h"
38 #endif
39 
40 #include "v.h"
41 #include "cvmacros.h"
42 
43 /* local prototypes */
44 static void bld_root_dfpglbs(void);
45 static int32 dfploc_cmp(const void *, const void *);
46 static void dmp_dfps(int32, int32);
47 static void bld_root2_dfpglbs(struct itree_t *, int32);
48 static void bld_identdfparams(int32);
49 static int32 ipth_cmp(const void *, const void *);
50 static int32 ipth2_cmp(register struct dfparam_t *, register struct dfparam_t *);
51 static void find_mustsplit_dfps(void);
52 static void do_defparam_splitting(void);
53 static void reset_dfp_targsyps(void);
54 static void reset_1dfp_targsyp(struct dfparam_t *);
55 static void reassign2_itnums(struct itree_t *);
56 static void set2_poundparams(struct itree_t *);
57 static void assgn_is_param(struct net_t *, struct xstk_t *, int32, int32, int32);
58 static void replace_param_rhs_expr(struct net_t *, word32 *, struct mod_t *);
59 static void set_1defparam(struct dfparam_t *);
60 static void recalc_1mod_params(struct mod_t *, struct net_t *, int32);
61 static void recalc_1mod_pndparams(struct mod_t *);
62 static int32 xpr_has_is_param(struct expr_t *);
63 static void set_parmval_from_isxpr(struct net_t *, struct expr_t *,
64  struct mod_t *);
65 static int32 all_parent_mods_recalced(struct mod_t *);
66 
67 static void set_lhs_expr_drvrtyp(struct expr_t *, int32, int32, int32);
68 static int32 comp_pre_elab_norm_con_ndx(struct net_t *, struct expr_t *, int32,
69  int32);
70 static int32 is_nonis_const_expr(struct expr_t *);
71 static void set_scalar_drvr_type(struct net_t *, int32);
72 static void set_vec_drvr_type(struct net_t *, int32, int32, int32);
73 static int32 port_expr_has_wrong_dir_drvr(struct expr_t *, int32, int32, int32, int32,
74  int32);
75 static int32 find_max_rng_drvr_state(struct net_t *, int32, int32);
76 static int32 expr_decl_lvalue(struct expr_t *);
77 static void chg_mpx_to_bid(struct expr_t *);
78 static void free_design_ndrvrs(void);
79 
80 static void bld_timstr_vals(void);
81 static void inrnges_mark_params(struct symtab_t *);
82 static void psel_set_allexprs(struct mod_t *);
83 static void stmt_do_inpsel_set(struct st_t *);
84 static void lstofsts_do_inpsel_set(register struct st_t *);
85 static void csitemlst_do_inpsel_set(register struct csitem_t *);
86 static void inpsel_xpr_markparam(struct expr_t *);
87 static void chk_undef_syms(struct symtab_t *, word32);
88 static void chkset_1mwire_rnges(void);
89 static void chk_modsym(struct sy_t *);
90 static void chk_1wire(struct net_t *);
91 static void chk_1reg(struct net_t *);
92 static void mark_sttypewires(void);
93 static void mark_stdr_wires(void);
94 static void mark_stdr_inout_wired_logic(void);
95 static int32 has_non_stren_wired_net(struct expr_t *);
96 static int32 net_type_tri(word32);
97 static int32 chk_hasst_wires(struct mod_t *, struct expr_t *);
98 static void mark_stwires(struct mod_t *, struct expr_t *);
99 static void prop_stsdown(void);
100 static void prop_stsup(void);
101 static int32 chkdel_expr(struct expr_t *, char *, int32);
102 static int32 nd_delnum(struct expr_t *, char *);
103 static int32 nd_delisnum(struct expr_t *, char *);
104 static void freeset_is0del(struct expr_t *, int32);
105 static void wr_ndisdel_err(struct expr_t *, int32, char *);
106 static void chk_wire_rng(struct net_t *);
107 static void chg_rng_isnum_to_num(struct net_t *, struct expr_t *, char *);
108 static void chk_taskvars(struct task_t *, int32);
109 static int32 chk_prtwidth(struct expr_t *, struct mod_pin_t *);
110 static void emit_shorted_informs(int32);
111 static void emit_1net_shorted_informs(struct mod_pin_t *, int32,
112  struct net_t *, int32);
113 static int32 net_in_expr(struct net_t *, struct expr_t *);
114 static int32 xhas_multconn_wire(struct expr_t *);
115 static void emit_nonbid_shortwarn(struct mod_pin_t *, struct expr_t *);
116 static void reconn_1mod_gateterms(struct mod_t *);
117 static struct expr_t *bld_bsel_expr(struct net_t *, int32);
118 static void conn_1gateterm_concat(struct mod_t *, struct giarr_t *,
119  struct expr_t *, int32);
120 static int32 legal_giarr_conn_concat(struct expr_t *);
121 static void reconn_1mod_instports(struct mod_t *);
122 static struct expr_t *bld_psel_expr(struct net_t *, int32, int32);
123 static void conn_1instport_concat(struct mod_t *, struct giarr_t *,
124  struct expr_t *, int32, int32);
125 static struct exprlst_t *splt_icat_align_xlist(struct expr_t *, int32);
126 static struct expr_t *bld_num_expr(struct xstk_t *);
127 static void set_1mpx_stren(struct expr_t *);
128 static void chk_1tsk(struct task_t *);
129 static void chk_inst_conns(void);
130 static void chk_iconn_downxmr(struct inst_t *, struct expr_t *);
131 static void chk_iconn_mixeddirrng(struct inst_t *, struct mod_pin_t *,
132  struct expr_t *);
133 static void chk_gates(void);
134 static int32 chk_1bltingate(struct gate_t *);
135 static void gate_errifn(struct gate_t *, int32);
136 static void chk_gate_nostren(struct gate_t *);
137 static void chk_tran_gate(struct gate_t *);
138 static int32 chk_tran_terms_same(struct gate_t *);
139 static void set_unc_gateterm(struct gate_t *, int32);
140 static void chk_1bit_tran(struct gate_t *, struct expr_t *, struct net_t *,
141  int32);
142 static void chk_tranif_gate(struct gate_t *);
143 static void chk_pull_gate(struct gate_t *);
144 static int32 chk_1udp(struct gate_t *);
145 static int32 chk_gate_source(struct gate_t *, struct expr_t *, int32, int32,
146  struct net_t **);
147 static void chk_contas(void);
148 static void cnv_1bcas_into_garr(int32, struct conta_t *);
149 static struct gate_t *convert_1bca_togate(struct gate_t *,
150  struct conta_t *);
151 static void nd_1bit_concat(struct expr_t *);
152 static void chk_getpat_nonscal(struct expr_t *);
153 static void chk_funcdef(struct task_t *);
154 static void chk_fdef_args(struct task_t *);
155 static void chk_nodel_stmt(struct st_t *);
156 static void chk_nodel_dsable(struct st_t *);
157 static int32 lhsexpr_hassym(struct expr_t *, struct sy_t *);
158 static void chk_varinits(void);
159 static void chk_stmts(void);
160 static void chk_1stmt(struct st_t *);
161 static void chk_case(struct st_t *);
162 static void chk_dctrl(struct delctrl_t *);
163 static void bld_stlst_evxlst(struct st_t *);
164 static void bld_stmt_evxlst(struct st_t *);
165 static void bld_case_evxlst(struct st_t *);
166 static void bld_tskenable_evxlst(struct st_t *);
167 static void bld_rhs_impl_evxlst(struct expr_t *);
168 static void bld_lhs_impl_evxlst(struct expr_t *);
169 static int32 xp_in_evxlst(struct expr_t *);
170 static struct expr_t *bld_evlst_comma_expr(void);
171 static void chk_qclvalue(struct expr_t *, word32, int32 *);
172 static void set_qc_frcassgn_net(struct expr_t *);
173 static int32 nd_qcreg(struct expr_t *);
174 static void chk_circular_qc_stmt(struct st_t *);
175 static int32 rhs_expr_has_net(struct expr_t *, struct net_t *);
176 static void chk_disable(struct st_t *);
177 static void reassign_itnums(void);
178 
179 /* extern prototypes (maybe defined in this module) */
180 extern char *__my_malloc(int32);
181 extern char *__my_realloc(char *, int32 , int32);
182 extern char *__to_wtnam(char *, struct net_t *);
183 extern char *__to_ptnam(char *, word32);
184 extern char *__to_sytyp(char *, word32);
185 extern char *__to_sttyp(char *, word32);
186 extern char *__to_qctyp(char *, word32);
187 extern char *__to_idnam(struct expr_t *);
188 extern char *__to_mpnam(char *, char *);
189 extern char *__msgexpr_tostr(char *, struct expr_t *);
190 extern char *__msgnumexpr_tostr(char *, struct expr_t *, int32);
191 extern struct expr_t *__copy_expr(struct expr_t *);
192 extern struct xstk_t *__eval2_xpr(struct expr_t *);
193 extern char *__pregab_tostr(char *, word32 *, word32 *, struct net_t *);
194 extern char *__msg2_blditree(char *, struct itree_t *);
195 extern char *__bld_lineloc(char *, word32, int32);
196 extern struct sy_t *__get_sym(char *, struct symtab_t *);
197 extern struct expr_t *__alloc_newxnd(void);
198 extern struct expr_t *__bld_rng_numxpr(word32, word32, int32);
199 extern struct paramlst_t *__copy_dellst(struct paramlst_t *);
200 extern void __set_poundparams(void);
201 extern void __set_1inst_pound_params(struct itree_t *, int32);
202 extern void __free_1dfparam(struct dfparam_t *);
203 extern struct itree_t *__find_dfpbot_itp(struct dfparam_t *);
204 extern int32 __ip_indsrch(char *);
205 extern void __my_free(char *, int32);
206 extern void __mark_widdet_params(struct mod_t *);
207 extern void __do_mdsplit(struct mod_t *);
208 extern void __dmp_itree(struct itree_t *);
209 extern void __sizchgxs(struct xstk_t *, int32);
210 extern void __narrow_sizchg(register struct xstk_t *, int32);
211 extern void __sizchg_widen(register struct xstk_t *, int32);
212 extern void __sgn_xtnd_widen(struct xstk_t *, int32);
213 extern void __grow_xstk(void);
214 extern void __chg_xstk_width(struct xstk_t *, int32);
215 extern int32 __wide_vval_is0(register word32 *, int32);
216 extern void __in_xpr_markparam(struct expr_t *);
217 extern int32 __chk_delparams(struct paramlst_t *, char *, int32);
218 extern void __free_dellst(struct paramlst_t *);
219 extern void __bld_mlevel_lists(void);
220 extern int32 __get_netwide(struct net_t *);
221 extern int32 __chk_rhsexpr(struct expr_t *, int32);
222 extern int32 __chk_numdelay(struct expr_t *, char *);
223 extern void __free_xtree(struct expr_t *);
224 extern void __free2_xtree(struct expr_t *);
225 extern void __init_xnd(struct expr_t *);
226 extern int32 __get_arrwide(struct net_t *);
227 extern int32 __nd_ndxnum(struct expr_t *, char *, int32);
228 extern int32 __chk_lhsexpr(struct expr_t *, int32);
229 extern void __set_expr_onrhs(struct expr_t *);
230 extern void __chk_lstofsts(struct st_t *);
231 extern struct expr_t *__widen_unsiz_rhs_assign(struct expr_t *, int);
232 extern struct expr_t *__get_lvalue_idndp(struct expr_t *);
233 extern void __chk_nodel_lstofsts(struct st_t *);
234 extern int32 __isleaf(struct expr_t *);
235 extern void __getwir_range(struct net_t *, int32 *, int32 *);
236 extern int32 __unnormalize_ndx(struct net_t *, int32);
237 extern int32 __chk_lhsdecl_scalared(struct expr_t *);
238 extern void __push_nbstk(struct st_t *);
239 extern void __pop_nbstk(void);
240 extern int32 __is_upward_dsable_syp(struct sy_t *, struct symtab_t *, int32 *);
241 extern void __chk_tskenable(struct st_t *);
242 extern void __set_lhswidth(struct expr_t *);
243 extern int32 __get_rhswidth(struct expr_t *);
244 extern void __chk_evxpr(struct expr_t *);
245 extern int32 __xhas_reg(struct expr_t *);
246 extern int32 __get_giarr_wide(struct giarr_t *giap);
247 extern void __rhspsel(register word32 *, register word32 *, register int32,
248  register int32);
249 extern int32 __chkndx_expr(struct expr_t *, char *);
250 extern int32 __expr_has_glb(struct expr_t *);
251 extern void __bld_unc_expr(void);
252 extern struct exprlst_t *__alloc_xprlst(void);
253 extern void __chk_1mdecls(void);
254 extern void __cnv_stk_fromreg_toreal(struct xstk_t *, int32);
255 extern void __cnv_stk_fromreal_toreg32(struct xstk_t *);
256 extern void __cnvt_param_stkval(struct xstk_t *, struct expr_t *,
257  struct net_t *, char *);
258 extern void __set_drvr_bits(void);
259 extern void __chk_chg_port_dir(int32);
260 extern void __assgn_nonis_param(struct net_t *, struct expr_t *,
261  struct xstk_t *);
262 extern void __chg_param_tois(struct net_t *, struct mod_t *);
263 extern int32 __alloc_is_cval(int32);
264 extern int32 __allocfill_cval_new(word32 *, word32 *, int32);
265 extern int32 __alloc_shareable_cval(word32, word32, int32);
266 extern int32 __alloc_shareable_rlcval(double);
267 extern void __push_wrkitstk(struct mod_t *, int32);
268 extern void __pop_wrkitstk(void);
269 extern int32 __is_const_expr(struct expr_t *);
270 extern int32 __xpr_has_param(struct expr_t *);
271 extern void __bld_flat_itree(void);
272 extern void __free_flat_itree(void);
273 extern int32 __cmp_xpr(struct expr_t *, struct expr_t *);
274 extern int32 __chk_paramexpr(struct expr_t *, int32);
275 extern void __set_numval(struct expr_t *, word32, word32, int32);
276 
277 extern void __cv_msg(char *, ...);
278 extern void __gfwarn(int32, word32, int32, char *, ...);
279 extern void __sgfwarn(int32, char *, ...);
280 extern void __gfinform(int32, word32, int32, char *, ...);
281 extern void __gferr(int32, word32, int32, char *, ...);
282 extern void __sgferr(int32, char *, ...);
283 extern void __dbg_msg(char *, ...);
284 extern void __sgfinform(int32, char *, ...);
285 extern void __sgfterr(int32, char *, ...);
286 extern void __pv_terr(int32, char *, ...);
287 extern void __arg_terr(char *, int32);
288 extern void __case_terr(char *, int32);
289 extern void __misc_terr(char *, int32);
290 extern void __misc_sgfterr(char *, int32);
291 extern void __misc_gfterr(char *, int32, word32, int32);
292 
293 extern word32 __masktab[];
294 
295 /*
296  * ROUTINES TO SAVE INITIAL SOURCE FOR PLI USE
297  */
298 
299 /*
300  * ROUTINES TO PROCESS XMR TYPE DEFPARAMS
301  */
302 
303 /*
304  * use all defparams in current module to change local param init values
305  * in other modules
306  * notice all defparams used to set module init values before values
307  * used in code
308  *
309  * notice defparams are not module items but parameters can be used on
310  * lvalues and defparams allowed in tasks where they can only
311  * be set with global ref. defparams
312  */
__process_defparams(void)313 extern void __process_defparams(void)
314 {
315  struct dfparam_t *dfpp;
316 
317  /* convert all downward relative defparams to rooted */
318  /* linked on by root nxt - even if 1 will be on root nxt */
319  bld_root_dfpglbs();
320 
321  /* handle splitting of all defparams */
322  do_defparam_splitting();
323  /* by here arrays of instances have been converted into normal instances */
324  if (__pndparam_splits || __defparam_splits) reset_dfp_targsyps();
325 
326  /* go through flat itree and reset all instance numbers */
327  reassign_itnums();
328 
329  /* SJM 03/16/04 - rebuild the levelized static (src contents) if any */
330  /* defparam spliting - if only pound param splitting still good */
331  /* this is not strictly needed now but will be for future generate */
332  if (__defparam_splits) __bld_mlevel_lists();
333 
334  /* set pound params if needed */
335  if (__num_inst_pndparams > 0) __set_poundparams();
336 
337  /* fixup new target syps and mdps if needed and set defparams */
338  /* this must be in exact source order including in root or local */
339  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
340   set_1defparam(dfpp);
341 }
342 
343 /*
344  * ROUTINES TO CONVERT ALL DOWNWARD DEFPARAMS TO ROOTED
345  */
346 
347 /*
348  * convert defparam lhs non rooted globals to right number of rooted
349  * links off non rooted and build 1 design wide list
350  *
351  * know will be at least one defparam or will not be called
352  * after here all design wide defparams in one list
353  * module mdfps unused after here
354  */
bld_root_dfpglbs(void)355 static void bld_root_dfpglbs(void)
356 {
357  register int32 ii;
358  register struct dfparam_t *dfpp, *dfpp2;
359  int32 num_defparams, num_locdefparams;
360  struct dfparam_t *last_dfpp, *dfpp3, **dfpptab;
361  struct mod_t *dfpmdp;
362 
363  /* go through list of 1 inst. corresponding to each top level module */
364  /* this also sets itree place to eval. rhs in */
365  for (ii = 0; ii < __numtopm; ii++) bld_root2_dfpglbs(__it_roots[ii], 1);
366 
367  /* convert to design wide linear defparam list */
368  last_dfpp = NULL;
369  num_defparams = num_locdefparams = 0;
370  for (dfpmdp = __modhdr; dfpmdp != NULL; dfpmdp = dfpmdp->mnxt)
371   {
372    for (dfpp = dfpmdp->mdfps; dfpp != NULL;)
373     {
374      if (dfpp->dfp_local || dfpp->dfp_rooted)
375       {
376        if (last_dfpp == NULL) __dfphdr = dfpp;
377        else last_dfpp->dfpnxt = dfpp;
378        last_dfpp = dfpp;
379        num_defparams++;
380        if (dfpp->dfp_local) num_locdefparams++;
381        dfpp = dfpp->dfpnxt;
382        continue;
383       }
384      dfpp2 = dfpp->rooted_dfps;
385      for (; dfpp2 != NULL; dfpp2 = dfpp2->rooted_dfps)
386       {
387        if (last_dfpp == NULL) __dfphdr = dfpp2;
388        else last_dfpp->dfpnxt = dfpp2;
389        last_dfpp = dfpp2;
390        num_defparams++;
391       }
392      dfpp3 = dfpp->dfpnxt;
393      /* finally free unrooted that has been replaced by rooted */
394      __free_1dfparam(dfpp);
395      dfpp = dfpp3;
396     }
397    /* SJM 02/18/01 - since freed need to set to nil to prevent copying */
398    /* when modules split - defparams are copied for giarr splitting */
399    dfpmdp->mdfps = NULL;
400   }
401  if (last_dfpp != NULL) last_dfpp->dfpnxt = NULL;
402 
403  /* sort global defparams by location since last must override */
404  /* know there will always be a least one defparam here */
405  dfpptab = (struct dfparam_t **)
406   __my_malloc(num_defparams*sizeof(struct dfparam_t *));
407  for (ii = 0, dfpp = __dfphdr; ii < num_defparams; ii++, dfpp = dfpp->dfpnxt)
408   dfpptab[ii] = dfpp;
409  qsort((char *) dfpptab, num_defparams, sizeof(struct dfparam_t *),
410   dfploc_cmp);
411  __dfphdr = dfpptab[0];
412  dfpp3 = __dfphdr;
413  for (ii = 1; ii < num_defparams; ii++)
414   {
415    dfpp3->dfpnxt = dfpptab[ii];
416    dfpp3 = dfpp3->dfpnxt;
417   }
418  dfpp3->dfpnxt = NULL;
419  /* design wide rooted (or local) def param list now ordered */
420  __my_free((char *) dfpptab, num_defparams*sizeof(struct dfparam_t *));
421 
422  /* SJM 06/04/05 - nil the rooted dfps field since no longer needed */
423  /* could leave but nil makes debugging easier */
424  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
425   dfpp->rooted_dfps = NULL;
426 
427  /* only find identicals if at least one non local */
428  if (num_defparams - num_locdefparams != 0)
429   {
430    bld_identdfparams(num_defparams - num_locdefparams);
431    find_mustsplit_dfps();
432   }
433  if (__debug_flg) dmp_dfps(TRUE, TRUE);
434 }
435 
dfploc_cmp(const void * dfpp1,const void * dfpp2)436 static int32 dfploc_cmp(const void *dfpp1, const void *dfpp2)
437 {
438  int32 cv;
439 
440  cv = (*((struct dfparam_t **) dfpp1))->dfpfnam_ind
441   - (*((struct dfparam_t **) dfpp2))->dfpfnam_ind;
442  if (cv != 0) return(cv);
443  return((*((struct dfparam_t **) dfpp1))->dfplin_cnt
444   - (*((struct dfparam_t **) dfpp2))->dfplin_cnt);
445 }
446 
447 /*
448  * dump defparam list
449  * only called if debugging on
450  *
451  * SJM 05/25/05 - rewrote to work with converted to rooted dfps
452  */
dmp_dfps(int32 emit_pth,int32 now_rted)453 static void dmp_dfps(int32 emit_pth, int32 now_rted)
454 {
455  struct dfparam_t *dfpp;
456  register int32 dfi, ii;
457  char identtyp;
458  struct inst_t *ip;
459 
460  __dbg_msg("$$$ Dumping all design defparams $$$\n");
461  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
462   {
463    if (dfpp->dfp_has_idents)
464     { if (dfpp->idntmastdfp == NULL) identtyp = 'M'; else identtyp = 'Y'; }
465    else identtyp = 'N';
466    __dbg_msg("==> defparam %s in %s at %s loc.=%u rooted=%u identical=%c\n",
467     dfpp->gdfpnam, dfpp->in_mdp->msym->synam,
468    __bld_lineloc(__xs, dfpp->dfpfnam_ind, dfpp->dfplin_cnt),
469     dfpp->dfp_local, dfpp->dfp_rooted, identtyp);
470 
471    /* will not have component since accessed from master */
472    if (dfpp->idntmastdfp != NULL || !emit_pth || dfpp->dfp_local) continue;
473 
474    /* here must still allocate dfpiis */
475    /* if root in module that is multiply instantiated must see table */
476    /* only once and rule is last source order is right instance to eval in */
477    ii = dfpp->dfpiis[0];
478    if (dfpp->dfp_rooted || now_rted) ip = __top_itab[ii];
479    else ip = &(dfpp->in_mdp->minsts[ii]);
480    for (dfi = 0; dfi <= dfpp->last_dfpi; dfi++)
481     {
482      sprintf(__xs, " (inst type %s)", ip->imsym->synam);
483      __dbg_msg("   component %s%s index %d\n", __xs, ip->isym->synam, ii);
484 
485      ii = dfpp->dfpiis[dfi + 1];
486      if (dfi < dfpp->last_dfpi) ip = &(ip->imsym->el.emdp->minsts[ii]);
487     }
488    __dbg_msg("\n");
489   }
490  __dbg_msg("$$$ end of defparms $$$\n");
491 }
492 
493 /*
494  * dump all param expressions
495  */
__dmp_all_param_exprs(void)496 extern void __dmp_all_param_exprs(void)
497 {
498  register int32 pi, ii;
499  register struct mod_t *mdp;
500  register struct net_t *np;
501  int32 wlen;
502  word32 *wp;
503 
504  __dbg_msg("*** dumping all params ***\n");
505  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
506   {
507    for (pi = 0; pi < mdp->mprmnum; pi++)
508     {
509      np = &(mdp->mprms[pi]);
510      wlen = wlen_(np->nwid);
511 
512      /* parameter has IS form, eval rhs from itree place and set num */
513      if (np->srep == SR_PISNUM)
514       {
515        for (ii = 0; ii < mdp->flatinum; ii++)
516         {
517          wp = &(np->nva.wp[2*ii*wlen]);
518          __dbg_msg("module %s param %s value %s\n", mdp->msym->synam,
519           np->nsym->synam, __pregab_tostr(__xs, wp, &(wp[wlen]), np));
520         }
521       }
522      else if (np->srep == SR_PNUM)
523       {
524        wp = np->nva.wp;
525        __dbg_msg("module %s param %s rhs expr. %s\n", mdp->msym->synam,
526         np->nsym->synam, __pregab_tostr(__xs, wp, &(wp[wlen]), np));
527       }
528      else __case_terr(__FILE__, __LINE__);
529      if (np->nrngrep != NX_CT) __misc_terr(__FILE__, __LINE__);
530      if (np->n_isarr)
531       {
532        __dbg_msg("  array range [%s:%s]", __msgexpr_tostr(__xs,
533         np->nu.ct->nx1), __msgexpr_tostr(__xs2, np->nu.ct->nx2));
534       }
535      else __dbg_msg(" ");
536      if (np->n_isavec)
537       {
538        __dbg_msg(" range [%s:%s]\n", __msgexpr_tostr(__xs, np->nu.ct->nx1),
539         __msgexpr_tostr(__xs2, np->nu.ct->nx2));
540       }
541      else __dbg_msg("\n");
542     }
543   }
544  __dbg_msg("*** end of dump ***\n");
545 }
546 
547 /*
548  * under each top module's convert defparam lhs global to rooted form
549  * uses extra storage but reclaimed after defparams substituted
550  *
551  * this just updates dfpiis for downward relative
552  * downward relative symbols in top module are not rooted but can never
553  * be in list
554  */
bld_root2_dfpglbs(struct itree_t * itp,int32 level)555 static void bld_root2_dfpglbs(struct itree_t *itp, int32 level)
556 {
557  register struct dfparam_t *dfpp;
558  struct dfparam_t *new_dfpp;
559  int32 i, ii, rtlen, *newiis;
560  byte *bp1, *bp2;
561  struct mod_t *imdp;
562  struct itree_t *tmpitp, *upitp;
563 
564  if (level >= MAXGLBCOMPS)
565   {
566 too_deep:
567    __pv_terr(310,
568     "downward defparam hierarchical path has too many components (%d)",
569     MAXGLBCOMPS);
570   }
571  imdp = itp->itip->imsym->el.emdp;
572  /* --- */
573  if (__debug_flg)
574   {
575    __dbg_msg("==> building defparam globals in inst. %s type %s\n",
576     itp->itip->isym->synam, imdp->msym->synam);
577   }
578  /* --- */
579 
580  /* convert unrooted to defparam rooted */
581  /* even if only one inst. of this need rooted form */
582  for (dfpp = imdp->mdfps; dfpp != NULL; dfpp = dfpp->dfpnxt)
583   {
584    /* SJM 05/26/05 - can't use indfp itp for dfps because splitting changes */
585    if (dfpp->dfp_local)
586     {
587      /* local defparams - NULL means in all instances - for dependent */
588      /* if rhs defparam is IS form must convert local value to IS form */
589      continue;
590     }
591 
592    /* if root in module that is multiply instantiated must see table */
593    /* only once and rule is last source order is right instance to eval in */
594    if (dfpp->dfp_rooted)
595     {
596      /* if rooted appears in multiply instantiated, possible that rhs */
597      /* expr. can contain IS form so that same target rooted defparam lhs */
598      /* gets assigned to once for each - using last one since arbitrary */
599      continue;
600     }
601    rtlen = level + dfpp->last_dfpi + 1;
602    if (rtlen >= MAXGLBCOMPS) goto too_deep;
603    newiis = (int32 *) __my_malloc(rtlen*sizeof(int32));
604    /* fill the new prefix - need instance symbol except module at top */
605    /* this is downward relative in top level */
606    tmpitp = itp;
607    for (i = level; i > 0; i--)
608     {
609      if (tmpitp->up_it == NULL)
610       {
611        ii = __ip_indsrch(tmpitp->itip->imsym->synam);
612        /* DBG remove -- */
613        if (ii == -1) __misc_terr(__FILE__, __LINE__);
614        if (i != 1) __misc_terr(__FILE__, __LINE__);
615        /* --- */
616        newiis[i - 1] = ii;
617        continue;
618       }
619      upitp = tmpitp->up_it;
620      bp1 = (byte *) tmpitp->itip;
621      bp2 = (byte *) upitp->itip->imsym->el.emdp->minsts;
622      ii = (bp1 - bp2)/sizeof(struct inst_t);
623      newiis[i - 1] = ii;
624      tmpitp = upitp;
625     }
626    /* finish by copying rest of path */
627    __last_gsc = level;
628    for (i = 0; i <= dfpp->last_dfpi; __last_gsc++, i++)
629     newiis[__last_gsc] = dfpp->dfpiis[i];
630 
631    /* if module has only 1 flattened instance just replace dfcmps */
632    /* notice tail param targsyp same for each */
633    if (imdp->flatinum == 1)
634     {
635      __my_free((char *) dfpp->dfpiis, (dfpp->last_dfpi + 1)*sizeof(int32));
636      dfpp->dfpiis = newiis;
637      dfpp->last_dfpi = __last_gsc - 1;
638      dfpp->dfp_rooted = TRUE;
639      continue;
640     }
641    new_dfpp = (struct dfparam_t *) __my_malloc(sizeof(struct dfparam_t));
642    *new_dfpp = *dfpp;
643    /* need to copy expressions here, since at least free requires sep. */
644    new_dfpp->dfpxlhs = __copy_expr(dfpp->dfpxlhs);
645    new_dfpp->dfpxrhs = __copy_expr(dfpp->dfpxrhs);
646    /* notice tail is pointed to by targsyp (not in cmps) */
647    new_dfpp->dfpiis = newiis;
648    new_dfpp->last_dfpi = __last_gsc - 1;
649 
650    /* put on front */
651    new_dfpp->rooted_dfps = dfpp->rooted_dfps;
652    dfpp->rooted_dfps = new_dfpp;
653    /* downward relative stem freed when new rooted copied to design list */
654   }
655  /* process 1 down depth first */
656  for (ii = 0; ii < imdp->minum; ii++)
657   bld_root2_dfpglbs(&(itp->in_its[ii]), level + 1);
658 }
659 
660 /*
661  * build the list of defparams independent of source module that have
662  * identical target module - goes through all defparams and connect
663  * those with identical target module
664  *
665  * this order identical path maybe same or maybe different defparams
666  * in source order so same will always use last source order
667  */
bld_identdfparams(int32 nrtdfps)668 static void bld_identdfparams(int32 nrtdfps)
669 {
670  register int32 dfi, dfi2;
671  register struct dfparam_t *dfpp1, *dfpp2;
672  struct dfparam_t *mastdfp, *dfpend, **dfppndx;
673 
674  /* build and sort index - ordered so all same rooted paths contingous */
675  /* within same paths ordered by source order */
676  dfppndx = (struct dfparam_t **)
677   __my_malloc(nrtdfps*sizeof(struct dfparam_t *));
678  for (dfi = -1, dfpp1 = __dfphdr; dfpp1 != NULL; dfpp1 = dfpp1->dfpnxt)
679   {
680    if (!dfpp1->dfp_local) dfppndx[++dfi] = dfpp1;
681   }
682  qsort((char *) dfppndx, nrtdfps, sizeof(struct dfparam_t *), ipth_cmp);
683 
684  for (dfi = 0; dfi < nrtdfps;)
685   {
686    dfpp1 = dfppndx[dfi];
687    /* because of sorting - never see one already in equivalence class */
688    /* DBG remove -- */
689    if (dfpp1->dfp_has_idents) __misc_terr(__FILE__, __LINE__);
690    /* --- */
691    if ((dfi2 = dfi + 1) >= nrtdfps) break;
692    dfpp2 = dfppndx[dfi2];
693    /* DBG remove -- */
694    if (dfpp2->dfp_has_idents) __misc_terr(__FILE__, __LINE__);
695    /* --- */
696    if (ipth2_cmp(dfpp1, dfpp2) != 0) { dfi++; continue; }
697 
698    /* know at least 2 equivalent - first is master */
699    mastdfp = dfpend = dfpp1;
700    dfpp1->idntmastdfp = NULL;
701    dfpp1->dfp_has_idents = TRUE;
702    for (;;)
703     {
704      /* DBG remove -- */
705      if (dfpp2->dfp_has_idents) __misc_terr(__FILE__, __LINE__);
706      /* --- */
707 
708      /* mark has ident and link on front of current work list */
709      dfpp2->dfp_has_idents = TRUE;
710      dfpp2->idntmastdfp = mastdfp;
711      dfpend->idntnxt = dfpp2;
712      dfpend = dfpp2;
713      /* DBG remove --- */
714      if (__debug_flg)
715       {
716        __dbg_msg("defparam %s in %s at %s same target inst. as %s at %s\n",
717         dfpp2->gdfpnam, dfpp2->in_mdp->msym->synam,
718         __bld_lineloc(__xs, dfpp2->dfpfnam_ind, dfpp2->dfplin_cnt),
719         mastdfp->gdfpnam, __bld_lineloc(__xs2, mastdfp->dfpfnam_ind,
720         mastdfp->dfplin_cnt));
721       }
722      /* --- */
723      if (++dfi2 >= nrtdfps) break;
724      dfpp2 = dfppndx[dfi2];
725      /* if not in current equiv. class, may start next one */
726      if (ipth2_cmp(dfpp1, dfpp2) != 0) break;
727     }
728    dfpend->idntnxt = NULL;
729    dfi = dfi2;
730   }
731  __my_free((char *) dfppndx, nrtdfps*sizeof(struct dfparam_t *));
732 }
733 
734 /*
735  * wrapper for sorting defparams - if same order by source loc.
736  */
ipth_cmp(const void * dfpp1p,const void * dfpp2p)737 static int32 ipth_cmp(const void *dfpp1p, const void *dfpp2p)
738 {
739  register int32 cv;
740  register struct dfparam_t *dfpp1, *dfpp2;
741 
742  dfpp1 = *((struct dfparam_t **) dfpp1p);
743  dfpp2 = *((struct dfparam_t **) dfpp2p);
744 
745  if ((cv = ipth2_cmp(dfpp1, dfpp2)) != 0) return(cv);
746 
747  /* if same, need source location order */
748  cv = dfpp1->dfpfnam_ind - dfpp2->dfpfnam_ind;
749  if (cv != 0) return(cv);
750  cv = (dfpp1->dfplin_cnt - dfpp2->dfplin_cnt);
751  if (cv != 0) return(cv);
752  return(0);
753 }
754 
755 /*
756  * compare 2 defparam records (use address for order)
757  */
ipth2_cmp(register struct dfparam_t * dfpp1,register struct dfparam_t * dfpp2)758 static int32 ipth2_cmp(register struct dfparam_t *dfpp1,
759  register struct dfparam_t *dfpp2)
760 {
761  register int32 ii;
762  register struct sy_t *sy1, *sy2;
763  int32 atend1, atend2;
764  struct itree_t *itp1, *itp2;
765 
766  itp1 = __it_roots[dfpp1->dfpiis[0]];
767  itp2 = __it_roots[dfpp2->dfpiis[0]];
768  for (ii = 0;;)
769   {
770    /* DBG remove --
771    if (itp1->itip == NULL || itp2->itip == NULL)
772     __misc_terr(__FILE__, __LINE__);
773    --- */
774    sy1 = itp1->itip->isym;
775    sy2 = itp2->itip->isym;
776    /* SJM 06/03/02 - cast to int32 and minus not 64 bit portable */
777    if (sy1 != sy2)
778     {
779      if (sy1 > sy2) return(1);
780      return(-1);
781     }
782    ii++;
783    atend1 = (ii > dfpp1->last_dfpi);
784    atend2 = (ii > dfpp2->last_dfpi);
785    if (!atend1 && !atend2)
786     {
787      itp1 = &(itp1->in_its[dfpp1->dfpiis[ii]]);
788      itp2 = &(itp2->in_its[dfpp2->dfpiis[ii]]);
789      continue;
790     }
791    /* if both past end - done (know same length) */
792    if (atend1 && atend2) break;
793    /* know one but not other past end - done with shortest first */
794    if (atend1) return(-1);
795    return(1);
796   }
797  return(0);
798 }
799 
800 /*
801  * mark wires that can effect target module expression widths in
802  * target module and if defparam contains mark as must split
803  * if not marked, then can use IS form
804  */
find_mustsplit_dfps(void)805 static void find_mustsplit_dfps(void)
806 {
807  register struct dfparam_t *dfpp, *dfpp2;
808  struct mod_t *imdp;
809  struct net_t *np;
810  struct itree_t *bot_itp;
811 
812  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
813   {
814    /* only look at non local master's from identicals here */
815    if (dfpp->dfp_local || dfpp->idntmastdfp != NULL) continue;
816 
817    bot_itp = __find_dfpbot_itp(dfpp);
818    imdp = bot_itp->itip->imsym->el.emdp;
819    /* if only 1 inst. no need to split */
820    if (imdp->flatinum == 1) continue;
821 
822    /* if target module does not have expr. width params set, do it now */
823    if (!imdp->mwiddetdone)
824     {
825      /* width marking must be done with module context */
826      __push_wrkitstk(imdp, 0);
827      __mark_widdet_params(imdp);
828      __pop_wrkitstk();
829      imdp->mwiddetdone = TRUE;
830     }
831 
832    /* if any of list with identical target width determining must split */
833    /* identical target means identical module type */
834    /* dfpp included in ident list */
835    if (dfpp->dfp_has_idents)
836     {
837      for (dfpp2 = dfpp; dfpp2 != NULL; dfpp2 = dfpp2->idntnxt)
838       {
839        np = dfpp2->targsyp->el.enp;
840        if (np->nu.ct->n_widthdet)
841         {
842          /* DBG remove --- */
843          if (__debug_flg)
844           {
845            __dbg_msg(
846 	    "+++ mark module %s to split defparam %s (mast of equiv class) width determining.\n",
847             imdp->msym->synam, np->nsym->synam);
848           }
849          /* --- */
850          /* SJM 03/21/04 - because all are in same destination inst */
851          /* equivalence class, once know that the master split can stop */
852          dfpp->dfp_mustsplit = TRUE;
853         }
854       }
855     }
856    else
857     {
858      np = dfpp->targsyp->el.enp;
859      if (np->nu.ct->n_widthdet)
860       {
861        /* DBG remove --- */
862        if (__debug_flg)
863         {
864          __dbg_msg(
865           "+++ mark module %s to split since defparam %s width determining.\n",
866           imdp->msym->synam, np->nsym->synam);
867         }
868        /* --- */
869        dfpp->dfp_mustsplit = TRUE;
870        /* AIV 02/04/04 - was wrongly breaking so did not process all defps */
871       }
872     }
873   }
874 }
875 
876 /*
877  * find bottom defparam itree loc.
878  */
__find_dfpbot_itp(struct dfparam_t * dfpp)879 extern struct itree_t *__find_dfpbot_itp(struct dfparam_t *dfpp)
880 {
881  register int32 dfi, ii;
882  register struct itree_t *bot_itp, *itp;
883 
884  ii = dfpp->dfpiis[0];
885  bot_itp = __it_roots[ii];
886  /* may not go through this loop if in top */
887  for (dfi = 1; dfi <= dfpp->last_dfpi; dfi++)
888   { ii = dfpp->dfpiis[dfi]; itp = &(bot_itp->in_its[ii]); bot_itp = itp; }
889  return(bot_itp);
890 }
891 
892 /*
893  * ROUTINES TO SPLIT MODULES AND UNWIND DEFPARAMS
894  */
895 
896 /*
897  * do all defparam splitting off
898  * since all rooted just descend from root in itree change itree imsym
899  * types and copy modules where needed
900  */
do_defparam_splitting(void)901 static void do_defparam_splitting(void)
902 {
903  register int32 ii2, dfi;
904  int32 ii, last_split;
905  struct dfparam_t *dfpp;
906  struct inst_t *ip;
907  struct itree_t *itp, *up_itp;
908  struct mod_t *orig_imdp, *imdp, *down_inst_mod;
909 
910  __defparam_splits = FALSE;
911  last_split = FALSE;
912  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
913   {
914    /* if has identical (i.e. more than one param in same inst set), */
915    /* then build path for 1 and at end copy same path for all idents */
916    if (dfpp->dfp_local || dfpp->idntmastdfp != NULL) continue;
917 
918    /* SJM 03/23/04 - if needed to split must rebuild itree because */
919    /* need to renumber the split off ones and the ones split from */
920    if (last_split)
921     {
922      __free_flat_itree();
923      __bld_flat_itree();
924      last_split = FALSE;
925     }
926 
927    /* first split module containing defparam target if needed */
928    dfi = dfpp->last_dfpi;
929    itp = __find_dfpbot_itp(dfpp);
930    ip = itp->itip;
931    imdp = ip->imsym->el.emdp;
932 
933    if (imdp->flatinum == 1)
934     {
935      /* DBG remove --- */
936      if (__debug_flg)
937       {
938        __dbg_msg("-- defparam %s mod %s not split - only 1 instance\n",
939         dfpp->gdfpnam, imdp->msym->synam);
940       }
941      /* --- */
942      continue;
943     }
944 
945    /* if can just change to IS expr. form, do not split */
946    if (!dfpp->dfp_mustsplit)
947     {
948      /* DBG remove --- */
949      if (__debug_flg)
950       {
951        __dbg_msg(
952         "-- defparam %s mod %s not split - can change param to inst. form\n",
953         dfpp->gdfpnam, imdp->msym->synam);
954       }
955      /* --- */
956      continue;
957     }
958 
959    /* always split off master (original) if needed */
960    if (imdp->mspltmst != NULL)
961     {
962      __gfwarn(535, dfpp->dfpfnam_ind, dfpp->dfplin_cnt,
963       "INTERNAL - bottom of tree module of type \"%s\" should not have master %s",
964       imdp->msym->synam, imdp->mspltmst->msym->synam);
965      orig_imdp = imdp->mspltmst;
966     }
967    else orig_imdp = imdp;
968 
969    /* DBG remove ---
970    if (__debug_flg)
971     {
972      __dbg_msg("==> before split of bottom mod %s and before split up\n",
973       orig_imdp->msym->synam);
974      __dmp_itree(__it_roots[0]);
975     }
976    --- */
977 
978    /* notice this set __inst_mod to new split off - each defaparam has */
979    /* own in module so this use of __inst_mod does not require saving */
980    /* LOOKATME - should not set __inst_mod inside but return value here */
981    __do_mdsplit(orig_imdp);
982    __defparam_splits = TRUE;
983    last_split = TRUE;
984 
985    /* DBG remove ---
986    if (__debug_flg)
987     {
988      __dbg_msg("==> after split but before split up without adjust to %s\n",
989       __inst_mod->msym->synam);
990      __dmp_itree(__it_roots[0]);
991     }
992    --- */
993 
994    /* DBG remove --- */
995    if (__debug_flg)
996     {
997      __dbg_msg("-- split defparam(s) %s type %s to %s target symbol %s.\n",
998       dfpp->gdfpnam, orig_imdp->msym->synam, __inst_mod->msym->synam,
999       dfpp->targsyp->synam);
1000     }
1001    /* --- */
1002    /* do not need to update non master defparam since will never see */
1003 
1004    up_itp = itp->up_it;
1005 try_split_up:
1006    /* notice that level i, ii is index in one up itree in_its */
1007    ii = dfpp->dfpiis[dfi];
1008    /* move 1 level up tree */
1009    dfi--;
1010    itp = up_itp;
1011    imdp = itp->itip->imsym->el.emdp;
1012    up_itp = up_itp->up_it;
1013    /* previous copied module */
1014    down_inst_mod = __inst_mod;
1015 
1016     /* DBG remove ---
1017     if (__debug_flg)
1018      {
1019       __dbg_msg("==> at beginning of try split up\n");
1020       __dmp_itree(__it_roots[0]);
1021      }
1022     --- */
1023 
1024    /* either fix 1 itree level above module type or split if needed */
1025 
1026    /* rule 1: if 1 up itree place inst_t module type has 1 flat inst, */
1027    /* just change imsym */
1028    /* top modules will always cause rule 1 termination */
1029    /* if already split off (common), know exactly one inst., do not split */
1030    if (imdp->flatinum == 1)
1031     {
1032      (imdp->minsts[ii]).imsym = down_inst_mod->msym;
1033 
1034      /* DBG remove --- */
1035      if (__debug_flg)
1036       {
1037        __dbg_msg("-- defparam %s module %s needs split but has 1 inst.\n",
1038 	dfpp->gdfpnam, imdp->msym->synam);
1039       }
1040      /* --- */
1041      continue;
1042     }
1043 
1044    /* rule 2: if module flatinum > 1, has contained inst_t split off */
1045    /* must copy module and work up tree */
1046    if (imdp->mspltmst != NULL) orig_imdp = imdp->mspltmst;
1047    else orig_imdp = imdp;
1048    /* notice here __inst_mod changed to newly split off, so works */
1049    /* but use of __inst mod makes code hard to follow */
1050    __do_mdsplit(orig_imdp);
1051 
1052    /* DBG remove ---
1053    if (__debug_flg)
1054     {
1055      __dbg_msg("==> after split - before itree fix up\n");
1056      __dmp_itree(__it_roots[0]);
1057     }
1058    --- */
1059 
1060    /* inside split off mod always change instances down module type */
1061    (__inst_mod->minsts[ii]).imsym = down_inst_mod->msym;
1062 
1063    /* since entire insts list in __inst_mod copy of list in original mod */
1064    /* each itip inside non leaf top module must be changed to address of */
1065    /* inst in split of __inst_mod */
1066    /* notice must update because other defparams may descend through here */
1067    for (ii2 = 0; ii2 < __inst_mod->minum; ii2++)
1068     (itp->in_its[ii2]).itip = &(__inst_mod->minsts[ii2]);
1069 
1070    /* --- DBG remove
1071    if (__debug_flg)
1072     {
1073      __dbg_msg("==> after split - after itree fix up\n");
1074      __dmp_itree(__it_roots[0]);
1075     }
1076    --- */
1077 
1078    /* DBG remove --- */
1079    if (__debug_flg)
1080     {
1081      __dbg_msg("-- defparam %s needing split mod %s split to %s\n",
1082       dfpp->gdfpnam, orig_imdp->msym->synam, __inst_mod->msym->synam);
1083     }
1084    /* --- */
1085    goto try_split_up;
1086   }
1087 
1088  /* SJM 03/23/04 - if last one needed to split must rebuild itree here */
1089  if (last_split)
1090   {
1091    __free_flat_itree();
1092    __bld_flat_itree();
1093   }
1094  /* DBG remove --- */
1095  if (__debug_flg)
1096   { for (ii2 = 0; ii2 < __numtopm; ii2++) __dmp_itree(__it_roots[ii2]); }
1097  /* --- */
1098 }
1099 
1100 /*
1101  * if any splitting must reset all target symbols
1102  * problem is that end instance of path may be split from other defparam
1103  */
reset_dfp_targsyps(void)1104 static void reset_dfp_targsyps(void)
1105 {
1106  register struct dfparam_t *dfpp, *dfpp2;
1107 
1108  for (dfpp = __dfphdr; dfpp != NULL; dfpp = dfpp->dfpnxt)
1109   {
1110    /* since local always copied and no xmr path no reset needed */
1111    if (dfpp->dfp_local || dfpp->idntmastdfp != NULL) continue;
1112 
1113    if (!dfpp->dfp_has_idents) { reset_1dfp_targsyp(dfpp); continue; }
1114 
1115    /* SJM 03/16/04 - LOOKATME - could just go through lists ignoring */
1116    /* idntmastdfp */
1117    /* master included on this list */
1118    for (dfpp2 = dfpp; dfpp2 != NULL; dfpp2 = dfpp2->idntnxt)
1119     reset_1dfp_targsyp(dfpp2);
1120   }
1121 }
1122 
1123 /*
1124  * in case splitting of target module (maybe from elsewhere)
1125  * reset target symbol
1126  */
reset_1dfp_targsyp(struct dfparam_t * dfpp)1127 static void reset_1dfp_targsyp(struct dfparam_t *dfpp)
1128 {
1129  register struct task_t *tskp;
1130  struct itree_t *itp;
1131  struct mod_t *mdp;
1132  struct sy_t *syp;
1133  char *chp;
1134 
1135  itp = __find_dfpbot_itp(dfpp);
1136  mdp = itp->itip->imsym->el.emdp;
1137  chp = dfpp->targsyp->synam;
1138  if (dfpp->dfptskp != NULL)
1139   {
1140    for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
1141     {
1142      if (strcmp(tskp->tsksyp->synam, dfpp->dfptskp->tsksyp->synam) == 0)
1143       goto have_task;
1144     }
1145    __arg_terr(__FILE__, __LINE__);
1146 
1147 have_task:
1148    if ((syp = __get_sym(chp, tskp->tsksymtab)) == NULL)
1149     __arg_terr(__FILE__, __LINE__);
1150    if (dfpp->targsyp != syp)
1151     {
1152      /* DBG remove -- */
1153      if (__debug_flg)
1154       {
1155        __dbg_msg(
1156         "++ for task defparam %s new bottom %s replacing %s with %s\n",
1157         dfpp->gdfpnam, __msg2_blditree(__xs, itp), dfpp->targsyp->synam,
1158         syp->synam);
1159       }
1160      /* ---*/
1161      dfpp->targsyp = syp;
1162      /* DBG remove --- */
1163      if (__debug_flg)
1164       {
1165        struct net_t *np;
1166 
1167        np = syp->el.enp;
1168        /* using first instance of original expression */
1169        __dbg_msg("-+- assigning params for %s in %s at %p - expr:%s\n",
1170         np->nsym->synam, mdp->msym->synam, np, __msgexpr_tostr(__xs,
1171         np->nu.ct->n_dels_u.d1x));
1172       }
1173      /* --- */
1174     }
1175    return;
1176   }
1177  /* DBG remove -- */
1178  if ((syp = __get_sym(chp, mdp->msymtab)) == NULL)
1179   __arg_terr(__FILE__, __LINE__);
1180  if (dfpp->targsyp != syp)
1181   {
1182    /* DBG remove -- */
1183    if (__debug_flg)
1184     {
1185      __dbg_msg("++ for defparam %s new bottom %s replacing %s with %s\n",
1186       dfpp->gdfpnam, __msg2_blditree(__xs, itp), dfpp->targsyp->synam,
1187       syp->synam);
1188     }
1189    /* ---*/
1190    dfpp->targsyp = syp;
1191   }
1192 }
1193 
1194 /*
1195  * ROUTINES TO BUILD AS IF FLATTENED INSTANCE TREE
1196  */
1197 
1198 /*
1199  * go through itree setting all inst fields to possible new split off value
1200  * split off module has same inst pointer (type different) but underneath
1201  * instances can be completeley different no. (structure unchanged though)
1202  */
reassign_itnums(void)1203 static void reassign_itnums(void)
1204 {
1205  register int32 ii;
1206  register struct mod_t *flmdp;
1207  struct itree_t *itp;
1208 
1209  for (flmdp = __modhdr; flmdp != NULL; flmdp = flmdp->mnxt)
1210   flmdp->lastinum = 0;
1211  /* notice types of top level modules cannot change */
1212  for (ii = 0; ii < __numtopm; ii++)
1213   {
1214    itp = __it_roots[ii];
1215    flmdp = itp->itip->imsym->el.emdp;
1216    itp->itinum = (flmdp->lastinum)++;
1217    reassign2_itnums(itp);
1218   }
1219  /* ---
1220  if (__debug_flg)
1221   {
1222    __dbg_msg("==> dumping itree with reset inst numbers\n");
1223    for (ii = 0; ii < __numtopm; ii++) __dmp_itree(__it_roots[ii]);
1224   }
1225  --- */
1226 }
1227 
1228 /*
1229  * non top level built itree for inst. of one module
1230  *
1231  * know up instance pointers point to allocated but not set itree nodes
1232  * for each inst. in module one up
1233  * try to make as breadth first as possible
1234  */
reassign2_itnums(struct itree_t * new_itp)1235 static void reassign2_itnums(struct itree_t *new_itp)
1236 {
1237  register int32 ii;
1238  struct itree_t *itp;
1239  struct mod_t *imdp, *mdp;
1240 
1241  imdp = new_itp->itip->imsym->el.emdp;
1242  /* fill contained itree instance contents */
1243  for (ii = 0; ii < imdp->minum; ii++)
1244   {
1245    /* alloc sets inst_t value */
1246    itp = &(new_itp->in_its[ii]);
1247    mdp = itp->itip->imsym->el.emdp;
1248    itp->itinum = (mdp->lastinum)++;
1249   }
1250  /* finally down 1 level */
1251  for (ii = 0; ii < imdp->minum; ii++)
1252   reassign2_itnums(&(new_itp->in_its[ii]));
1253 }
1254 
1255 /*
1256  * ROUTINES TO SET POUND AND DEFPARAMS
1257  */
1258 
1259 /*
1260  * must set pound params by top down scan of itree
1261  * rule is first set all pound params
1262  */
__set_poundparams(void)1263 extern void __set_poundparams(void)
1264 {
1265  register int32 ii;
1266  struct itree_t *itp;
1267 
1268  for (ii = 0; ii < __numtopm; ii++)
1269   {
1270    /* since pound params change params one level down - none at top */
1271    itp = __it_roots[ii];
1272    set2_poundparams(itp);
1273   }
1274 }
1275 
1276 /*
1277  * set pound params
1278  * try to make as breadth first as possible
1279  */
set2_poundparams(struct itree_t * up_itp)1280 static void set2_poundparams(struct itree_t *up_itp)
1281 {
1282  register int32 ii, ii2;
1283  int32 giawid, is_giarr;
1284  struct itree_t *itp;
1285  struct inst_t *ip;
1286  struct mod_t *up_mdp;
1287  struct giarr_t *giap;
1288 
1289  up_mdp = up_itp->itip->imsym->el.emdp;
1290  giap = NULL;
1291  giawid = 0;
1292  for (ii = 0; ii < up_mdp->minum; ii++)
1293   {
1294    if (up_mdp->miarr != NULL && (giap = up_mdp->miarr[ii]) != NULL)
1295     {
1296      giawid = __get_giarr_wide(giap);
1297      is_giarr = TRUE;
1298     }
1299    else is_giarr = FALSE;
1300 
1301    /* if module no params or none set nil, if some set non nil but some */
1302    /* locations will be nil instead of pointing to up pound param expr. */
1303    itp = &(up_itp->in_its[ii]);
1304    ip = itp->itip;
1305 
1306    /* for giarr's in each expanded instance although since no generate */
1307    /* all are the same */
1308    if (is_giarr)
1309     {
1310      if (ip->ipxprtab != NULL)
1311       {
1312        for (ii2 = ii; ii2 < ii + giawid; ii2++)
1313         {
1314          itp = &(up_itp->in_its[ii2]);
1315          __set_1inst_pound_params(itp, TRUE);
1316         }
1317       }
1318     }
1319    else { if (ip->ipxprtab != NULL) __set_1inst_pound_params(itp, FALSE); }
1320 
1321    /* skip all but first instance of instance array expanded */
1322    /* works because know all must have same type */
1323    /* for array of instances, need master ip in giarr */
1324    if (is_giarr) { giawid = __get_giarr_wide(giap); ii += (giawid - 1); }
1325   }
1326  /* finally down 1 level */
1327  for (ii = 0; ii < up_mdp->minum; ii++)
1328   {
1329    set2_poundparams(&(up_itp->in_its[ii]));
1330 
1331    /* skip all but first instance of instance array expanded */
1332    /* works because know all must have same type */
1333    /* for array of instances, need master ip in giarr */
1334    if (up_mdp->miarr != NULL && (giap = up_mdp->miarr[ii]) != NULL)
1335     {
1336      giawid = __get_giarr_wide(giap);
1337      ii += (giawid - 1);
1338     }
1339   }
1340 }
1341 
1342 /*
1343  * set the pound parameters for all of 1 instance down
1344  *
1345  * only called if instance has at least one pound param
1346  *
1347  * for anything set here must evaluate to number because this is the next
1348  * place in sort order but must leave as expr. because some other
1349  * instances of IS form parameter may need to use default
1350  */
__set_1inst_pound_params(struct itree_t * itp,int32 is_giarr)1351 extern void __set_1inst_pound_params(struct itree_t *itp, int32 is_giarr)
1352 {
1353  register int32 pi;
1354  struct expr_t *pxp;
1355  struct mod_t *imdp;
1356  struct inst_t *ip;
1357  struct xstk_t *xsp;
1358  struct net_t *modnp;
1359  char s1[RECLEN];
1360 
1361  /* top module can not be destination of pound params */
1362  /* DBG remove --- */
1363  if (itp->up_it == NULL) __misc_terr(__FILE__, __LINE__);
1364  /* --- */
1365 
1366  ip = itp->itip;
1367  imdp = itp->itip->imsym->el.emdp;
1368  /* pound parameters are nets (param var typ) defined in module */
1369  /* if # param list short ok, do not change last */
1370  for (pi = 0; pi < imdp->mprmnum; pi++)
1371   {
1372    pxp = ip->ipxprtab[pi];
1373    /* explicit form with this one unused or short list */
1374    if (pxp == NULL) continue;
1375 
1376    modnp = &(imdp->mprms[pi]);
1377 
1378    /* SJM 01/26/05 - mistake because if param set by def param was marking */
1379    /* add preventing recalc param rhs from using expr but must also set */
1380    /* bit for pound param overrides */
1381    modnp->nu.ct->p_setby_defpnd = TRUE;
1382 
1383    /* use whatever parm values in rhs are current to freeze rhs to num */
1384    /* here is the source order point for pound param */
1385    /* must evaluate in instantiating module but set in lower */
1386    __push_itstk(itp->up_it);
1387    xsp = __eval_xpr(pxp);
1388    __pop_itstk();
1389 
1390    /* know this is parameter */
1391    /* if not already in IS form convert and make each inst. old expr. */
1392    /* providing more than one inst. - 1st inst. set from # parm if >1 insts */
1393    /* causes change to IS form */
1394    if (modnp->srep == SR_PNUM)
1395     {
1396      /* special case, if part of inst array, never convert to IS form */
1397      /* because each inst array its own type and all params must be same */
1398      if (is_giarr)
1399       {
1400        sprintf(s1, "%s (pound param)", __msg2_blditree(__xs, itp));
1401        __cnvt_param_stkval(xsp, pxp, modnp, s1);
1402        __assgn_nonis_param(modnp, pxp, xsp);
1403        goto chk_dbg;
1404       }
1405 
1406      /* this will replicate initial value and change srep */
1407      if (imdp->flatinum > 1 && !modnp->nu.ct->n_widthdet)
1408        __chg_param_tois(modnp, imdp);
1409      else
1410       {
1411        sprintf(s1, "%s (pound param)", __msg2_blditree(__xs, itp));
1412        __cnvt_param_stkval(xsp, pxp, modnp, s1);
1413        __assgn_nonis_param(modnp, pxp, xsp);
1414        goto chk_dbg;
1415       }
1416     }
1417    /* IS param case (was or newly converted to IS) */
1418    sprintf(s1, "%s (per instance pound param)", __msg2_blditree(__xs, itp));
1419    __cnvt_param_stkval(xsp, pxp, modnp, s1);
1420    assgn_is_param(modnp, xsp, pxp->has_sign,
1421     itp->itip->imsym->el.emdp->flatinum, itp->itinum);
1422 
1423    /* update paramter value but leave original expr. - needed if user */
1424    /* wants different parameter assign algorithm */
1425 
1426    /* should dump parameter size info here */
1427 chk_dbg:
1428    if (__debug_flg)
1429     {
1430      __push_itstk(itp);
1431      __dbg_msg(
1432       "+++ setting # param %s to %s in module %s (%d insts) from inst. %s\n",
1433       modnp->nsym->synam, __pregab_tostr(__xs, xsp->ap, xsp->bp, modnp),
1434       imdp->msym->synam, imdp->flatinum, ip->isym->synam);
1435      __pop_itstk();
1436     }
1437    __pop_xstk();
1438   }
1439 }
1440 
1441 /*
1442  * assign new value to non IS parameter
1443  */
__assgn_nonis_param(struct net_t * np,struct expr_t * xrhs,struct xstk_t * xsp)1444 extern void __assgn_nonis_param(struct net_t *np, struct expr_t *xrhs,
1445  struct xstk_t *xsp)
1446 {
1447  int32 owlen, nwlen;
1448 
1449  owlen = wlen_(np->nwid);
1450  nwlen = wlen_(xsp->xslen);
1451  /* if param real because declared or inital RHS real know xsp converted */
1452  /* so just assign */
1453  if (np->ntyp == N_REAL)
1454   {
1455    memcpy(np->nva.wp, xsp->ap, 2*owlen*WRDBYTES);
1456    return;
1457   }
1458  __my_free((char *) np->nva.wp, 2*WRDBYTES*owlen);
1459  np->nva.wp = (word32 *) __my_malloc(2*WRDBYTES*nwlen);
1460  memcpy(np->nva.wp, xsp->ap, 2*nwlen*WRDBYTES);
1461 
1462  /* change param width if needed */
1463  if (xsp->xslen != np->nwid)
1464   {
1465    np->nwid = xsp->xslen;
1466    if (np->nu.ct->nx1 != NULL) __free_xtree(np->nu.ct->nx1);
1467    if (np->nu.ct->nx2 != NULL) __free_xtree(np->nu.ct->nx2);
1468    if (np->nwid == 1)
1469     {
1470      np->n_isavec = FALSE;
1471      np->nu.ct->nx1 = np->nu.ct->nx2 = NULL;
1472     }
1473    else
1474     {
1475      np->nu.ct->nx1 = __bld_rng_numxpr((word32) (np->nwid - 1), 0L, WBITS);
1476      np->nu.ct->nx2 = __bld_rng_numxpr(0L, 0L, WBITS);
1477      np->n_isavec = TRUE;
1478     }
1479   }
1480 
1481  /* also use rhs constant value if string/non string */
1482  if (xrhs->is_string) np->nu.ct->pstring = TRUE;
1483  else { np->nu.ct->pstring = FALSE; np->nu.ct->pbase = BDEC; }
1484 }
1485 
1486 /*
1487  * assign new value to IS parameter
1488  */
assgn_is_param(struct net_t * np,struct xstk_t * xsp,int32 rhs_sign,int32 ninsts,int32 iti)1489 static void assgn_is_param(struct net_t *np, struct xstk_t *xsp,
1490  int32 rhs_sign, int32 ninsts, int32 iti)
1491 {
1492  register int32 ii;
1493  int32 owlen, nwlen;
1494  word32 *wp, *wp2, *wp3, *wp4;
1495 
1496  owlen = wlen_(np->nwid);
1497  nwlen = wlen_(xsp->xslen);
1498  /* if param real because declared or inital RHS real know xsp converted */
1499  /* just assign to right inst. loc */
1500  if (np->ntyp == N_REAL)
1501   {
1502    wp = &(np->nva.wp[2*owlen*iti]);
1503    memcpy(wp, xsp->ap, 2*owlen*WRDBYTES);
1504    return;
1505   }
1506 
1507  /* if new value wider must free and realloc so all wider */
1508  /* also change new width - this is tricky case */
1509  if (xsp->xslen > np->nwid)
1510   {
1511    /* save old area */
1512    wp2 = np->nva.wp;
1513    /* allocate new area of new wider size */
1514    np->nva.wp = (word32 *) __my_malloc(2*ninsts*WRDBYTES*nwlen);
1515    /* point to new area */
1516    wp = np->nva.wp;
1517    for (ii = 0; ii < ninsts; ii++)
1518     {
1519      /* right inst. area of old value */
1520      wp3 = &(wp2[2*owlen*ii]);
1521      /* right inst of new area */
1522      wp4 = &(wp[2*nwlen*ii]);
1523      /* since widening must zero first */
1524      zero_allbits_(wp4, xsp->xslen);
1525      zero_allbits_(&(wp4[nwlen]), xsp->xslen);
1526      /* copy in to first arg - high bits 0 */
1527      cp_walign_(wp4, wp3, np->nwid);
1528      cp_walign_(&(wp4[nwlen]), &(wp3[owlen]), np->nwid);
1529     }
1530 
1531    /* finally free old */
1532    __my_free((char *) wp2, 2*ninsts*WRDBYTES*owlen);
1533    /* only widening case */
1534    np->nwid = xsp->xslen;
1535 
1536    /* need to change range */
1537    if (np->nu.ct->nx1 != NULL) __free_xtree(np->nu.ct->nx1);
1538    if (np->nu.ct->nx2 != NULL) __free_xtree(np->nu.ct->nx2);
1539    np->nu.ct->nx1 = __bld_rng_numxpr((word32) (np->nwid - 1), 0L, WBITS);
1540    np->nu.ct->nx2 = __bld_rng_numxpr(0L, 0L, WBITS);
1541    np->n_isavec = TRUE;
1542 
1543    /* adjust old word32 len since now widened */
1544    owlen = wlen_(np->nwid);
1545   }
1546  else
1547   {
1548    /* if new narrower, widen */
1549    /* use net's signedness since if param declared sign will be on in net */
1550    if (xsp->xslen < np->nwid)
1551     {
1552      /* SJM 05/13/04 - rhs expr signedness determines if sign extend needed */
1553      /* was wrongly using lhs */
1554      if (rhs_sign) __sgn_xtnd_widen(xsp, np->nwid);
1555      else __sizchgxs(xsp, np->nwid);
1556     }
1557   }
1558 
1559  /* finally change this inst one */
1560  wp = &(np->nva.wp[2*owlen*iti]);
1561  memcpy(wp, xsp->ap, 2*owlen*WRDBYTES);
1562  /* here must not change param properties except width */
1563 }
1564 
1565 /*
1566  * routine to replace all instances of original expression from
1567  * local defparam
1568  *
1569  * needed so vpi_ access of rhs expr gets right one from pound/defparam
1570  * not originale source
1571  */
replace_param_rhs_expr(struct net_t * np,word32 * wp,struct mod_t * imdp)1572 static void replace_param_rhs_expr(struct net_t *np, word32 *wp,
1573  struct mod_t *imdp)
1574 {
1575  int32 wlen;
1576  double d1;
1577  struct expr_t *xp;
1578 
1579  /* free expr table and convert back if already IS form */
1580  if (np->nu.ct->parm_srep == SR_PISXPR)
1581   {
1582    __my_free((char *) np->nu.ct->n_dels_u.d4x,
1583     imdp->flatinum*sizeof(struct expr_t *));
1584    np->nu.ct->parm_srep = SR_PXPR;
1585   }
1586  xp = __alloc_newxnd();
1587  wlen = wlen_(np->nwid);
1588 
1589  if (np->ntyp == N_REAL)
1590   {
1591    xp->optyp = REALNUM;
1592    xp->is_real = TRUE;
1593    /* SJM 03/25/02 - still need width - since no x part WBITS */
1594    xp->szu.xclen = WBITS;
1595    xp->ibase = np->nu.ct->pbase;
1596 
1597    memcpy(&d1, wp, sizeof(double));
1598    xp->ru.xvi = __alloc_shareable_rlcval(d1);
1599    np->nu.ct->n_dels_u.d1x = xp;
1600    return;
1601   }
1602 
1603  if (np->nwid <= WBITS)
1604   {
1605    xp->ru.xvi = __alloc_shareable_cval(wp[0], wp[1], np->nwid);
1606   }
1607  else
1608   {
1609    xp->ru.xvi = __allocfill_cval_new(wp, &(wp[2*wlen]), wlen);
1610   }
1611 
1612  xp->optyp = NUMBER;
1613  xp->ibase = np->nu.ct->pbase;
1614  if (np->nu.ct->pstring) xp->is_string = TRUE;
1615  if (np->n_signed) xp->has_sign = TRUE;
1616 
1617  np->nu.ct->n_dels_u.d1x = xp;
1618 }
1619 
1620 /*
1621  * set 1 defparam - know all splitting done
1622  *
1623  * notice there be a slight memory leak here since old expression
1624  * value of parameter is not freed but no longer accessible from here
1625  * do not know if accessible form other place because no copy when
1626  * convert to IS form just have each point to the one expr.
1627  *
1628  * know all defparams converted to rooted by here - never specparams here
1629  */
set_1defparam(struct dfparam_t * dfpp)1630 static void set_1defparam(struct dfparam_t *dfpp)
1631 {
1632  int32 wlen;
1633  struct dfparam_t *mast_dfpp;
1634  struct expr_t *lhsndp;
1635  struct net_t *np;
1636  struct xstk_t *xsp;
1637  struct mod_t *imdp;
1638  struct itree_t *itp;
1639  char s1[RECLEN];
1640 
1641  __sfnam_ind = dfpp->dfpfnam_ind;
1642  __slin_cnt = dfpp->dfplin_cnt;
1643 
1644  if (dfpp->idntmastdfp != NULL) mast_dfpp = dfpp->idntmastdfp;
1645  else mast_dfpp = dfpp;
1646 
1647  /* first step evaluate to make sure rhs is constant needs to be done */
1648  /* here since source order and if leave param on rhs further defparam */
1649  /* may change which invalidates source order */
1650  if (dfpp->dfp_local)
1651   {
1652    imdp = dfpp->in_mdp;
1653    __push_wrkitstk(imdp, 0);
1654    xsp = __eval_xpr(dfpp->dfpxrhs);
1655    __pop_wrkitstk();
1656   }
1657  else
1658   {
1659    /* SJM 04/24/05 - fix minor bug this must eval in actual defined in itree */
1660    /* loc not the master's - LOOKATME - is master needed here? */
1661    itp = __find_dfpbot_itp(dfpp);
1662    __push_itstk(itp);
1663    imdp = itp->itip->imsym->el.emdp;
1664    xsp = __eval_xpr(dfpp->dfpxrhs);
1665    __pop_itstk();
1666   }
1667 
1668  /* only possibilities here are ident or global ident */
1669  lhsndp = dfpp->dfpxlhs;
1670 
1671  /* key is that this np must be np in target split off module */
1672  /* and know will be SYM N */
1673  if (lhsndp->optyp == ID) np = lhsndp->lu.sy->el.enp;
1674  else np = dfpp->targsyp->el.enp;
1675  /* SJM 02/28/04 - added flag since must know set by defparam for recalc */
1676  np->nu.ct->p_setby_defpnd = TRUE;
1677  wlen = wlen_(np->nwid);
1678 
1679  /* DBG remove -- */
1680  if (!np->n_isaparam || np->nu.ct->p_specparam)
1681   __arg_terr(__FILE__, __LINE__);
1682  /* -- */
1683 
1684  /* always convert parameter value to declared parameter */
1685  sprintf(s1, "defparam in %s at %s", imdp->msym->synam,
1686   __bld_lineloc(__xs, __sfnam_ind, __slin_cnt));
1687  __cnvt_param_stkval(xsp, dfpp->dfpxrhs, np, s1);
1688 
1689  /* if local applies to all instances and mast dfpp same */
1690  if (dfpp->dfp_local)
1691   {
1692    imdp = dfpp->in_mdp;
1693    /* since must be source order, change back from instance specific */
1694    if (np->srep == SR_PISNUM)
1695     {
1696      __my_free((char *) np->nva.wp, imdp->flatinum*2*WRDBYTES*wlen);
1697      np->srep = SR_PNUM;
1698      np->nva.wp = (word32 *) __my_malloc(2*WRDBYTES*wlen);
1699     }
1700    memcpy(np->nva.wp, xsp->ap, 2*WRDBYTES*wlen);
1701 
1702    /* change so original expression for all instances using new local */
1703    /* defparam evaluated rhs numeric expr. */
1704    /* makes vpi get value form parameter in vpi_ work */
1705    /* this may allocate expr nodes so need mod - although expr not needed */
1706    /* at run time */
1707    __push_wrkitstk(imdp, 0);
1708    replace_param_rhs_expr(np, xsp->ap, imdp);
1709    __pop_wrkitstk();
1710   }
1711  else
1712   {
1713    /* set the target itree place - use master if part of identical group */
1714    itp = __find_dfpbot_itp(mast_dfpp);
1715    imdp = itp->itip->imsym->el.emdp;
1716    /* change to IS NUM form only if more than 1 inst. of module */
1717    if (np->srep == SR_PNUM && imdp->flatinum > 1) __chg_param_tois(np, imdp);
1718 
1719    /* 06/06/00 - SJM - can't copy must use param assign routines */
1720    /* can be either IS or non IS form */
1721    if (np->srep == SR_PISNUM)
1722     {
1723      assgn_is_param(np, xsp, dfpp->dfpxrhs->has_sign, imdp->flatinum,
1724       itp->itinum);
1725     }
1726    else __assgn_nonis_param(np, dfpp->dfpxrhs, xsp);
1727 
1728    /* leave original expr. - only value of lhs parameter changes */
1729    /* allows using algorithm for assigning defparams */
1730   }
1731  /* DBG remove --- */
1732  if (__debug_flg)
1733   {
1734    __dbg_msg("+++ setting defparam %s path %s to %s in module %s\n",
1735     np->nsym->synam, dfpp->gdfpnam, __pregab_tostr(__xs, xsp->ap, xsp->bp, np),
1736     imdp->msym->synam);
1737   }
1738  /* --- */
1739  __pop_xstk();
1740 }
1741 
1742 /*
1743  * for new parameter assignment algorithm - convert to declared or
1744  * implicit from rhs declared type and width
1745  *
1746  * this converts to type and size of param - new algorithm assumes
1747  * that parameters are somehow declared (possibly from initial rhs expr)
1748  */
__cnvt_param_stkval(struct xstk_t * xsp,struct expr_t * xrhs,struct net_t * np,char * innam)1749 extern void __cnvt_param_stkval(struct xstk_t *xsp, struct expr_t *xrhs,
1750  struct net_t *np, char *innam)
1751 {
1752  char s1[RECLEN];
1753 
1754  /* DBG remove -- */
1755  if (!np->n_isaparam) __arg_terr(__FILE__, __LINE__);
1756  /* --- */
1757 
1758  /* case 1: declared or initial real - convert to real */
1759  if (np->ntyp == N_REAL)
1760   {
1761    if (!xrhs->is_real)
1762     {
1763      if (xrhs->szu.xclen == WBITS && xrhs->has_sign) strcpy(s1, "integer");
1764      else sprintf(s1, "%d bit register", xrhs->szu.xclen);
1765      __gfinform(486, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1766       "parameter %s in %s assign required conversion from %s to real",
1767       np->nsym->synam, innam, s1);
1768 
1769      __cnv_stk_fromreg_toreal(xsp, (xrhs->has_sign == 1));
1770     }
1771   }
1772  else
1773   {
1774    /* know param is non real */
1775    if (xrhs->is_real)
1776     {
1777      if (np->nwid == WBITS && np->n_signed) strcpy(s1, "integer");
1778      else sprintf(s1, "%d bit register", np->nwid);
1779 
1780      __gfinform(487, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1781       "parameter %s in %s assign required conversion from real to %s",
1782       np->nsym->synam, innam, s1);
1783 
1784      __cnv_stk_fromreal_toreg32(xsp);
1785     }
1786    /* but it may have wrong width - in new algorithm param assigns */
1787    if (xsp->xslen != xrhs->szu.xclen)
1788     {
1789      __gfinform(488, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1790       "parameter %s in %s assign width mismatch was %d new %d - widest used",
1791       np->nsym->synam, innam, xsp->xslen, np->nwid);
1792 
1793      /* SJM 05/24/00 - now never narrow always use widest */
1794      /* SJM 09/29/03 - change to handle sign extension and separate types */
1795      /* never narrow */
1796      if (xsp->xslen < np->nwid)
1797       {
1798        if (xrhs->has_sign) __sgn_xtnd_widen(xsp, np->nwid);
1799        else __sizchg_widen(xsp, np->nwid);
1800       }
1801     }
1802   }
1803 }
1804 
1805 /*
1806  * recalculate all parameters with other params on rhs
1807  * needed in case rhs params, changed from def or pound setting
1808  *
1809  * SJM 02/28/04 - fixes bug not match LRM when pound/def set rhs expr param
1810  * LOOKATME - handling all cases although think some impossible
1811  *
1812  * LOOKATME - algorithm uses whatever net type is although strictly
1813  * speaking conversion when no explicit width/type given in param decl
1814  * could be needed - if change - then previous syntax checking invalidated
1815  */
__recalc_param_vals(void)1816 extern void __recalc_param_vals(void)
1817 {
1818  register struct mod_t *mdp;
1819  struct task_t *tskp;
1820  int32 mlevel, chged, all_done;
1821 
1822  for (;;)
1823   {
1824    all_done = TRUE;
1825    chged = FALSE;
1826 
1827    /* SJM 03/16/04 - if static (source content) mod level d.s. changed */
1828    /* from splitting of pound params levelized lists updated dynamically */
1829    /* and if from def params will have been rebuilt */
1830    for (mlevel = __dagmaxdist; mlevel >= 0; mlevel--)
1831     {
1832      for (mdp = __mdlevhdr[mlevel]; mdp != NULL; mdp = mdp->mlevnxt)
1833       {
1834        if (mdp->mod_parms_gd) continue;
1835 
1836        all_done = FALSE;
1837        if (!all_parent_mods_recalced(mdp)) continue;
1838        chged = TRUE;
1839 
1840        /* if no params mark as done */
1841        if (mdp->mprmnum == 0)
1842         {
1843          mdp->mod_parms_gd = TRUE;
1844          continue;
1845         }
1846        /* LOOKATME - always recalculate since can't detect if recalced */
1847        /* if no instance have pound params, does no extra checking */
1848        /* but can't call if top mod */
1849        /* AIV 09/27/06 - no need to recalc local params here */
1850        if (mdp->minstnum != 0) recalc_1mod_pndparams(mdp);
1851 
1852        /* AIV 09/27/06 - must recalc all params/local parms/task local parm */
1853        /* after any pound param recalc done, can set params to final vals */
1854        recalc_1mod_params(mdp, mdp->mprms, mdp->mprmnum);
1855        /* recalc all the localparams */
1856        recalc_1mod_params(mdp, mdp->mlocprms, mdp->mlocprmnum);
1857        /* recalc all the task localparams */
1858        for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
1859         {
1860          recalc_1mod_params(mdp, tskp->tsk_locprms, tskp->tlocprmnum);
1861         }
1862 
1863        /* now all parameters in this module set to good final value */
1864        mdp->mod_parms_gd = TRUE;
1865       }
1866     }
1867    if (all_done) break;
1868    /* if pass with no progress, internal error */
1869    if (!chged) __misc_terr(__FILE__, __LINE__);
1870   }
1871 }
1872 
1873 /*
1874  * recalc all params for one module
1875  *
1876  * know all parameters set by pound and/or def params have right value
1877  */
recalc_1mod_params(struct mod_t * mdp,struct net_t * mprms,int32 num)1878 static void recalc_1mod_params(struct mod_t *mdp, struct net_t *mprms,
1879  int32 num)
1880 {
1881  register int32 pi, ii;
1882  int32 wlen;
1883  word32 *wp;
1884  struct net_t *np;
1885  struct xstk_t *xsp;
1886  struct expr_t *xp, **xtab;
1887 
1888  for (pi = 0; pi < num; pi++)
1889   {
1890    np = &(mprms[pi]);
1891 
1892    /* if rhs does not contain any parameter, or parameter set by defparam */
1893    /* that removes the rhs expr, no need to recalculate */
1894    /* SJM 03/01/04 - if rhs set by defparam also can't recalc */
1895    if (!np->nu.ct->p_rhs_has_param || np->nu.ct->p_setby_defpnd) continue;
1896 
1897    wlen = wlen_(np->nwid);
1898    /* case 1: param representation IS expr form */
1899    if (np->nu.ct->parm_srep == SR_PISXPR)
1900     {
1901      if (np->srep == SR_PNUM)
1902       {
1903        /* change to is num - not sure if can happen */
1904        __my_free((char *) np->nva.wp, 2*WRDBYTES*wlen);
1905        np->srep = SR_PISNUM;
1906        np->nva.wp = (word32 *) __my_malloc(2*WRDBYTES*wlen*mdp->flatinum);
1907       }
1908      else if (np->srep != SR_PISNUM) __case_terr(__FILE__, __LINE__);
1909      /* eval expr for every inst */
1910      xtab = np->nu.ct->n_dels_u.d4x;
1911      for (ii = 0; ii < mdp->flatinum; ii++)
1912       {
1913        __push_itstk(mdp->moditps[ii]);
1914        xp = xtab[ii];
1915        xsp = __eval_xpr(xp);
1916 
1917        /* SJM 04/09/02 - need to also convert to/from real to match net */
1918        if (xp->is_real && np->ntyp != N_REAL)
1919         {
1920          __cnv_stk_fromreal_toreg32(xsp);
1921          if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1922         }
1923        else if (!xp->is_real && np->ntyp == N_REAL)
1924         {
1925          __cnv_stk_fromreg_toreal(xsp, (xp->is_real == 1));
1926         }
1927        else if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1928 
1929        wp = &(np->nva.wp[ii*2*wlen]);
1930        memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
1931        __pop_xstk();
1932        __pop_itstk();
1933       }
1934      continue;
1935     }
1936    if (np->nu.ct->parm_srep == SR_PXPR)
1937     {
1938      /* case 2: rhs expr non IS */
1939      if (np->srep == SR_PNUM)
1940       {
1941        xp = np->nu.ct->n_dels_u.d1x;
1942        /* if any IS PNUM params on rhs, must also chg this to IS */
1943        if (xpr_has_is_param(xp))
1944         {
1945          __my_free((char *) np->nva.wp, 2*WRDBYTES*wlen);
1946          np->srep = SR_PISNUM;
1947          np->nva.wp = (word32 *)
1948          __my_malloc(2*WRDBYTES*wlen*mdp->flatinum);
1949          set_parmval_from_isxpr(np, xp, mdp);
1950          continue;
1951         }
1952        /* case 2a: both non IS - any inst context works */
1953        __push_itstk(mdp->moditps[0]);
1954        xsp = __eval_xpr(xp);
1955        /* SJM 04/09/02 - need to also convert to/from real to match net */
1956        if (xp->is_real && np->ntyp != N_REAL)
1957         {
1958          __cnv_stk_fromreal_toreg32(xsp);
1959          if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1960         }
1961        else if (!xp->is_real && np->ntyp == N_REAL)
1962         {
1963          __cnv_stk_fromreg_toreal(xsp, (xp->is_real == 1));
1964         }
1965        else if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1966 
1967        wp = np->nva.wp;
1968        memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
1969        __pop_xstk();
1970        __pop_itstk();
1971        continue;
1972       }
1973      if (np->srep == SR_PISNUM)
1974       {
1975        /* SJM 04/09/02 - LOOKATME - can this case ever happen? */
1976        /* case 2b: param value IS but only one expr non IS) */
1977        /* only one value - can use any itree loc to eval */
1978        xp = np->nu.ct->n_dels_u.d1x;
1979 
1980        /* case 2a: both non IS - any inst context works */
1981        __push_itstk(mdp->moditps[0]);
1982        xsp = __eval_xpr(xp);
1983        /* SJM 04/09/02 - need to also convert to/from real to match net */
1984        if (xp->is_real && np->ntyp != N_REAL)
1985         {
1986          __cnv_stk_fromreal_toreg32(xsp);
1987          if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1988         }
1989        else if (!xp->is_real && np->ntyp == N_REAL)
1990         {
1991          __cnv_stk_fromreg_toreal(xsp, (xp->is_real == 1));
1992         }
1993        else if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
1994        __pop_itstk();
1995 
1996        /* set same value for each */
1997        for (ii = 0; ii < mdp->flatinum; ii++)
1998         {
1999          wp = &(np->nva.wp[ii*2*wlen]);
2000          memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
2001         }
2002        __pop_xstk();
2003        continue;
2004       }
2005      __case_terr(__FILE__, __LINE__);
2006     }
2007    /* if this param changed by pound/def, bit may be on but now number */
2008   }
2009 }
2010 
2011 /*
2012  * recalculate all pound that are set by instances instantiating this mod
2013  *
2014  * new pound params calculation never requires - to IS or size/type change
2015  */
recalc_1mod_pndparams(struct mod_t * mdp)2016 static void recalc_1mod_pndparams(struct mod_t *mdp)
2017 {
2018  register int32 ii, pi;
2019  int32 wlen;
2020  word32 *wp;
2021  struct itree_t *itp, *up_itp;
2022  struct inst_t *ip;
2023  struct net_t *np;
2024  struct expr_t *pxp;
2025  struct xstk_t *xsp;
2026 
2027  for (ii = 0; ii < mdp->flatinum; ii++)
2028   {
2029    itp = mdp->moditps[ii];
2030    ip = itp->itip;
2031    if (ip->ipxprtab == NULL) continue;
2032 
2033    if (itp->up_it == NULL) __misc_terr(__FILE__, __LINE__);
2034    up_itp = itp->up_it;
2035    /* if not pound params for this containing inst, nothing to do */
2036 
2037    /* must push since converts need down mod itree loc */
2038    __push_itstk(itp);
2039    for (pi = 0; pi < mdp->mprmnum; pi++)
2040     {
2041      np = &(mdp->mprms[pi]);
2042 
2043      pxp = ip->ipxprtab[pi];
2044      /* explicit form with this one unused or short list */
2045      if (pxp == NULL) continue;
2046      /* if pound param high conn expr does not contain param, nothing to do */
2047      /* SJM 03/01/04 - if rhs set by defparam can't recalc */
2048      if (!__xpr_has_param(pxp) || np->nu.ct->p_setby_defpnd)
2049       continue;
2050 
2051      /* eval in up and know then any parameters used in expr */
2052      __push_itstk(up_itp);
2053      xsp = __eval_xpr(pxp);
2054      __pop_itstk();
2055 
2056      /* SJM 04/09/02 - need to also convert to/from real to match net */
2057      if (pxp->is_real && np->ntyp != N_REAL)
2058       {
2059        __cnv_stk_fromreal_toreg32(xsp);
2060        if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
2061       }
2062      else if (!pxp->is_real && np->ntyp == N_REAL)
2063       {
2064        __cnv_stk_fromreg_toreal(xsp, (pxp->is_real == 1));
2065       }
2066      else if (np->nwid != xsp->xslen) __sizchgxs(xsp, np->nwid);
2067 
2068      /* if parameter set by pound param, it must be IS */
2069      wlen = wlen_(np->nwid);
2070      if (np->srep == SR_PNUM)
2071       {
2072        /* SJM 03/01/04 - non IS form ok here for array of insts case */
2073        /* ??? if (mdp->flatinum > 1) __misc_terr(__FILE__, __LINE__); */
2074        memcpy(np->nva.wp, xsp->ap, 2*wlen*WRDBYTES);
2075       }
2076      else if (np->srep == SR_PISNUM)
2077       {
2078        wp = &(np->nva.wp[ii*2*wlen]);
2079        memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
2080       }
2081      __pop_xstk();
2082     }
2083    __pop_itstk();
2084   }
2085 }
2086 
2087 /*
2088  * return T if parameter rhs expr contains IS rep param
2089  */
xpr_has_is_param(struct expr_t * ndp)2090 static int32 xpr_has_is_param(struct expr_t *ndp)
2091 {
2092  struct sy_t *syp;
2093  struct net_t *np;
2094  struct expr_t *fandp;
2095 
2096  switch ((byte) ndp->optyp) {
2097   case NUMBER: case REALNUM: case ISNUMBER: case ISREALNUM: return(FALSE);
2098   case ID:
2099    syp = ndp->lu.sy;
2100    if (!syp->sydecl || syp->sytyp != SYM_N) return(FALSE);
2101    np = syp->el.enp;
2102    if (np->n_isaparam && np->srep == SR_PISNUM) return(TRUE);
2103    return(FALSE);
2104   case GLBREF: return(FALSE);
2105   case FCALL:
2106    for (fandp = ndp->ru.x; fandp != NULL; fandp = fandp->ru.x)
2107     {
2108      /* LOOKATME - even if real param not allowed arg to const systf */
2109      /* can be real */
2110      if (xpr_has_is_param(fandp->lu.x)) return(TRUE);
2111     }
2112    return(FALSE);
2113  }
2114  if (ndp->lu.x != NULL) if (xpr_has_is_param(ndp->lu.x)) return(TRUE);
2115  if (ndp->ru.x != NULL) if (xpr_has_is_param(ndp->ru.x)) return(TRUE);
2116  return(FALSE);
2117 }
2118 
2119 /*
2120  * return T all paramters known in modules that use pound params to set
2121  * params in this module
2122  *
2123  */
all_parent_mods_recalced(struct mod_t * mdp)2124 static int32 all_parent_mods_recalced(struct mod_t *mdp)
2125 {
2126  register int32 ii;
2127  struct itree_t *itp;
2128 
2129  /* if mod has no params trivially true */
2130  if (mdp->mprmnum == 0) return(TRUE);
2131  /* if top mod, obviously T */
2132  if (mdp->minstnum == 0) return(TRUE);
2133 
2134  for (ii = 0; ii < mdp->flatinum; ii++)
2135   {
2136    itp = mdp->moditps[ii];
2137    /* DBG remove -- */
2138    if (itp->up_it == NULL) __misc_terr(__FILE__, __LINE__);
2139    /* -- */
2140    if (!itp->up_it->itip->imsym->el.emdp->mod_parms_gd) return(FALSE);
2141   }
2142  return(TRUE);
2143 }
2144 
2145 /*
2146  * set param value (nva) for P IS NUM net from one expr
2147  */
set_parmval_from_isxpr(struct net_t * np,struct expr_t * xp,struct mod_t * mdp)2148 static void set_parmval_from_isxpr(struct net_t *np, struct expr_t *xp,
2149  struct mod_t *mdp)
2150 {
2151  register int32 ii;
2152  int32 wlen;
2153  word32 *wp;
2154  struct xstk_t *xsp;
2155 
2156  wlen = wlen_(np->nwid);
2157  for (ii = 0; ii < mdp->flatinum; ii++)
2158   {
2159    __push_itstk(mdp->moditps[ii]);
2160    /* need to re-eval for every inst */
2161    xsp = __eval_xpr(xp);
2162    /* SJM 09/29/03 - change to handle sign extension and separate types */
2163    if (xsp->xslen > np->nwid) __narrow_sizchg(xsp, np->nwid);
2164    else if (xsp->xslen < np->nwid)
2165     {
2166      if (xp->has_sign) __sgn_xtnd_widen(xsp, np->nwid);
2167      else __sizchg_widen(xsp, np->nwid);
2168     }
2169 
2170    wp = &(np->nva.wp[ii*2*wlen]);
2171    memcpy(wp, xsp->ap, 2*wlen*WRDBYTES);
2172    __pop_xstk();
2173    __pop_itstk();
2174   }
2175 }
2176 
2177 /*
2178  * ROUTINES TO FIND PORT CONNECTED AS INOUTS AND CHG DIR OR EMIT WARN
2179  */
2180 
2181 /*
2182  * routine to set driver bits for nets
2183  * if driven by internal instance output port up drvr, set iconn driver bit
2184  * if driven by module input port down drvr, set mdprt driver bit
2185  * for all other drivers set inmod driver bit
2186  *
2187  * SJM 05/23/01 - now using per bit algorithm because otherwise can't
2188  * detect shorted ports or 2nd iconn that is wrong direction driver
2189  */
__set_drvr_bits(void)2190 extern void __set_drvr_bits(void)
2191 {
2192  register int32 pi, ii, gi;
2193  register struct mod_pin_t *mpp;
2194  int32 ptyp, pnum;
2195  struct inst_t *ip;
2196  struct mod_t *mdp, *imdp;
2197  struct gate_t *gp;
2198  struct conta_t *cap;
2199  struct expr_t *xp;
2200 
2201  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2202   {
2203    __push_wrkitstk(mdp, 0);
2204 
2205    /* first process all instances in module to set the high conn iconns */
2206    for (ii = 0; ii < mdp->minum; ii++)
2207     {
2208      ip = &(mdp->minsts[ii]);
2209      imdp = ip->imsym->el.emdp;
2210      if ((pnum = imdp->mpnum) == 0) continue;
2211 
2212      for (pi = 0; pi < pnum; pi++)
2213       {
2214        mpp = &(imdp->mpins[pi]);
2215        xp = ip->ipins[pi];
2216        ptyp = mpp->mptyp;
2217 
2218        /* for inout always marks high conn tran drvr */
2219        if (ptyp == IO_BID) set_lhs_expr_drvrtyp(xp, DRVR_NON_PORT,
2220         ip->isym->syfnam_ind, ip->isym->sylin_cnt);
2221        else if (ptyp == IO_OUT) set_lhs_expr_drvrtyp(xp, DRVR_ICONN,
2222         ip->isym->syfnam_ind, ip->isym->sylin_cnt);
2223       }
2224     }
2225 
2226    /* next gates including udps */
2227    for (gi = 0; gi < mdp->mgnum; gi++)
2228     {
2229      /* if this is array of gates, will cause direction chg to inout */
2230      /* SJM 05/23/01 - FIXME - should unwind these and not change */
2231      gp = &(mdp->mgates[gi]);
2232      switch ((byte) gp->g_class) {
2233       case GC_PULL:
2234        /* one gate all drivers can have multiple pins */
2235        for (pi = 0; pi < (int32) gp->gpnum; pi++)
2236         {
2237          xp = gp->gpins[pi];
2238          /* pull will force change to inoutk so tran type */
2239          set_lhs_expr_drvrtyp(xp, DRVR_NON_PORT, gp->gsym->syfnam_ind,
2240           gp->gsym->sylin_cnt);
2241         }
2242        break;
2243       case GC_TRAN:
2244        /* both terminals of tran, need drvr field set */
2245        set_lhs_expr_drvrtyp(gp->gpins[0], DRVR_NON_PORT, gp->gsym->syfnam_ind,
2246         gp->gsym->sylin_cnt);
2247        set_lhs_expr_drvrtyp(gp->gpins[1], DRVR_NON_PORT, gp->gsym->syfnam_ind,
2248         gp->gsym->sylin_cnt);
2249        break;
2250       case GC_TRANIF:
2251        /* first two  terminals of tranif, need drvr field set */
2252        set_lhs_expr_drvrtyp(gp->gpins[0], DRVR_NON_PORT, gp->gsym->syfnam_ind,
2253         gp->gsym->sylin_cnt);
2254        set_lhs_expr_drvrtyp(gp->gpins[1], DRVR_NON_PORT, gp->gsym->syfnam_ind,
2255         gp->gsym->sylin_cnt);
2256        break;
2257       default:
2258        /* for gate/udp, unless output unc. set drv type field in conn net */
2259        /* if output unc. (OPEMPTY), chges are not seen (do not propagate) */
2260        if (gp->gpins[0]->optyp == OPEMPTY) continue;
2261        set_lhs_expr_drvrtyp(gp->gpins[0], DRVR_NON_PORT, gp->gsym->syfnam_ind,
2262         gp->gsym->sylin_cnt);
2263      }
2264     }
2265    for (cap = mdp->mcas; cap != NULL; cap = cap->pbcau.canxt)
2266     {
2267      set_lhs_expr_drvrtyp(cap->lhsx, DRVR_NON_PORT, cap->casym->syfnam_ind,
2268       cap->casym->sylin_cnt);
2269     }
2270 
2271    /* LOOKATME - for top level module ports, still setting */
2272    /* module ports (low conns) */
2273    pnum = mdp->mpnum;
2274    for (pi = 0; pi < pnum; pi++)
2275     {
2276      mpp = &(mdp->mpins[pi]);
2277      xp = mpp->mpref;
2278      ptyp = mpp->mptyp;
2279      /* for inout always marks low conn tran drvr */
2280      if (ptyp == IO_BID) set_lhs_expr_drvrtyp(xp, DRVR_NON_PORT,
2281       mpp->mpfnam_ind, mpp->mplin_cnt);
2282      else if (ptyp == IO_IN) set_lhs_expr_drvrtyp(xp, DRVR_MDPRT,
2283       mpp->mpfnam_ind, mpp->mplin_cnt);
2284     }
2285    __pop_wrkitstk();
2286   }
2287  /* FIXME - not using tf_ drivers to change module port direction */
2288  /* think this is right since not really structural drivers" */
2289 }
2290 
2291 /*
2292  * set lhs lvalue expr driver bits (i.e. know will be lvalue expr)
2293  */
set_lhs_expr_drvrtyp(struct expr_t * xp,int32 drvr_typ,int32 fnind,int32 flcnt)2294 static void set_lhs_expr_drvrtyp(struct expr_t *xp, int32 drvr_typ, int32 fnind,
2295  int32 flcnt)
2296 {
2297  int32 ri1, ri2;
2298  struct net_t *np;
2299  struct expr_t *idndp, *catxp;
2300 
2301  ri1 = ri2 = -1;
2302  switch ((byte) xp->optyp) {
2303   case ID: case GLBREF:
2304    if (xp->lu.sy->sytyp != SYM_N)
2305     {
2306      /* SJM 11/12/01 - must catch syntax error of using non net as port */
2307      /* iconn connection */
2308      /* actual error will be found during pass 2 - needed for port coerce */
2309      __gferr(3415, fnind, flcnt,
2310       "lllegal declarative lvalue %s - see detailed pass 2 error",
2311       __msgexpr_tostr(__xs, xp));
2312      __pv_err_cnt--;
2313      return;
2314     }
2315    np = xp->lu.sy->el.enp;
2316    break;
2317   case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
2318    return;
2319   case LSB:
2320    idndp = xp->lu.x;
2321    np = idndp->lu.sy->el.enp;
2322    /* SJM 09/24/01 - if syntax err where selecting from non vector emit */
2323    /* error and do not set drive type */
2324    if (np->nsym->sytyp != SYM_N || !np->n_isavec)
2325     {
2326      __gferr(3412, fnind, flcnt,
2327       "attempt to bit select from non vector %s", np->nsym->synam);
2328      return;
2329     }
2330    ri1 = ri2 = comp_pre_elab_norm_con_ndx(np, xp->ru.x, fnind, flcnt);
2331    /* SJM 07/07/03 - for illegal negative index, can't set bit drvr types */
2332    if (ri1 == -2) return;
2333    break;
2334   case PARTSEL:
2335    idndp = xp->lu.x;
2336    np = idndp->lu.sy->el.enp;
2337    if (np->nsym->sytyp != SYM_N || !np->n_isavec)
2338     {
2339      __gferr(3412, fnind, flcnt,
2340       "attempt to part select from non vector %s", np->nsym->synam);
2341      return;
2342     }
2343    /* notice need to eval these const exprs since not folded yet */
2344    ri1 = comp_pre_elab_norm_con_ndx(np, xp->ru.x->lu.x, fnind, flcnt);
2345    ri2 = comp_pre_elab_norm_con_ndx(np, xp->ru.x->ru.x, fnind, flcnt);
2346    /* SJM 07/07/03 - for illegal negative index, can't set bit drvr types */
2347    if (ri1 == -2 || ri2 == -2) return;
2348    break;
2349   case LCB:
2350    for (catxp = xp->ru.x; catxp != NULL; catxp = catxp->ru.x)
2351     { set_lhs_expr_drvrtyp(catxp->lu.x, drvr_typ, fnind, flcnt); }
2352    return;
2353   default:
2354    /* SJM 10/22/01 - need to flag problem but not count as error since */
2355    /* actual error will be found during pass 2 - needed for port coerce */
2356    __gferr(3415, fnind, flcnt, "lllegal declarative lvalue %s - see detailed pass 2 error",
2357     __msgexpr_tostr(__xs, xp));
2358    __pv_err_cnt--;
2359    return;
2360  }
2361  if (np->n_isavec) set_vec_drvr_type(np, ri1, ri2, drvr_typ);
2362  else set_scalar_drvr_type(np, drvr_typ);
2363 }
2364 
2365 /*
2366  * compute a known constant expr numeric index before elaboration and folding
2367  * notice since constants not yet folded, must normalize constants too
2368  */
comp_pre_elab_norm_con_ndx(struct net_t * np,struct expr_t * xp,int32 fnind,int32 flcnt)2369 static int32 comp_pre_elab_norm_con_ndx(struct net_t *np, struct expr_t *xp,
2370  int32 fnind, int32 flcnt)
2371 {
2372  int32 nni1, nni2, biti, biti2, prtxpr_rng_bad;
2373  struct xstk_t *xsp;
2374 
2375  if (!is_nonis_const_expr(xp)) return(-1);
2376 
2377  xsp = __eval_xpr(xp);
2378  /* if wide or x/z, be pessimistic and assume all of range (i.e. out of rng) */
2379  if (xsp->xslen > WBITS || xsp->bp[0] != 0)
2380   { __pop_xstk(); return(-1); }
2381  biti2 = (int32) xsp->ap[0];
2382  __pop_xstk();
2383 
2384  /* SJM 04/07/23 - nx1 may not be set for nets decl from implicit connect */
2385  if (np->nu.ct->nx1 == NULL || np->nu.ct->nx2 == NULL)
2386   {
2387    biti = -1;
2388   }
2389  else
2390   {
2391    nni1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
2392    nni2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
2393    /* SJM 07/31/03 - because port drivers are needed before ranges set */
2394    /* must make sure that mod port expr constant selects are in range */
2395    /* notice - not yet normalized to h:0 */
2396    prtxpr_rng_bad = FALSE;
2397    if (nni1 >= nni2)
2398     { if (biti2 > nni1 || biti2 < nni2) prtxpr_rng_bad  = TRUE; }
2399    else { if (biti2 < nni1 || biti2 > nni2) prtxpr_rng_bad = TRUE; }
2400    if (prtxpr_rng_bad)
2401     {
2402      __gferr(3415, fnind, flcnt,
2403       "module port expression select range index %d outside net range [%d:%d] - can't fix",
2404       biti2, nni1, nni2);
2405      return(-2);
2406     }
2407 
2408    if (nni1 < 0 || nni2 < 0 || biti2 < 0)
2409     {
2410      __gferr(3415, fnind, flcnt, "lllegal negative port declaration range");
2411      return(-2);
2412     }
2413    biti = normalize_ndx_(biti2, nni1, nni2);
2414   }
2415  return(biti);
2416 }
2417 
2418 /*
2419  * check to see if an expressions is pre elaboration non IS constant
2420  * no folding before here and selects legal providing no variables appear
2421  */
is_nonis_const_expr(struct expr_t * ndp)2422 static int32 is_nonis_const_expr(struct expr_t *ndp)
2423 {
2424  struct net_t *np;
2425 
2426  np = NULL;
2427  if (__isleaf(ndp))
2428   {
2429    if (ndp->optyp == ID)
2430     {
2431      if (ndp->lu.sy->sytyp != SYM_N) return(FALSE);
2432      np = ndp->lu.sy->el.enp;
2433      if (!np->n_isaparam) return(FALSE);
2434     }
2435    if (ndp->optyp == GLBREF) return(FALSE);
2436    /* here IS number is non constant */
2437    if (ndp->optyp == ISNUMBER) return(FALSE);
2438 
2439    /* SJM 05/19/04 - because of driver bit setting needed to do later */
2440    /* expr checking - only for parameters expr size not yet set */
2441    /* therefore set it to parameter width here as kludge - value will be */
2442    /* right but will be set again later */
2443    if (ndp->optyp == ID && ndp->szu.xclen == 0)
2444     {
2445      ndp->szu.xclen = np->nwid;
2446     }
2447 
2448    return(TRUE);
2449   }
2450  if (ndp->lu.x != NULL)
2451   { if (!is_nonis_const_expr(ndp->lu.x)) return(FALSE); }
2452  if (ndp->ru.x != NULL)
2453   { if (!is_nonis_const_expr(ndp->ru.x)) return(FALSE); }
2454  return(TRUE);
2455 }
2456 
2457 /*
2458  * set scalar driver type - know never passed drvr none
2459  */
set_scalar_drvr_type(struct net_t * np,int32 drvr_typ)2460 static void set_scalar_drvr_type(struct net_t *np, int32 drvr_typ)
2461 {
2462  /* if current state drvr none, set to passed new state */
2463  if (np->n_drvtyp == DRVR_NONE) { np->n_drvtyp = drvr_typ; return; }
2464 
2465  /* otherwide set to real driver - any 2nd driver becomes non port where */
2466  /* always need to change to inout if possible */
2467  np->n_drvtyp = DRVR_NON_PORT;
2468 }
2469 
2470 /*
2471  * set driver type - know never passed drvr none
2472  * if ri1 -1, then entire range - know ranges normalized before here
2473  */
set_vec_drvr_type(struct net_t * np,int32 ri1,int32 ri2,int32 drvr_typ)2474 static void set_vec_drvr_type(struct net_t *np, int32 ri1, int32 ri2, int32 drvr_typ)
2475 {
2476  register int32 ri, bi;
2477  int32 nni1, nni2, wid;
2478 
2479  /* range convert to constants but not normalized by here */
2480  nni1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
2481  nni2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
2482  wid = ((nni1 >= nni2) ? (nni1 - nni2 + 1) : (nni2 - nni1 + 1));
2483  /* allocate per bit drv state if needed */
2484  if (np->nu.ct->n_pb_drvtyp == NULL)
2485   {
2486    np->nu.ct->n_pb_drvtyp = (byte *) __my_malloc(wid);
2487    for (bi = 0; bi < wid; bi++) np->nu.ct->n_pb_drvtyp[bi] = DRVR_NONE;
2488   }
2489 
2490  if (ri1 == -1) { ri1 = wid - 1; ri2 = 0; }
2491  for (ri = ri1; ri >= ri2; ri--)
2492   {
2493    /* if current state drvr none, set to passed new state */
2494    if (np->nu.ct->n_pb_drvtyp[ri] == DRVR_NONE)
2495     { np->nu.ct->n_pb_drvtyp[ri] = drvr_typ; continue; }
2496    /* otherwide set to real driver - any 2nd driver becomes non port where */
2497    /* always need to change to inout if possible */
2498    np->nu.ct->n_pb_drvtyp[ri] = DRVR_NON_PORT;
2499   }
2500 }
2501 
2502 /*
2503  * check connection pattern for all input and output ports and change if
2504  * nd_chg T and return num_chged if any changed (0 if none changed)
2505  *
2506  * if input has lowconn driver and highconn is wire lvalue chg to inout
2507  * if output has highconn driver and lowconn is wire lvalue chg to inout
2508  *
2509  * if option not used, emit warning else emit inform if option used
2510  */
__chk_chg_port_dir(int32 nd_chg)2511 extern void __chk_chg_port_dir(int32 nd_chg)
2512 {
2513  register int32 pi, ii;
2514  register struct mod_pin_t *mpp;
2515  int32 pnum, num_chged, sav_num_chged;
2516  struct inst_t *ip;
2517  struct mod_t *mdp, *imdp;
2518  struct expr_t *xp;
2519  char s1[RECLEN];
2520 
2521  for (num_chged = 0;;)
2522   {
2523    sav_num_chged = num_chged;
2524    for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2525     {
2526      /* process for every instance in module */
2527      for (ii = 0; ii < mdp->minum; ii++)
2528       {
2529        ip = &(mdp->minsts[ii]);
2530        imdp = ip->imsym->el.emdp;
2531        if ((pnum = imdp->mpnum) == 0) continue;
2532 
2533        for (pi = 0; pi < pnum; pi++)
2534         {
2535          mpp = &(imdp->mpins[pi]);
2536          /* any up iconn connection to inout is fi>1 here */
2537          xp = ip->ipins[pi];
2538 
2539          /* SJM 06/01/01 SJM - never change if either hiconn or loconn */
2540          /* concatenate - idea is that concat is expr so must be declared */
2541          /* with right direction or assume no backwards driving */
2542          if (mpp->mpref->optyp == LCB || xp->optyp == LCB) continue;
2543 
2544          /* SJM 11/15/00 - need to emit warnings for connections where */
2545          /* XL port collapsing may produce wrong result */
2546          /* case 1: instance input port where down lowconn has drivers */
2547          if (mpp->mptyp == IO_IN)
2548           {
2549            /* SJM 05/23/01 - changeable if both hiconn and loconn decl lval */
2550            /* and has wrong direction driver(s) */
2551            /* for port, even if subrange, if any bits in vec, change */
2552            if (expr_decl_lvalue(mpp->mpref) && expr_decl_lvalue(xp)
2553             && port_expr_has_wrong_dir_drvr(mpp->mpref, IO_IN, -1, -1,
2554              mpp->mpfnam_ind, mpp->mplin_cnt))
2555             {
2556              if (nd_chg)
2557               {
2558                __gfinform(3005, mpp->mpfnam_ind, mpp->mplin_cnt,
2559                 "input port %s (pos. %d) of instance at %s has lowconn driver(s) - changed to inout from +change_port_type option - otherwise value of %s in %s could differ",
2560                 __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2561                 __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2562                 __msgexpr_tostr(s1, xp), mdp->msym->synam);
2563 
2564                mpp->mptyp = IO_BID;
2565                chg_mpx_to_bid(mpp->mpref);
2566                set_lhs_expr_drvrtyp(mpp->mpref, DRVR_NON_PORT,
2567                 mpp->mpfnam_ind, mpp->mplin_cnt);
2568                set_lhs_expr_drvrtyp(xp, DRVR_NON_PORT, ip->isym->syfnam_ind,
2569                 ip->isym->sylin_cnt);
2570                num_chged++;
2571                continue;
2572               }
2573              if (mdp->mgarr != NULL || imdp->mgarr != NULL)
2574               {
2575                /* SJM 05/23/01 - if mod has arrays of gates just inform but */
2576                /* still would change if change port types on */
2577                __gfinform(3005, mpp->mpfnam_ind, mpp->mplin_cnt,
2578                 "input port %s (pos. %d) of instance at %s has lowconn driver(s), value of %s in %s may differ from simulators using port collapsing - use +change_port_type for compatibility",
2579                 __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2580                 __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2581                 __msgexpr_tostr(s1, xp), mdp->msym->synam);
2582                continue;
2583               }
2584 
2585              __gfwarn(3107, mpp->mpfnam_ind, mpp->mplin_cnt,
2586               "input port %s (pos. %d) of instance at %s has lowconn driver(s), value of %s in %s may differ from simulators using port collapsing - use +change_port_type for compatibility",
2587               __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2588               __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2589               __msgexpr_tostr(s1, xp), mdp->msym->synam);
2590             }
2591            continue;
2592           }
2593          if (mpp->mptyp == IO_OUT)
2594           {
2595            /* SJM 05/23/01 - changeable if both hiconn and loconn decl lval */
2596            /* and has wrong direction driver(s) */
2597            /* for output if bsel or psel, need range but decomposed here */
2598            if (expr_decl_lvalue(mpp->mpref) && expr_decl_lvalue(xp)
2599             && port_expr_has_wrong_dir_drvr(xp, IO_OUT, -1, -1,
2600             mpp->mpfnam_ind, mpp->mplin_cnt))
2601             {
2602              if (nd_chg)
2603               {
2604                __gfinform(3004, mpp->mpfnam_ind, mpp->mplin_cnt,
2605                 "output port %s (pos. %d) of instance at %s has highconn driver(s) - changed to inout from +change_port_type option - otherwise value of %s in %s could differ",
2606                __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2607                __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2608                __msgexpr_tostr(s1, mpp->mpref), imdp->msym->synam);
2609 
2610                mpp->mptyp = IO_BID;
2611                chg_mpx_to_bid(mpp->mpref);
2612                set_lhs_expr_drvrtyp(mpp->mpref, DRVR_NON_PORT,
2613                 mpp->mpfnam_ind, mpp->mplin_cnt);
2614                set_lhs_expr_drvrtyp(xp, DRVR_NON_PORT, ip->isym->syfnam_ind,
2615                 ip->isym->sylin_cnt);
2616                num_chged++;
2617                continue;
2618               }
2619              if (mdp->mgarr != NULL || imdp->mgarr != NULL)
2620               {
2621                /* SJM 05/23/01 - if mod has arrays of gates just inform but */
2622                /* still would change if change port types on */
2623                __gfinform(3005, mpp->mpfnam_ind, mpp->mplin_cnt,
2624               "output port %s (pos. %d) of instance at %s has highconn driver(s), value of %s in %s may differ from simulators using port collapsing - use +change_port_type for compatibility",
2625               __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2626               __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2627               __msgexpr_tostr(s1, mpp->mpref), imdp->msym->synam);
2628                continue;
2629               }
2630              __gfwarn(3108, mpp->mpfnam_ind, mpp->mplin_cnt,
2631               "output port %s (pos. %d) of instance at %s has highconn driver(s), value of %s in %s may differ from simulators using port collapsing - use +change_port_type for compatibility",
2632               __to_mpnam(__xs, mpp->mpsnam), pi + 1,
2633               __bld_lineloc(__xs2, ip->isym->syfnam_ind, ip->isym->sylin_cnt),
2634               __msgexpr_tostr(s1, mpp->mpref), imdp->msym->synam);
2635             }
2636           }
2637         }
2638       }
2639     }
2640    /* if none changed, done - else try to find more */
2641    if (sav_num_chged == num_chged) break;
2642   }
2643  if (nd_chg && __verbose)
2644   {
2645    __cv_msg(
2646     "  %d input and/or output ports that are connected as inout changed to inout.\n",
2647     num_chged);
2648   }
2649  free_design_ndrvrs();
2650 }
2651 
2652 /*
2653  * return T if expression has (can have) wrong direction drivers
2654  * for input port, expect down mod port expr to have only MD PRT driver
2655  * for output port, expect up iconn expr to have only up iconn driver
2656  *
2657  * this is run before tran channels built
2658  * never called for ports already inouts or that can't be changed to inout
2659  */
port_expr_has_wrong_dir_drvr(struct expr_t * xp,int32 pdir,int32 ri1,int32 ri2,int32 fnind,int32 flcnt)2660 static int32 port_expr_has_wrong_dir_drvr(struct expr_t *xp, int32 pdir, int32 ri1,
2661  int32 ri2, int32 fnind, int32 flcnt)
2662 {
2663  register struct expr_t *catndp;
2664  int32 elem_lval, has_drvrs, max_drv_state;
2665  struct net_t *np;
2666 
2667  /* SJM 07/07/03 - if neg range error - can't check dir - error later */
2668  /* SJM 07/16/03 - for non vector expect ri2 to be -1 - can't check for */
2669  /* negative range */
2670  if (ri1 < -1 || ri2 < -1) return(FALSE);
2671 
2672  if (__isleaf(xp))
2673   {
2674    if (xp->optyp == ID || xp->optyp == GLBREF)
2675     {
2676      np = xp->lu.sy->el.enp;
2677      /* if not wire, does not have wrong dir driver */
2678      if (np->ntyp >= NONWIRE_ST) return(FALSE);
2679 
2680      if (np->n_isavec) max_drv_state = find_max_rng_drvr_state(np, ri1, ri2);
2681      else max_drv_state = np->n_drvtyp;
2682 
2683      /* if no drivers, can't be wrong direction */
2684      if (max_drv_state == DRVR_NONE) return(FALSE);
2685 
2686      /* if has non port (inout non port here), always has wrog dir */
2687      if (max_drv_state == DRVR_NON_PORT) return(TRUE);
2688 
2689      if (pdir == IO_IN)
2690       {
2691        /* if input port, wrong direction is non port or 1 up iconn driver */
2692        if (max_drv_state != DRVR_MDPRT) return(TRUE);
2693       }
2694      else if (pdir == IO_OUT)
2695       {
2696        /* if output port, wrong direction is non port or 1 down mdprt drvr */
2697        if (max_drv_state != DRVR_ICONN) return(TRUE);
2698       }
2699      else __case_terr(__FILE__, __LINE__);
2700      return(FALSE);
2701     }
2702    /* if leaf, non id or global, can't have drivers */
2703    return(FALSE);
2704   }
2705  /* arithmetic/logic operators exprs or fcalls can't have drivers */
2706  switch ((byte) xp->optyp) {
2707   /* for selects, ignore select expr. */
2708   case LSB:
2709    /* if not lvalue, never need to change */
2710    if (!__is_const_expr(xp->ru.x)) return(FALSE);
2711    /* if port is input, any driver (even outside bsel) still need dir chg */
2712    if (pdir == IO_IN) ri1 = -1;
2713    else
2714     {
2715      np = xp->lu.x->lu.sy->el.enp;
2716      ri1 = comp_pre_elab_norm_con_ndx(np, xp->ru.x, fnind, flcnt);
2717      /* SJM 07/07/03 - if illegal neg rng - treat as right dir */
2718      if (ri1 == -2) return(FALSE);
2719     }
2720    if (port_expr_has_wrong_dir_drvr(xp->lu.x, pdir, ri1, ri1, fnind,
2721     flcnt)) return(TRUE);
2722    return(FALSE);
2723   case PARTSEL:
2724    /* if port is input, any driver (even outside sel) still need dir chg */
2725    if (pdir == IO_IN) ri1 = ri2 = -1;
2726    else
2727     {
2728      np = xp->lu.x->lu.sy->el.enp;
2729      ri1 = comp_pre_elab_norm_con_ndx(np, xp->ru.x->lu.x, fnind, flcnt);
2730      ri2 = comp_pre_elab_norm_con_ndx(np, xp->ru.x->ru.x, fnind, flcnt);
2731      /* SJM 07/07/03 - if illegal neg rng - treat as right dir */
2732      if (ri1 == -2 || ri2 == -2) return(FALSE);
2733     }
2734    if (port_expr_has_wrong_dir_drvr(xp->lu.x, pdir, ri1, ri2, fnind, flcnt))
2735     return(TRUE);
2736    return(FALSE);
2737   case LCB:
2738    /* if any component has drivers and all are decl lvals, then T */
2739    has_drvrs = FALSE;
2740    elem_lval = TRUE;
2741    for (catndp = xp->ru.x; catndp != NULL; catndp = catndp->ru.x)
2742     {
2743      /* if any expr has drivers and no regs, then concat can have drvrs */
2744      if (port_expr_has_wrong_dir_drvr(catndp->lu.x, pdir, -1, -1, fnind,
2745       flcnt)) has_drvrs = TRUE;
2746      /* if not decl lvalue, concat can't be decl lvalue either */
2747      if (!expr_decl_lvalue(catndp->lu.x)) elem_lval = FALSE;
2748     }
2749    if (has_drvrs && elem_lval) return(TRUE);
2750    break;
2751   default: break;
2752  }
2753  /* if not an lvalue, can't be changed to inout */
2754  return(FALSE);
2755 }
2756 
2757 /*
2758  * compute maximum driver state of expr
2759  * for module will always be entire expr, for up iconn may be for subrange
2760  *
2761  * if entire range -1, else normalized range
2762  * only called for vectors
2763  */
find_max_rng_drvr_state(struct net_t * np,int32 ri1,int32 ri2)2764 static int32 find_max_rng_drvr_state(struct net_t *np, int32 ri1, int32 ri2)
2765 {
2766  register int32 bi;
2767  int32 max_drvr_state, nni1, nni2, wid;
2768 
2769  nni1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
2770  nni2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
2771  wid = ((nni1 >= nni2) ? (nni1 - nni2 + 1) : (nni2 - nni1 + 1));
2772  max_drvr_state = DRVR_NONE;
2773  if (ri1 == -1) { ri1 = wid - 1; ri2 = 0; }
2774  for (bi = ri1; bi >= ri2; bi--)
2775   {
2776    /* if current driver state, max. hard non port (maybe inout), found max */
2777    if (np->nu.ct->n_pb_drvtyp[bi] == DRVR_NON_PORT)
2778     { max_drvr_state = DRVR_NON_PORT; break; }
2779 
2780    /* if this one is driver none, nothing to do */
2781    if (max_drvr_state == DRVR_NONE) continue;
2782 
2783    /* if max same as this one, nothing to do */
2784    if (np->nu.ct->n_pb_drvtyp[bi] == max_drvr_state) continue;
2785 
2786    /* if this one, non inout port, know will be different so set to max */
2787    max_drvr_state = DRVR_NON_PORT;
2788    break;
2789   }
2790  return(max_drvr_state);
2791 }
2792 
2793 /*
2794  * check to see if an expressions is constant
2795  *
2796  * no folding and selects legal providing no variables appear
2797  */
__is_const_expr(struct expr_t * ndp)2798 extern int32 __is_const_expr(struct expr_t *ndp)
2799 {
2800  struct net_t *np;
2801 
2802  if (__isleaf(ndp))
2803   {
2804    if (ndp->optyp == ID)
2805     {
2806      if (ndp->lu.sy->sytyp != SYM_N) return(FALSE);
2807      np = ndp->lu.sy->el.enp;
2808      if (!np->n_isaparam) return(FALSE);
2809     }
2810    if (ndp->optyp == GLBREF) return(FALSE);
2811    return(TRUE);
2812   }
2813  if (ndp->lu.x != NULL) { if (!__is_const_expr(ndp->lu.x)) return(FALSE); }
2814  if (ndp->ru.x != NULL) { if (!__is_const_expr(ndp->ru.x)) return(FALSE); }
2815  return(TRUE);
2816 }
2817 
2818 /*
2819  * return T if expr is decl lvalue
2820  * only if decl lvalue high conn and low conn can be changed to inout port
2821  */
expr_decl_lvalue(struct expr_t * xp)2822 static int32 expr_decl_lvalue(struct expr_t *xp)
2823 {
2824  struct expr_t *catndp;
2825  struct net_t *np;
2826 
2827  switch ((byte) xp->optyp) {
2828   case ID: case GLBREF:
2829    np = xp->lu.sy->el.enp;
2830    /* reg is not decl lvalue */
2831    if (np->ntyp < NONWIRE_ST) return(TRUE);
2832    break;
2833   case LSB:
2834    /* declarative lvalue only if constant expr */
2835    /* SJM 05/23/01 - at this point const exprs not folded */
2836    if (!__is_const_expr(xp->ru.x)) return(FALSE);
2837    np = xp->lu.x->lu.sy->el.enp;
2838    /* only wire is decl lvalue */
2839    if (np->ntyp < NONWIRE_ST) return(TRUE);
2840    break;
2841   case PARTSEL:
2842    np = xp->lu.x->lu.sy->el.enp;
2843    /* only wire is decl lvalue */
2844    if (np->ntyp < NONWIRE_ST) return(TRUE);
2845    break;
2846   case LCB:
2847    /* if any element of concat not decl lvalue, concat can't be changed */
2848    for (catndp = xp->ru.x; catndp != NULL; catndp = catndp->ru.x)
2849     {
2850      if (!expr_decl_lvalue(catndp->lu.x)) return(FALSE);
2851     }
2852    return(TRUE);
2853   default: break;
2854  }
2855  /* if not an lvalue, can't be changed to inout */
2856  return(FALSE);
2857 }
2858 
2859 /*
2860  * routine to change IO type of all port expr contaned nets
2861  * know will be lvalue or will not be called
2862  */
chg_mpx_to_bid(struct expr_t * mpx)2863 static void chg_mpx_to_bid(struct expr_t *mpx)
2864 {
2865  register struct expr_t *catndp;
2866  struct net_t *np;
2867 
2868  switch ((byte) mpx->optyp) {
2869    case ID: case GLBREF:
2870     np = mpx->lu.sy->el.enp;
2871     np->iotyp = IO_BID;
2872     break;
2873    case LSB: case PARTSEL:
2874     chg_mpx_to_bid(mpx->lu.x);
2875     break;
2876    case LCB:
2877     for (catndp = mpx->ru.x; catndp != NULL; catndp = catndp->ru.x)
2878      { chg_mpx_to_bid(catndp->lu.x); }
2879     break;
2880    default: __case_terr(__FILE__, __LINE__);
2881   }
2882 }
2883 
2884 /*
2885  * free all vector rng reps in design - never attached for task vars
2886  */
free_design_ndrvrs(void)2887 static void free_design_ndrvrs(void)
2888 {
2889  register struct mod_t *mdp;
2890  register int32 ni;
2891  register struct net_t *np;
2892  int32 nni1, nni2, wid;
2893 
2894  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2895   {
2896    /* only free for wires, regs and task vars never pb drv fields */
2897    for (np = &(mdp->mnets[0]), ni = 0; ni < mdp->mnnum; ni++, np++)
2898     {
2899      if (!np->n_isavec) continue;
2900 
2901      if (np->nu.ct->n_pb_drvtyp != NULL)
2902       {
2903        nni1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
2904        nni2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
2905        wid = ((nni1 >= nni2) ? (nni1 - nni2 + 1) : (nni2 - nni1 + 1));
2906        __my_free((char *) np->nu.ct->n_pb_drvtyp, wid);
2907        np->nu.ct->n_pb_drvtyp = NULL;
2908       }
2909     }
2910   }
2911 }
2912 
2913 /*
2914  * ROUTINES TO SET TIME SCALE VALUES
2915  */
2916 
2917 /*
2918  * process module and design timescales
2919  * this is needed before any conversion of delay constant expressions
2920  * to ticks
2921  * notice storing inverse so higher value is smaller time
2922  */
__process_timescales(void)2923 extern void __process_timescales(void)
2924 {
2925  register struct mod_t *mdp;
2926 
2927  /* notice implied - so 0 is max 1 sec. (10**-0 secs.) */
2928  /* larger units is shorter tick */
2929  __des_timeprec = 0;
2930  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2931   {
2932    if (mdp->mtime_units + mdp->mtime_prec > __des_timeprec)
2933     __des_timeprec = mdp->mtime_units + mdp->mtime_prec;
2934   }
2935  /* unless set %t time format defaults to ticks */
2936  __tfmt_units = __des_timeprec;
2937 
2938  /* next mark all modules with des time units - no scaling needed */
2939  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2940   {
2941    if (mdp->mtime_units == __des_timeprec) mdp->mno_unitcnv = TRUE;
2942   }
2943  bld_timstr_vals();
2944 }
2945 
2946 /*
2947  * routine to build "absolute time" multiplier and suffix for to_timstr
2948  * message times
2949  */
bld_timstr_vals(void)2950 static void bld_timstr_vals(void)
2951 {
2952  register struct mod_t *mdp;
2953 
2954  strcpy(__timstr_unitsuf, "");
2955  __timstr_mult = 1ULL;
2956  __nd_timstr_suf = FALSE;
2957  /* if module has scaled time timstr values need suffix and multiplier */
2958  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2959   {
2960    /* if not no unit conversion need absolute times */
2961    if (!mdp->mno_unitcnv) { __nd_timstr_suf = TRUE; break; }
2962   }
2963  /* if all modules have same time unit (no matter what), timstr no units */
2964  if (!__nd_timstr_suf) return;
2965 
2966  /* if any differ, need absolute units but still not scaled to module */
2967  /* i.e. value will be absolute time of tick */
2968  switch (__des_timeprec) {
2969   case 0:
2970    __timstr_mult = 1ULL;
2971    strcpy(__timstr_unitsuf, " s");
2972    break;
2973   case 1:
2974    __timstr_mult = 100ULL;
2975    strcpy(__timstr_unitsuf, " ms");
2976    break;
2977   case 2:
2978    __timstr_mult = 10ULL;
2979    strcpy(__timstr_unitsuf, " ms");
2980    break;
2981   case 3:
2982    __timstr_mult = 1ULL;
2983    strcpy(__timstr_unitsuf, " ms");
2984    break;
2985   case 4:
2986    __timstr_mult = 100ULL;
2987    strcpy(__timstr_unitsuf, " us");
2988    break;
2989   case 5:
2990    __timstr_mult = 10ULL;
2991    strcpy(__timstr_unitsuf, " us");
2992    break;
2993   case 6:
2994    __timstr_mult = 1ULL;
2995    strcpy(__timstr_unitsuf, " us");
2996    break;
2997   case 7:
2998    __timstr_mult = 100ULL;
2999    strcpy(__timstr_unitsuf, " ns");
3000    break;
3001   case 8:
3002    __timstr_mult = 10ULL;
3003    strcpy(__timstr_unitsuf, " ns");
3004    break;
3005   case 9:
3006    __timstr_mult = 1ULL;
3007    strcpy(__timstr_unitsuf, " ns");
3008    break;
3009   case 10:
3010    __timstr_mult = 100ULL;
3011    strcpy(__timstr_unitsuf, " ps");
3012    break;
3013   case 11:
3014    __timstr_mult = 10ULL;
3015    strcpy(__timstr_unitsuf, " ps");
3016    break;
3017   case 12:
3018    __timstr_mult = 1ULL;
3019    strcpy(__timstr_unitsuf, " ps");
3020    break;
3021   case 13:
3022    __timstr_mult = 100ULL;
3023    strcpy(__timstr_unitsuf, " fs");
3024    break;
3025   case 14:
3026    __timstr_mult = 10ULL;
3027    strcpy(__timstr_unitsuf, " fs");
3028    break;
3029   case 15:
3030    __timstr_mult = 1ULL;
3031    strcpy(__timstr_unitsuf, " fs");
3032    break;
3033  default: __case_terr(__FILE__, __LINE__);
3034  }
3035 }
3036 
3037 /*
3038  * ROUTINES TO MARK PARAMS THAT EFFECT EXPRESSION WIDTHS
3039  */
3040 
3041 /*
3042  * mark all parameters that are in ranges or cats (or port def. psels)
3043  *
3044  * called first time when module is target of xmr defparam that needs to
3045  * be split
3046  *
3047  * this marks all param net_t's that can effect width so that splitting is
3048  * needed but unless actual xmr defparam marked, does not cause splitting
3049  */
__mark_widdet_params(struct mod_t * pmdp)3050 extern void __mark_widdet_params(struct mod_t *pmdp)
3051 {
3052  struct task_t *tskp;
3053 
3054  /* check all wire and array declaration ranges - mark any param there */
3055  inrnges_mark_params(pmdp->msymtab);
3056 
3057  /* task list contains all symbols in task but if has named blocks */
3058  /* symbols declared there will be checked in its task on list */
3059  for (tskp = pmdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3060   inrnges_mark_params(tskp->tsksymtab);
3061 
3062  /* for all modules since checked before splitting port header range */
3063  /* params already marked */
3064 
3065  /* finally find all psel params in any expressions */
3066  /* insts, contas, task/functions, statements */
3067  /* also any bit select expression connecting to output or inout port */
3068  psel_set_allexprs(pmdp);
3069 }
3070 
3071 /*
3072  * mark all parameters in declaration ranges for one symbol table
3073  *
3074  * by here know symbol table format frozen form
3075  * must use symbol table because may not have nets list built when called
3076  */
inrnges_mark_params(struct symtab_t * sytp)3077 static void inrnges_mark_params(struct symtab_t *sytp)
3078 {
3079  register int32 syi;
3080  struct sy_t **syms;
3081  struct sy_t *syp;
3082  struct net_t *np;
3083 
3084  for (syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
3085   {
3086    syp = syms[syi];
3087    if (syp->sytyp != SYM_N) continue;
3088    np = syp->el.enp;
3089 
3090    /* set in cat or range bit for wire range params */
3091    if (np->n_isavec)
3092     {
3093      __in_xpr_markparam(np->nu.ct->nx1);
3094      __in_xpr_markparam(np->nu.ct->nx2);
3095     }
3096    /* set in cat or range bit for array range params */
3097    if (np->n_isarr)
3098     {
3099      __in_xpr_markparam(np->nu.ct->ax1);
3100      __in_xpr_markparam(np->nu.ct->ax2);
3101     }
3102   }
3103 }
3104 
3105 /*
3106  * set the width determining bit for any wire in expressions
3107  * caller determined is expression used in width determing place
3108  *
3109  * expression not yet checked but just marks IDs that are there
3110  * may mark wrong internal select params but selects here will cause
3111  * error later since must be constant expr.
3112  * any parameter including in "from param" select marked here
3113  */
__in_xpr_markparam(struct expr_t * xp)3114 extern void __in_xpr_markparam(struct expr_t *xp)
3115 {
3116  struct net_t *np;
3117 
3118  if (__isleaf(xp))
3119   {
3120    if (xp->optyp == ID && xp->lu.sy->sytyp == SYM_N)
3121     {
3122      np = xp->lu.sy->el.enp;
3123      if (np->n_isaparam)
3124       {
3125        np->nu.ct->n_widthdet = TRUE;
3126        __inst_mod->mhas_widthdet = TRUE;
3127       }
3128     }
3129    return;
3130   }
3131  if (xp->lu.x != NULL) __in_xpr_markparam(xp->lu.x);
3132  if (xp->ru.x != NULL) __in_xpr_markparam(xp->ru.x);
3133 }
3134 
3135 /*
3136  * mark params in all part selects and CATREP lhs repeat expressions
3137  * and tran out bit select ranges anywhere in module
3138  *
3139  * width determining marked for params used in array of gate or inst
3140  * ranges - only cause split if marked param a def or pound param and
3141  * really needs to cause containing module to be split
3142  */
psel_set_allexprs(struct mod_t * pmdp)3143 static void psel_set_allexprs(struct mod_t *pmdp)
3144 {
3145  register int32 pi, j;
3146  register struct inst_t *ip;
3147  register struct gate_t *gp;
3148  int32 pnum, skip_giarr;
3149  struct task_t *tskp;
3150  struct conta_t *cap;
3151  struct ialst_t *ialp;
3152  struct expr_t *xp;
3153  struct mod_pin_t *mpp;
3154  struct mod_t *down_mdp;
3155  struct net_t *np;
3156  struct giarr_t *giap;
3157 
3158  /* any part select in module except specify where no defparams possible */
3159  if ((pnum = pmdp->mpnum) != 0)
3160   {
3161    /* mark for module ports */
3162    for (pi = 0; pi < pnum; pi++)
3163     { mpp = &(pmdp->mpins[pi]); inpsel_xpr_markparam(mpp->mpref); }
3164   }
3165  giap = NULL;
3166  for (j = 0; j < pmdp->minum; j++)
3167   {
3168    ip = &(pmdp->minsts[j]);
3169    /* for array of instances, need master ip in giarr */
3170    if (pmdp->miarr != NULL && (giap = pmdp->miarr[j]) != NULL)
3171     skip_giarr = TRUE;
3172    else skip_giarr = FALSE;
3173 
3174    down_mdp = ip->imsym->el.emdp;
3175    for (pi = 0; pi < (int32) down_mdp->mpnum; pi++)
3176     {
3177      xp = ip->ipins[pi];
3178      /* DBG remove --- */
3179      if (xp == NULL) __misc_terr(__FILE__, __LINE__);
3180      /* --- */
3181 
3182      /* this will mark any part select even those that for arrays of insts */
3183      /* become bit selects */
3184      inpsel_xpr_markparam(xp);
3185 
3186      /* instance connection bit selects to inout or output ports must be */
3187      /* width det because effects tran channels */
3188      mpp = &(down_mdp->mpins[pi]);
3189      if (xp->optyp == LSB)
3190       {
3191        /* 05/19/01 SJM - for input and output that are param bsel from net */
3192        /* must mark as splittable if relevant param passed down */
3193        if (mpp->mptyp == IO_IN)
3194         {
3195          /* 06/01/01 SJM - if XMR, must always mark */
3196          if (xp->lu.x->optyp != ID) __in_xpr_markparam(xp->ru.x);
3197          else
3198           {
3199            np = xp->lu.x->lu.sy->el.enp;
3200            if (np->ntyp < NONWIRE_ST) __in_xpr_markparam(xp->ru.x);
3201           }
3202          continue;
3203         }
3204        if (mpp->mptyp == IO_BID || mpp->mptyp == IO_OUT)
3205         __in_xpr_markparam(xp->ru.x);
3206       }
3207     }
3208    /* routine always called after inst arrays expanded into per bit but */
3209    /* before connections apportioned to each expanded inst. - just do first */
3210    if (skip_giarr)
3211     {
3212      /* DBG remove -- */
3213      if (!giap->gia_xpnd) __misc_terr(__FILE__, __LINE__);
3214      if (giap->gia_bi != j) __misc_terr(__FILE__, __LINE__);
3215      /* --- */
3216      j += __get_giarr_wide(giap) - 1;
3217     }
3218   }
3219  for (cap = pmdp->mcas; cap != NULL; cap = cap->pbcau.canxt)
3220   {
3221    inpsel_xpr_markparam(cap->lhsx);
3222    if (cap->lhsx->optyp == LSB)
3223     {
3224      /* if conta output could drive path dest. cannot be IS form */
3225      np = cap->lhsx->lu.x->lu.sy->el.enp;
3226      if (np->iotyp == IO_OUT || np->iotyp == IO_BID)
3227       { __in_xpr_markparam(cap->lhsx->ru.x); continue; }
3228     }
3229    inpsel_xpr_markparam(cap->rhsx);
3230   }
3231 
3232  /* bit selects not width determining, except determines tran channel */
3233  /* for trans */
3234  /* now gates outputs that are IS form bit selects are ok just not acc. */
3235  for (j = 0; j < pmdp->mgnum; j++)
3236   {
3237    gp = &(pmdp->mgates[j]);
3238 
3239    /* array of gates is only place part select allowed */
3240    /* any parameter used in part select is potentially width determing */
3241    /* reason is that for width 1 will be replicated and for other widths */
3242    /* will be apportioned so must split containing module */
3243    if (pmdp->mgarr != NULL && (giap = pmdp->mgarr[j]) != NULL)
3244     {
3245      skip_giarr = TRUE;
3246      for (pi = 0; pi < (int32) gp->gpnum; pi++)
3247       {
3248        xp = gp->gpins[pi];
3249        inpsel_xpr_markparam(xp);
3250       }
3251     }
3252    else skip_giarr = FALSE;
3253 
3254    if (gp->g_class != GC_TRAN || gp->g_class == GC_TRANIF)
3255     {
3256      if (gp->gpins[0]->optyp == LSB)
3257       {
3258        /* 06/01/01 - if connection is xmr can never be port */
3259        if (gp->gpins[0]->lu.x->optyp != ID) goto nxt_gate;
3260 
3261        /* if gate output could drive path dest. cannot be IS form */
3262        np = gp->gpins[0]->lu.x->lu.sy->el.enp;
3263 
3264        if (np->iotyp == IO_OUT || np->iotyp == IO_BID)
3265         { __in_xpr_markparam(gp->gpins[0]->ru.x); goto nxt_gate; }
3266       }
3267      goto nxt_gate;
3268     }
3269    /* for trans any bit select in either inout port is width determining */
3270    xp = gp->gpins[0];
3271    if (xp->optyp == LSB) __in_xpr_markparam(xp->ru.x);
3272    /* mark the output bit select range - if present */
3273    xp = gp->gpins[1];
3274    if (xp->optyp == LSB) __in_xpr_markparam(xp->ru.x);
3275 
3276    /* routine always called after gate arrays expanded into per bit but */
3277    /* before connections apportioned to each expanded inst. - just do first */
3278 nxt_gate:
3279    if (skip_giarr)
3280     {
3281      /* DBG remove -- */
3282      if (!giap->gia_xpnd) __misc_terr(__FILE__, __LINE__);
3283      if (giap->gia_bi != j) __misc_terr(__FILE__, __LINE__);
3284      /* --- */
3285      j += (__get_giarr_wide(giap) - 1);
3286     }
3287   }
3288  /* notice processing name blocks here not inline */
3289  for (tskp = pmdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3290   lstofsts_do_inpsel_set(tskp->tskst);
3291  /* initial/always can only be stmt here - maybe extra added at prep. */
3292  for (ialp = pmdp->ialst; ialp != NULL; ialp = ialp->ialnxt)
3293   lstofsts_do_inpsel_set(ialp->iastp);
3294  /* notice defparams cannot effect specify section */
3295 }
3296 
3297 /*
3298  * mark all psels in concatenates in any statement expr.
3299  */
stmt_do_inpsel_set(struct st_t * stp)3300 static void stmt_do_inpsel_set(struct st_t *stp)
3301 {
3302  struct csitem_t *dflt_csip;
3303 
3304  switch ((byte) stp->stmttyp) {
3305   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA: case S_NBPROCA:
3306    inpsel_xpr_markparam(stp->st.spra.lhsx);
3307    inpsel_xpr_markparam(stp->st.spra.rhsx);
3308    break;
3309   case S_IF:
3310    inpsel_xpr_markparam(stp->st.sif.condx);
3311    lstofsts_do_inpsel_set(stp->st.sif.thenst);
3312    lstofsts_do_inpsel_set(stp->st.sif.elsest);
3313    break;
3314   case S_CASE:
3315    inpsel_xpr_markparam(stp->st.scs.csx);
3316    /* first is always default - st nil if no default */
3317    dflt_csip = stp->st.scs.csitems;
3318    csitemlst_do_inpsel_set(dflt_csip->csinxt);
3319    if (dflt_csip->csist != NULL) lstofsts_do_inpsel_set(dflt_csip->csist);
3320    break;
3321   case S_FOREVER:
3322   case S_WHILE:
3323    inpsel_xpr_markparam(stp->st.swh.lpx);
3324    lstofsts_do_inpsel_set(stp->st.swh.lpst);
3325    break;
3326   case S_WAIT:
3327    inpsel_xpr_markparam(stp->st.swait.lpx);
3328    lstofsts_do_inpsel_set(stp->st.swait.lpst);
3329    break;
3330   case S_REPEAT:
3331    inpsel_xpr_markparam(stp->st.srpt.repx);
3332    lstofsts_do_inpsel_set(stp->st.srpt.repst);
3333    break;
3334   case S_FOR:
3335    {
3336     struct for_t *frp;
3337 
3338     frp = stp->st.sfor;
3339     stmt_do_inpsel_set(frp->forassgn);
3340     inpsel_xpr_markparam(frp->fortermx);
3341     stmt_do_inpsel_set(frp->forinc);
3342     lstofsts_do_inpsel_set(frp->forbody);
3343    }
3344    break;
3345   case S_DELCTRL:
3346    /* do not need to check delay expression - width will resolve to WBITS */
3347    lstofsts_do_inpsel_set(stp->st.sdc->actionst);
3348    break;
3349   case S_NAMBLK:
3350    /* do not need to process here - done when set bits for tasks defs */
3351    break;
3352   case S_UNBLK:
3353    lstofsts_do_inpsel_set(stp->st.sbsts);
3354    break;
3355   case S_UNFJ:
3356    {
3357     register int32 fji;
3358     struct st_t *fjstp;
3359 
3360     for (fji = 0;; fji++)
3361      {
3362       if ((fjstp = stp->st.fj.fjstps[fji]) == NULL) break;
3363       /* SJM 09/24/01 - this can be 2 stmts for for (for assgn then for) */
3364       lstofsts_do_inpsel_set(fjstp);
3365      }
3366    }
3367    break;
3368   case S_TSKCALL:
3369    {
3370     register struct expr_t *xp;
3371 
3372     for (xp = stp->st.stkc.targs; xp != NULL; xp = xp->ru.x)
3373      inpsel_xpr_markparam(xp->lu.x);
3374    }
3375    break;
3376   case S_QCONTA:
3377    inpsel_xpr_markparam(stp->st.sqca->qclhsx);
3378    inpsel_xpr_markparam(stp->st.sqca->qcrhsx);
3379    break;
3380   case S_CAUSE: case S_DSABLE: case S_NULL: case S_STNONE: case S_QCONTDEA:
3381    break;
3382   default: __case_terr(__FILE__, __LINE__);
3383  }
3384 }
3385 
3386 /*
3387  * process each statements of statement list for in psel exprs
3388  */
lstofsts_do_inpsel_set(register struct st_t * stp)3389 static void lstofsts_do_inpsel_set(register struct st_t *stp)
3390 {
3391  for (; stp != NULL; stp = stp->stnxt) stmt_do_inpsel_set(stp);
3392 }
3393 
csitemlst_do_inpsel_set(register struct csitem_t * csip)3394 static void csitemlst_do_inpsel_set(register struct csitem_t *csip)
3395 {
3396  register struct exprlst_t *xplp;
3397 
3398  for (; csip != NULL; csip = csip->csinxt)
3399   {
3400    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
3401     inpsel_xpr_markparam(xplp->xp);
3402    lstofsts_do_inpsel_set(csip->csist);
3403   }
3404 }
3405 
3406 /*
3407  * mark any param that is appears inside any part select range
3408  * as sell as any CATREP repeat count expressions
3409  *
3410  * must process every module expr. through here if module target of
3411  * xmr defparam and multiply instantiated
3412  * since nested concatenates not yet expanded must handle nesting
3413  */
inpsel_xpr_markparam(struct expr_t * xp)3414 static void inpsel_xpr_markparam(struct expr_t *xp)
3415 {
3416  /* loop statements expr. can be nil */
3417  if (xp == NULL) return;
3418 
3419  switch ((byte) xp->optyp) {
3420   case ID: case GLBREF: case NUMBER: case ISNUMBER:
3421   case REALNUM: case ISREALNUM:
3422    return;
3423   case PARTSEL:
3424    __in_xpr_markparam(xp->ru.x->lu.x);
3425    __in_xpr_markparam(xp->ru.x->ru.x);
3426    return;
3427   case CATREP:
3428    inpsel_xpr_markparam(xp->lu.x);
3429    if (xp->ru.x != NULL) inpsel_xpr_markparam(xp->ru.x);
3430    return;
3431   }
3432  /* for here can have expr. like a + {...} inside concat - so descend */
3433  if (xp->lu.x != NULL) inpsel_xpr_markparam(xp->lu.x);
3434  if (xp->ru.x != NULL) inpsel_xpr_markparam(xp->ru.x);
3435 }
3436 
3437 /*
3438  * MODULE LEVEL DECLARATION CHECKING ROUTINES
3439  */
3440 
3441 /*
3442  * check undefined symbol and freeze ranges (eval. defparam rhs exprs)
3443  * must stop if any pass 1 errors before calling this
3444  */
__chk_1mdecls(void)3445 extern void __chk_1mdecls(void)
3446 {
3447  register struct task_t *tskp;
3448  int32 tregbasi;
3449 
3450  chk_undef_syms(__inst_mod->msymtab, MODULE);
3451 
3452  /* this also counts number of regs in tasks and set all nnum fields */
3453  chkset_1mwire_rnges();
3454 
3455  /* must check task variables before any statement checking because of */
3456  /* xmrs - notice named blocked included here */
3457  tregbasi = __inst_mod->mnnum;
3458  for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3459   {
3460    chk_taskvars(tskp, tregbasi);
3461    tregbasi += tskp->trnum;
3462   }
3463 
3464 }
3465 
3466 /*
3467  * check all symbols in given table (module/task/func/lab. block)
3468  * notice this cannot be used to check decl. of specify specparams
3469  */
chk_undef_syms(struct symtab_t * sytp,word32 objttyp)3470 static void chk_undef_syms(struct symtab_t *sytp, word32 objttyp)
3471 {
3472  register int32 syi;
3473  int32 save_obj;
3474  struct sy_t *syp;
3475 
3476  __wrkstab = sytp->stsyms;
3477  save_obj = __cur_declobj;
3478  __cur_declobj = objttyp;
3479  for (syi = 0; syi < (int32) sytp->numsyms; syi++)
3480   {
3481    syp = __wrkstab[syi];
3482    chk_modsym(syp);
3483   }
3484  __cur_declobj = save_obj;
3485 }
3486 
3487 /*
3488  * check one symbol
3489  */
chk_modsym(struct sy_t * syp)3490 static void chk_modsym(struct sy_t *syp)
3491 {
3492  switch ((byte) syp->sytyp) {
3493   /* params still in symbol table but cannot be undeclared so works */
3494   case SYM_N:
3495    if (__cur_declobj == MODULE) chk_1wire(syp->el.enp);
3496    else chk_1reg(syp->el.enp);
3497    break;
3498   case SYM_TSK: case SYM_F: case SYM_STSK: case SYM_SF:
3499    if (!syp->sydecl)
3500     __gferr(770, syp->syfnam_ind, syp->sylin_cnt,
3501      "%s %s not declared", __to_sytyp(__xs, syp->sytyp), syp->synam);
3502    break;
3503   /* since non legal in expr. symbol error caught elsewhere */
3504   case SYM_CA: case SYM_TCHK: case SYM_PTH: break;
3505   /* things checked elsewhere that can be in mod. sym. table */
3506   /* and are declared by usage */
3507   case SYM_I: case SYM_LB: case SYM_UDP: case SYM_PRIM:
3508   break;
3509  default:
3510   /* symbol decl. lost */
3511   __misc_gfterr(__FILE__, __LINE__, syp->syfnam_ind, syp->sylin_cnt);
3512  }
3513 }
3514 
3515 /*
3516  * check 1 wire - just makes sure declared - must check attributes later
3517  * wire here just means not in task/func.
3518  */
chk_1wire(struct net_t * np)3519 static void chk_1wire(struct net_t *np)
3520 {
3521  struct sy_t *syp;
3522 
3523  syp = np->nsym;
3524  if (!syp->sydecl)
3525   {
3526    if (syp->sytyp == SYM_CA || syp->sytyp == SYM_PTH
3527    || syp->sytyp == SYM_TCHK)
3528     {
3529      __gferr(1147, syp->syfnam_ind, syp->sylin_cnt,
3530       "constructed internal %s %s may not appear in source - only as run time string",
3531       __to_sytyp(__xs, syp->sytyp), syp->synam);
3532      return;
3533     }
3534    if (np->iotyp == NON_IO)
3535     {
3536      __gferr(771, syp->syfnam_ind, syp->sylin_cnt,
3537       "wire/reg/event %s not declared", syp->synam);
3538     }
3539    else
3540     __gferr(772, syp->syfnam_ind, syp->sylin_cnt,
3541      "module definition port %s not declared", syp->synam);
3542    return;
3543   }
3544  /* LOOKATME - what trireg checking needed */
3545 }
3546 
3547 /*
3548  * check 1 task/function/named block wire
3549  * this can check everything because task declarations all at top
3550  *
3551  * this rotine is called through sybmol table checking for tasks
3552  */
chk_1reg(struct net_t * np)3553 static void chk_1reg(struct net_t *np)
3554 {
3555  struct sy_t *syp;
3556 
3557  syp = np->nsym;
3558  if (!syp->sydecl)
3559   {
3560    __gferr(773, syp->syfnam_ind, syp->sylin_cnt,
3561     "task/function/named block reg %s not declared", syp->synam);
3562    return;
3563   }
3564 }
3565 
3566 /*
3567  * check and set the module's wire ranges
3568  *
3569  * also preprocesses wire delays to simulation form and builds wire tab by
3570  * copying list elements to table and freeing list
3571  * notice key is that nothing before here points directly to net
3572  * always through symbol table which is also updated here
3573  *
3574  * routine is passed total number of vars in modules so all vars
3575  * including task regs are contigous and can be accessed as offset
3576  * from mod base
3577  *
3578  */
chkset_1mwire_rnges(void)3579 static void chkset_1mwire_rnges(void)
3580 {
3581  register int32 syi, ni;
3582  register struct sy_t *syp;
3583  register struct net_t *np;
3584  int32 dnum, nnum, mvarnum;
3585  struct sy_t **syms;
3586  struct symtab_t *sytp;
3587  struct net_t *ntab, *np2;
3588  struct paramlst_t *pmp, *dhdr;
3589  struct task_t *tskp;
3590 
3591  sytp = __inst_mod->msymtab;
3592  /* count number of nets and store in mod field */
3593  nnum = 0;
3594  for (syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
3595   {
3596    syp = syms[syi];
3597 
3598    if (syp->sytyp != SYM_N) continue;
3599    np = syp->el.enp;
3600    if (!np->n_isaparam) nnum++;
3601   }
3602  __inst_mod->mnnum = nnum;
3603  mvarnum = nnum;
3604 
3605  /* then count number of regs in each task - set and keep running total */
3606  for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3607   {
3608    sytp = tskp->tsksymtab;
3609    nnum = 0;
3610    for (syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
3611     {
3612      syp = syms[syi];
3613      if (syp->sytyp != SYM_N) continue;
3614      np = syp->el.enp;
3615      if (np->n_isaparam) continue;
3616      nnum++;
3617     }
3618    tskp->trnum = nnum;
3619    mvarnum += nnum;
3620   }
3621  /* set total nnumber of vars in module for possible use by dmpv */
3622  __inst_mod->mtotvarnum = mvarnum;
3623 
3624  ntab = NULL;
3625  if (mvarnum != 0)
3626   {
3627    ntab = (struct net_t *) __my_malloc(mvarnum*sizeof(struct net_t));
3628   }
3629 
3630  /* SJM 08/30/00 must include task nets here in case only task's have */
3631  /* declared variables */
3632  if (__inst_mod->mtotvarnum == 0) return;
3633  __inst_mod->mnets = ntab;
3634 
3635  /* fixing task vars in ntab later */
3636  /* point sytp back to mod not task symbol table */
3637  sytp = __inst_mod->msymtab;
3638  /* not sure if saved needed here */
3639  for (ni = 0, syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
3640   {
3641    syp = syms[syi];
3642    if (syp->sytyp != SYM_N) continue;
3643 
3644    np = syp->el.enp;
3645    /* parameters checked elsewhere */
3646    if (np->n_isaparam) continue;
3647 
3648 
3649    np2 = &(ntab[ni]);
3650    *np2 = *np;
3651    __my_free((char *) np, sizeof(struct net_t));
3652    syp->el.enp = np2;
3653    ni++;
3654    np = np2;
3655 
3656    /* do not need to save these, never called with previous location */
3657    __sfnam_ind = np->nsym->syfnam_ind;
3658    __slin_cnt = np->nsym->sylin_cnt;
3659 
3660    chk_wire_rng(np);
3661 
3662    /* LOOKATME - maybe should allow expressions here but lrm says no */
3663    /* can process expression at this early point since final value */
3664    /* of all parameters know by here */
3665    if ((pmp = np->nu.ct->n_dels_u.pdels) != NULL)
3666     {
3667      dhdr = __copy_dellst(pmp);
3668      if ((dnum = __chk_delparams(dhdr, "wire delay", TRUE)) == -1)
3669       np->nu.ct->n_dels_u.pdels = NULL;
3670      else
3671       {
3672        if (dnum > 3)
3673         {
3674          __sgferr(792,
3675           "wire delay for %s has more then 3 delays (%d)", np->nsym->synam,
3676           dnum);
3677          np->nu.ct->n_dels_u.pdels = NULL;
3678         }
3679       }
3680      __free_dellst(dhdr);
3681     }
3682   }
3683 }
3684 
3685 /*
3686  * debugging routine to dump net names of all nets in all modules
3687  */
__dbg_dmpall_nets(void)3688 extern void __dbg_dmpall_nets(void)
3689 {
3690  register struct mod_t *mdp;
3691  register struct net_t *np;
3692  register int32 ni;
3693 
3694  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3695   {
3696    __dbg_msg("--- dumping nets for module %s\n", mdp->msym->synam);
3697    if (mdp->mnnum == 0) continue;
3698    for (np = &(mdp->mnets[0]), ni = 0; ni < mdp->mnnum; ni++, np++)
3699     {
3700      __dbg_msg("  setting symbol %s to point to net %s\n",
3701       np->nsym->synam, np->nsym->el.enp->nsym->synam);
3702     }
3703   }
3704 }
3705 
3706 /*
3707  * STRENGTH PROPOGATION TO WIRES ROUTINES
3708  */
3709 
3710 /*
3711  * mark wires that need strength storage and all strength expressions
3712  * notice this is before splitting since strengths structural
3713  */
__mark_st_wires(void)3714 extern void __mark_st_wires(void)
3715 {
3716  /* mark all wires that are strength from type (no wire strength decls) */
3717  mark_sttypewires();
3718  /* mark all wires immediately driven by strengths */
3719  mark_stdr_wires();
3720  mark_stdr_inout_wired_logic();
3721  if (__design_no_strens) return;
3722 
3723  /* must build module type levelized table after all splitting */
3724  /* only used here but not freed since only 4 byte ptr per level */
3725  /* field in mod_t needed anyway */
3726  __bld_mlevel_lists();
3727 
3728  /* SJM 10/16/99 - need to keep propagating until no progress */
3729  /* not sure why this is needed but missing strenght from 4 */
3730  /* know need 4 for shorted inout ports - why more? */
3731  for (;;)
3732   {
3733    __strenprop_chg = FALSE;
3734    prop_stsdown();
3735    /* prop strengths up through mod outs and inouts */
3736    prop_stsup();
3737    /* DBG remove -- */
3738    if (__debug_flg) __dbg_msg("  >>> Complete one strength marking pass.\n");
3739    /* --- */
3740    if (!__strenprop_chg) break;
3741   }
3742 }
3743 
3744 /*
3745  * mark all wires that are strength from decl. type
3746  * know if module in list - will be in output
3747  */
mark_sttypewires(void)3748 static void mark_sttypewires(void)
3749 {
3750  register int32 syi;
3751  register struct mod_t *mdp;
3752  register struct net_t *np;
3753  register struct sy_t *syp;
3754  struct sy_t **syms;
3755  struct symtab_t *sytp;
3756 
3757  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3758   {
3759    sytp = mdp->msymtab;
3760    /* table (array) of nets still not built at this point */
3761    for (syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
3762     {
3763      syp = syms[syi];
3764      if (syp->sytyp != SYM_N) continue;
3765      np = syp->el.enp;
3766 
3767      /* notice N_TRI is just N_WIRE */
3768 
3769      switch ((byte) np->ntyp) {
3770       /* these are always marked strength */
3771       case N_TRIREG: case N_TRI0: case N_TRI1: case N_SUPPLY0:
3772       case N_SUPPLY1:
3773        np->n_stren = TRUE;
3774        mdp->mhassts = TRUE;
3775        __design_no_strens = FALSE;
3776 
3777        /* --- DBG remove
3778        if (__debug_flg)
3779         __dbg_msg("++marking direct decl. type wire %s in %s\n", np->nsym->synam,
3780          mdp->msym->synam);
3781        --- */
3782 
3783        break;
3784      }
3785     }
3786   }
3787 }
3788 
3789 /*
3790  * for every module mark wire that are driven by strengths
3791  * notice explicit conta output driving strength is treated as no strength
3792  * think that may be wrong.
3793  */
mark_stdr_wires(void)3794 static void mark_stdr_wires(void)
3795 {
3796  register int32 gi;
3797  register struct mod_t *mdp;
3798  register struct conta_t *cap;
3799  int32 i, skip_giarr;
3800  struct gate_t *gp;
3801  struct giarr_t *giap;
3802 
3803  giap = NULL;
3804  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3805   {
3806    for (gi = 0; gi < mdp->mgnum; gi++)
3807     {
3808      gp = &(mdp->mgates[gi]);
3809      if (mdp->mgarr != NULL && (giap = mdp->mgarr[gi]) != NULL)
3810       skip_giarr = TRUE;
3811      else skip_giarr = FALSE;
3812 
3813      switch ((byte) gp->g_class) {
3814       case GC_PULL:
3815        /* pull all connections */
3816        for (i = 0; i < (int32) gp->gpnum; i++)
3817         { mark_stwires(mdp, gp->gpins[i]); }
3818        break;
3819       case GC_MOS: case GC_TRAN: case GC_TRANIF: case GC_CMOS:
3820        /* mos or tran gates first 2 ports only - rest are controls */
3821        mark_stwires(mdp, gp->gpins[0]);
3822        mark_stwires(mdp, gp->gpins[1]);
3823        break;
3824       case GC_BUFIF:
3825        /* buffer only output is strength */
3826        mark_stwires(mdp, gp->gpins[0]);
3827        break;
3828       case GC_LOGIC: case GC_UDP:
3829        /* logic only mark output if has strength */
3830        if (gp->g_hasst && gp->g_stval != ST_STRVAL)
3831         mark_stwires(mdp, gp->gpins[0]);
3832        break;
3833       }
3834      if (skip_giarr) gi += (__get_giarr_wide(giap) - 1);
3835     }
3836    for (cap = mdp->mcas; cap != NULL; cap = cap->pbcau.canxt)
3837     {
3838      if (!cap->ca_hasst || cap->ca_stval == ST_STRVAL) continue;
3839      /* 1 bit continuous assign not converted to gate at this point */
3840      mark_stwires(mdp, cap->lhsx);
3841     }
3842   }
3843 }
3844 
3845 /*
3846  * routine to mark wires in port highconn or lowconn that have wired logic
3847  * stren model - needed so will use wire type incremental switch relax proc
3848  *
3849  * 04/22/01 SJM - changed so wand/wor in inout port hi/low conn always stren
3850  */
mark_stdr_inout_wired_logic(void)3851 static void mark_stdr_inout_wired_logic(void)
3852 {
3853  register int32 ii, pi;
3854  register struct mod_t *mdp;
3855  int32 pnum;
3856  struct mod_pin_t *mpp;
3857  struct inst_t *ip;
3858  struct mod_t *imdp;
3859  struct expr_t *xp;
3860 
3861  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3862   {
3863    /* if inout port and lowconn wor/wand, mark port expr as stren */
3864    for (pi = 0; pi < mdp->mpnum; pi++)
3865     {
3866      mpp = &(mdp->mpins[pi]);
3867      if (mpp->mptyp != IO_BID) continue;
3868 
3869      if (has_non_stren_wired_net(mpp->mpref))
3870       mark_stwires(mdp, mpp->mpref);
3871     }
3872 
3873    /* if iconn highconn wor/wand, mark expr as stren */
3874    for (ii = 0; ii < mdp->minum; ii++)
3875     {
3876      ip = &(mdp->minsts[ii]);
3877      imdp = ip->imsym->el.emdp;
3878      if ((pnum = imdp->mpnum) == 0) continue;
3879 
3880      for (pi = 0; pi < pnum; pi++)
3881       {
3882        mpp = &(imdp->mpins[pi]);
3883        if (mpp->mptyp != IO_BID) continue;
3884 
3885        xp = ip->ipins[pi];
3886        if (has_non_stren_wired_net(xp)) mark_stwires(imdp, xp);
3887       }
3888     }
3889   }
3890 }
3891 
3892 /*
3893  * return T if inout (lhs) expr, has wand or wor port
3894  */
has_non_stren_wired_net(struct expr_t * lhsx)3895 static int32 has_non_stren_wired_net(struct expr_t *lhsx)
3896 {
3897  register struct expr_t *catndp;
3898  register struct net_t *np;
3899 
3900  switch ((byte) lhsx->optyp) {
3901   /* SJM 07/10/01 - if later syntax error non lvalues possible here */
3902   case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
3903    break;
3904   case ID: case GLBREF:
3905    np = lhsx->lu.sy->el.enp;
3906    if (net_type_tri(np->ntyp)) return(TRUE);
3907    break;
3908   case LSB: case PARTSEL:
3909    np = lhsx->lu.x->lu.sy->el.enp;
3910    if (net_type_tri(np->ntyp)) return(TRUE);
3911    break;
3912   case LCB:
3913    for (catndp = lhsx->ru.x; catndp != NULL; catndp = catndp->ru.x)
3914     {
3915      if (has_non_stren_wired_net(catndp->lu.x)) return(TRUE);
3916     }
3917    break;
3918   default: __case_terr(__FILE__, __LINE__);
3919  }
3920  return(FALSE);
3921 }
3922 
3923 /*
3924  * return T if net type is wand or wor (wired logic)
3925  */
net_type_tri(word32 ntyp)3926 static int32 net_type_tri(word32 ntyp)
3927 {
3928  switch ((byte) ntyp) {
3929   case N_TRIOR: case N_WO: case N_TRIAND: case N_WA: return(TRUE);
3930   default: break;
3931  }
3932  return(FALSE);
3933 }
3934 
3935 /*
3936  * check to see if expr has any stren wires, if yes return T else F
3937  *
3938  * SJM 06/01/01 - need separate check routine because must return
3939  * T if any concat el has stren but must always set all elements
3940  * logic for combined routine was wrong
3941  */
chk_hasst_wires(struct mod_t * mdp,struct expr_t * lhsx)3942 static int32 chk_hasst_wires(struct mod_t *mdp, struct expr_t *lhsx)
3943 {
3944  struct net_t *np;
3945 
3946  switch ((byte) lhsx->optyp) {
3947    /* if global has driven strength - all instances of wire must be */
3948    /* strength */
3949   case GLBREF: case ID:
3950    np = lhsx->lu.sy->el.enp;
3951    break;
3952   case LSB: case PARTSEL:
3953    /* this is bit select or array index */
3954    np = lhsx->lu.x->lu.sy->el.enp;
3955    break;
3956   case LCB:
3957    {
3958     register struct expr_t *ndp2;
3959 
3960     /* know lhs concatenates never nested */
3961     for (ndp2 = lhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
3962      {
3963       /* if any strength, must other must be marked */
3964       if (chk_hasst_wires(mdp, ndp2->lu.x)) return(TRUE);
3965      }
3966     return(FALSE);
3967    }
3968   default: return(FALSE);
3969  }
3970  /* know if non wire, n stren never true */
3971  if (np->n_stren) return(TRUE);
3972  return(FALSE);
3973 }
3974 
3975 /*
3976  * for lhs expression driven with strength mark all wires
3977  * if not good lhs, ignore error caught later
3978  *
3979  * SJM 06/01/15 - change so separate mark routine
3980  */
mark_stwires(struct mod_t * mdp,struct expr_t * lhsx)3981 static void mark_stwires(struct mod_t *mdp, struct expr_t *lhsx)
3982 {
3983  struct net_t *np;
3984 
3985  switch ((byte) lhsx->optyp) {
3986    /* if global has driven strength - all instances of wire must be */
3987    /* strength */
3988   case GLBREF: case ID:
3989    np = lhsx->lu.sy->el.enp;
3990    break;
3991   case LSB: case PARTSEL:
3992    /* this is bit select or array index */
3993    np = lhsx->lu.x->lu.sy->el.enp;
3994    break;
3995   case LCB:
3996    {
3997     register struct expr_t *ndp2;
3998 
3999     /* know lhs concatenates never nested */
4000     /* mark all - if some els already marked, does nothing */
4001     for (ndp2 = lhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4002      { mark_stwires(mdp, ndp2->lu.x); }
4003     return;
4004    }
4005   default: return;
4006  }
4007  /* must be wire to have strength */
4008  if (np->ntyp >= NONWIRE_ST) return;
4009 
4010  /* SJM 10/15/99 - if mark and already marked, just return T */
4011  if (!np->n_stren)
4012   {
4013    /* --- DBG remove */
4014    if (__debug_flg)
4015     __dbg_msg("++marking wire %s in %s\n", np->nsym->synam,
4016      mdp->msym->synam);
4017    /* --- */
4018    np->n_stren = TRUE;
4019    __strenprop_chg = TRUE;
4020    mdp->mhassts = TRUE;
4021    __design_no_strens = FALSE;
4022   }
4023 }
4024 
4025 /*
4026  * build the levelized module type list
4027  *
4028  * this is sometimes called before minsts exists (part of d.s. built)
4029  */
__bld_mlevel_lists(void)4030 extern void __bld_mlevel_lists(void)
4031 {
4032  register struct mod_t *mdp, *last_mdp;
4033  register int32 mlevel;
4034 
4035  /* then build the by level header table and link same level modules on it */
4036  if (__mdlevhdr == NULL)
4037   {
4038    __mdlevhdr = (struct mod_t **)
4039     __my_malloc((__dagmaxdist + 1)*sizeof(struct mod_t *));
4040   }
4041  /* need to initialize this to nil since may be rebuilt */
4042  for (mlevel = 0; mlevel <= __dagmaxdist; mlevel++) __mdlevhdr[mlevel] = NULL;
4043  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt) mdp->mlevnxt = NULL;
4044 
4045  for (mlevel = 0; mlevel <= __dagmaxdist; mlevel++)
4046   {
4047    last_mdp = NULL;
4048    for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4049     {
4050      if (mdp->mlpcnt != mlevel) continue;
4051      if (last_mdp == NULL) __mdlevhdr[mlevel] = mdp;
4052      else last_mdp->mlevnxt = mdp;
4053      last_mdp = mdp;
4054     }
4055   }
4056 }
4057 
4058 /*
4059  * propagate strengths down
4060  *
4061  * 04/22/01 - changed so inout port either highconn or lowonn wired and or or
4062  * now both marked as strength
4063  */
prop_stsdown(void)4064 static void prop_stsdown(void)
4065 {
4066  register int32 pi, ii;
4067  register struct mod_t *smdp;
4068  /* do all max. dag dist. modules first - level 1 has no insts. */
4069  register struct inst_t *ip;
4070  int32 mlevel, pnum, skip_giarr;
4071  struct mod_pin_t *mpp;
4072  struct mod_t *imdp;
4073  struct giarr_t *giap;
4074  struct expr_t *xp;
4075 
4076  /* could stop one up (level 2 (1 from bottom)) here */
4077  giap = NULL;
4078  for (mlevel = __dagmaxdist; mlevel >= 0; mlevel--)
4079   {
4080    for (smdp = __mdlevhdr[mlevel]; smdp != NULL; smdp = smdp->mlevnxt)
4081     {
4082      /* even if no strength must still try to propagate down for */
4083      /* possible unconndrive */
4084      for (ii = 0; ii < smdp->minum; ii++)
4085       {
4086        ip = &(smdp->minsts[ii]);
4087        if (smdp->miarr != NULL && (giap = smdp->miarr[ii]) != NULL)
4088         skip_giarr = TRUE;
4089        else skip_giarr = FALSE;
4090 
4091        imdp = ip->imsym->el.emdp;
4092        if ((pnum = imdp->mpnum) == 0) goto nxt_inst;
4093 
4094        for (pi = 0; pi < pnum; pi++)
4095         {
4096 	 mpp = &(imdp->mpins[pi]);
4097 	 if (mpp->mptyp == IO_OUT) continue;
4098 
4099          xp = ip->ipins[pi];
4100          /* --- DBG remove
4101          if (__debug_flg)
4102           __dbg_msg(
4103            "++trying to prop stren down from %s (in %s) to %s (in %s)\n",
4104            __msgexpr_tostr(__xs, xp), smdp->msym->synam,
4105            __msgexpr_tostr(__xs2, mpp->mpref), imdp->msym->synam);
4106          --- */
4107 
4108          /* if op empty `unconndrive, must propagate st. down */
4109          if (xp->optyp == OPEMPTY && xp->unc_pull != NO_UNCPULL)
4110           { mark_stwires(imdp, mpp->mpref); continue; }
4111 
4112 	 /* if port inst. port has strength, propagate down */
4113          if (chk_hasst_wires(smdp, xp))
4114 	  { mark_stwires(imdp, mpp->mpref); continue; }
4115 	}
4116 nxt_inst:
4117        /* AIV 08/23/04 - was hanging should be += */
4118        if (skip_giarr) ii += (__get_giarr_wide(giap) - 1);
4119       }
4120     }
4121   }
4122 }
4123 
4124 /*
4125  * propagate strengths up
4126  */
prop_stsup(void)4127 static void prop_stsup(void)
4128 {
4129  register int32 pi, ii;
4130  register struct mod_t *smdp;
4131  register struct inst_t *ip;
4132  int32 mlevel, pnum, skip_giarr;
4133  struct mod_pin_t *mpp;
4134  struct mod_t *imdp;
4135  struct giarr_t *giap;
4136  struct expr_t *xp;
4137 
4138  giap = NULL;
4139  /* start up 1 since propagating from one down to current */
4140  for (mlevel = 1; mlevel <= __dagmaxdist; mlevel++)
4141   {
4142    for (smdp = __mdlevhdr[mlevel]; smdp != NULL; smdp = smdp->mlevnxt)
4143     {
4144      /* go through module instances marking down port wires */
4145      for (ii = 0; ii < smdp->minum; ii++)
4146       {
4147        ip = &(smdp->minsts[ii]);
4148        if (smdp->miarr != NULL && (giap = smdp->miarr[ii]) != NULL)
4149         skip_giarr = TRUE;
4150        else skip_giarr = FALSE;
4151 
4152        imdp = ip->imsym->el.emdp;
4153        if ((pnum = imdp->mpnum) == 0) goto nxt_inst;
4154        for (pi = 0; pi < pnum; pi++)
4155         {
4156          mpp = &(imdp->mpins[pi]);
4157          xp = ip->ipins[pi];
4158 	 if (mpp->mptyp == IO_IN) continue;
4159 
4160          /* --- DBG remove
4161          if (__debug_flg)
4162           __dbg_msg(
4163            "++trying to prop stren up from %s (in %s) to %s (in %s)\n",
4164            __msgexpr_tostr(__xs, mpp->mpref), imdp->msym->synam,
4165            __msgexpr_tostr(__xs2, xp), smdp->msym->synam);
4166          --- */
4167 
4168 	 /* if down port has strength, need to propagate up */
4169          if (chk_hasst_wires(imdp, mpp->mpref))
4170           mark_stwires(smdp, xp);
4171 	}
4172 nxt_inst:
4173          if (skip_giarr) ii += (__get_giarr_wide(giap) - 1);
4174       }
4175     }
4176   }
4177 }
4178 
4179 /*
4180  * ROUTINES TO CHECK CONSTANT DELAYS (IGNORES DELAY EXPRS)
4181  */
4182 
4183 /*
4184  * check a list of constant delays and convert to scaled non real ticks
4185  * return number of delays - -1 on error
4186  */
__chk_delparams(struct paramlst_t * pmp2,char * emsg,int32 mustbeconst)4187 extern int32 __chk_delparams(struct paramlst_t *pmp2, char *emsg,
4188  int32 mustbeconst)
4189 {
4190  register struct paramlst_t *pmp;
4191  int32 pmnum, err;
4192 
4193  err = FALSE;
4194  for (pmnum = 0, pmp = pmp2; pmp != NULL; pmp = pmp->pmlnxt, pmnum++)
4195   {
4196    if (!chkdel_expr(pmp->plxndp, emsg, mustbeconst)) err = TRUE;
4197    /* make sure actual delay expressions output as dec. */
4198    pmp->plxndp->ibase = BDEC;
4199    /* param expression evaluted to number during delay prep */
4200   }
4201  if (err) return(-1);
4202  return(pmnum);
4203 }
4204 
4205 /*
4206  * check a delay expression but cannot convert until prep. time
4207  * uses flag mustbeconst to cause error if expr.
4208  * returns F on error
4209  */
chkdel_expr(struct expr_t * dxp,char * emsg,int32 mustbeconst)4210 static int32 chkdel_expr(struct expr_t *dxp, char *emsg,
4211  int32 mustbeconst)
4212 {
4213  int32 sav_ecnt;
4214 
4215  sav_ecnt = __pv_err_cnt;
4216  __chk_rhsexpr(dxp, 0);
4217  if (mustbeconst) return(__chk_numdelay(dxp, emsg));
4218  /* case (procedural for now) where delay can be expression */
4219  if (sav_ecnt != __pv_err_cnt) return(FALSE);
4220  /* delay expr. always output as decimal */
4221  dxp->ibase = BDEC;
4222  return(TRUE);
4223 }
4224 
4225 /*
4226  * check to make sure a delay is a number
4227  * returns F on error
4228  */
__chk_numdelay(struct expr_t * ndp,char * emsg)4229 extern int32 __chk_numdelay(struct expr_t *ndp, char *emsg)
4230 {
4231  switch ((byte) ndp->optyp) {
4232   case NUMBER:
4233    if (!nd_delnum(ndp, emsg)) return(FALSE);
4234    break;
4235   case ISNUMBER:
4236    if (!nd_delisnum(ndp, emsg)) return(FALSE);
4237    break;
4238   case REALNUM: case ISREALNUM: return(TRUE);
4239   default:
4240    __sgferr(845, "non constant %s delay illegal", emsg);
4241    __free2_xtree(ndp);
4242    __init_xnd(ndp);
4243 
4244    /* bad delay must be 0 */
4245    ndp->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
4246    ndp->szu.xclen = WBITS;
4247    ndp->optyp = NUMBER;
4248    return(FALSE);
4249  }
4250  return(TRUE);
4251 }
4252 
4253 /*
4254  * check NUMBER delay to make sure convert in prep. section will succeed
4255  * catches too wide (non 0) and x/z forms - if expr. converts to 0 const.
4256  */
nd_delnum(struct expr_t * ndp,char * emsg)4257 static int32 nd_delnum(struct expr_t *ndp, char *emsg)
4258 {
4259  int32 err, wlen;
4260  word32 *ap, *bp;
4261  struct xstk_t *xsp;
4262 
4263  err = FALSE;
4264  ap = &(__contab[ndp->ru.xvi]);
4265  wlen = wlen_(ndp->szu.xclen);
4266  bp = &(ap[wlen]);
4267  if (ndp->szu.xclen > TIMEBITS)
4268   {
4269    if (!vval_is0_(&(ap[2]), ndp->szu.xclen - TIMEBITS)
4270     || !vval_is0_(bp, ndp->szu.xclen))
4271     {
4272      __force_base = BDEC;
4273      __msgexpr_tostr(__xs, ndp);
4274      __force_base = BNONE;
4275      err = TRUE;
4276     }
4277    /* always free-alloc */
4278    __free2_xtree(ndp);
4279    __init_xnd(ndp);
4280    /* notice if not a number make into 32 bit x */
4281    ndp->optyp = NUMBER;
4282    if (err)
4283     {
4284      ndp->szu.xclen = WBITS;
4285      /* bad delay must be zero */
4286      ndp->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
4287      goto wr_msg;
4288     }
4289 
4290    /* LOOKATME - time width dependent */
4291    ndp->szu.xclen = TIMEBITS;
4292    ndp->ru.xvi = __allocfill_cval_new(ap, bp, 2);
4293    return(TRUE);
4294   }
4295  if (ndp->szu.xclen > WBITS)
4296   {
4297    if (bp[0] != 0L || bp[1] != 0L)
4298     {
4299      /* notice on error here just leave as 8 bytes - since non IS form */
4300      ndp->szu.xclen = TIMEBITS;
4301 
4302      push_xstk_(xsp, 2*WBITS);
4303      memset(xsp->ap, 0, 4*WRDBYTES);
4304      ndp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, 2);
4305      __pop_xstk();
4306      goto fill_xs;
4307     }
4308    return(TRUE);
4309   }
4310  ndp->szu.xclen = WBITS;
4311  if (bp[0] == 0L) return(TRUE);
4312  ndp->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
4313 
4314 fill_xs:
4315  __force_base = BDEC;
4316  __msgexpr_tostr(__xs, ndp);
4317  __force_base = BNONE;
4318 
4319 wr_msg:
4320  __sgferr(848,
4321   "%s value %s not required up to %d bit non x/z delay number - set to 0",
4322   emsg, __xs, TIMEBITS);
4323  return(FALSE);
4324 }
4325 
4326 /*
4327  * need an delay up to 64 bit number - same as nd_ndxisnum except 64 bits
4328  * changed in prep - this just checks but if error converts to 0
4329  * LOOKATME - should change from TIMEBITS 8 bytes to 4 bytes if all high 0
4330  * SIZEDEPENDENT notice this routine has built in 32 bit word32 and 64 bit time
4331  *
4332  * FIXME - this routine looks wrong or can be improved
4333  */
nd_delisnum(struct expr_t * ndp,char * emsg)4334 static int32 nd_delisnum(struct expr_t *ndp, char *emsg)
4335 {
4336  register int32 iti;
4337  int32 err, wlen, wsiz;
4338  word32 *wp, *wp2, *ap, *bp;
4339 
4340  err = FALSE;
4341  wlen = wlen_(ndp->szu.xclen);
4342  wp = &(__contab[ndp->ru.xvi]);
4343  /* case 1: wider than TIMEBITS (64) */
4344  if (ndp->szu.xclen > 64)
4345   {
4346    /* check all high bits if 0 and not z just extract low 8 byte sections */
4347    for (iti = 0; iti < __inst_mod->flatinum; iti++)
4348     {
4349      ap = &(wp[2*wlen*iti]);
4350      bp = &(ap[wlen]);
4351      if (!vval_is0_(&(ap[2]), ndp->szu.xclen - 64)
4352       || !vval_is0_(bp, ndp->szu.xclen))
4353       { wr_ndisdel_err(ndp, iti, emsg); err = TRUE; }
4354     }
4355    if (err) { freeset_is0del(ndp, __inst_mod->flatinum); return(FALSE); }
4356 
4357    /* convert to TIMEBITS by extracting low 64 a/b bits of each */
4358    /* this frees subtree under ndp but xva constant field can not be freed */
4359    __free2_xtree(ndp);
4360    __init_xnd(ndp);
4361    ndp->optyp = ISNUMBER;
4362    ndp->szu.xclen = TIMEBITS;
4363    wsiz = 2*__inst_mod->flatinum;
4364    ndp->ru.xvi = __alloc_is_cval(wsiz);
4365    wp2 = &(__contab[ndp->ru.xvi]);
4366    for (iti = 0; iti < __inst_mod->flatinum; iti++)
4367     {
4368      ap = &(wp[2*wlen*iti]);
4369      bp = &(ap[wlen]);
4370      wp2[4*iti] = ap[0]; wp2[4*iti + 1] = ap[1];
4371      wp2[4*iti + 2] = bp[0]; wp2[4*iti + 3] = bp[1];
4372     }
4373    return(TRUE);
4374   }
4375  /* case 2 between WBITS and TIMEBITS */
4376  if (ndp->szu.xclen > WBITS)
4377   {
4378    for (iti = 0; iti < __inst_mod->flatinum; iti++)
4379     {
4380      ap = &(wp[4*iti]);
4381      bp = &(ap[2]);
4382      if (bp[0] != 0L || bp[1] != 0L)
4383       { wr_ndisdel_err(ndp, iti, emsg); err = TRUE; }
4384     }
4385    /* notice on error here even good instances set to 0 */
4386    if (err) { freeset_is0del(ndp, __inst_mod->flatinum); return(FALSE); }
4387    /* this uses fact that constants are always stored as 8 byte chunks */
4388    ndp->szu.xclen = 64;
4389    return(TRUE);
4390   }
4391  /* finally case is all WBITS */
4392  for (iti = 0; iti < __inst_mod->flatinum; iti++)
4393   {
4394    ap = &(wp[2*iti]); bp = &(ap[1]);
4395    if (bp[0] != 0L)
4396     {
4397      wr_ndisdel_err(ndp, iti, emsg);
4398      ap[0] = bp[0] = 0L;
4399      err = TRUE;
4400     }
4401   }
4402  /* here value left unless x/z in which case converted to 0 */
4403  ndp->szu.xclen = WBITS;
4404  return(!err);
4405 }
4406 
4407 /*
4408  * upon error free and set delay expr. to WBITS IS delay 0's
4409  *
4410  * LOOKATME - this does not free previous constant entry
4411  */
freeset_is0del(struct expr_t * ndp,int32 insts)4412 static void freeset_is0del(struct expr_t *ndp, int32 insts)
4413 {
4414  register int32 iti;
4415  word32 *wp;
4416 
4417  __free2_xtree(ndp);
4418  __init_xnd(ndp);
4419  ndp->optyp = ISNUMBER;
4420  ndp->szu.xclen = WBITS;
4421  ndp->ru.xvi = __alloc_is_cval(1*insts);
4422  wp = &(__contab[ndp->ru.xvi]);
4423  for (iti = 0; iti < insts; iti++) wp[2*iti] = wp[2*iti + 1] = 0L;
4424 }
4425 
4426 /*
4427  * write an is need delay form error message
4428  */
wr_ndisdel_err(struct expr_t * ndp,int32 iti,char * emsg)4429 static void wr_ndisdel_err(struct expr_t *ndp, int32 iti, char *emsg)
4430 {
4431  char s1[RECLEN];
4432 
4433  __force_base = BDEC;
4434  __sgferr(838,
4435   "%s value %s not required up to %d bit non x/z delay number (inst. %d)",
4436    emsg, __msgnumexpr_tostr(s1, ndp, iti), TIMEBITS, iti);
4437  __force_base = BNONE;
4438 }
4439 
4440 /*
4441  * check a wires range and array range
4442  */
chk_wire_rng(struct net_t * np)4443 static void chk_wire_rng(struct net_t *np)
4444 {
4445  int32 vwid, mwid, ival;
4446  word32 *wp;
4447  struct expr_t *ndp, *ndp2;
4448  char s1[RECLEN];
4449 
4450  if (np->n_isavec)
4451   {
4452    /* this must be a non x/z constant that can be a wire range */
4453    /* changes to WBIT vectored form */
4454    /* never IS form */
4455    sprintf(s1, "wire or reg first range of %s", np->nsym->synam);
4456    if (!__chkndx_expr(np->nu.ct->nx1, s1))
4457     {
4458 bad_wire:
4459      np->n_isavec = FALSE;
4460      np->nu.ct->nx1 = np->nu.ct->nx2 = NULL;
4461      goto chk_arr;
4462     }
4463    wp = &(__contab[np->nu.ct->nx1->ru.xvi]);
4464    ival = (int32) wp[0];
4465    if (ival < 0)
4466     {
4467      __sgferr(902, "%s value %d illegal negative number", s1, ival);
4468      goto bad_wire;
4469     }
4470 
4471    sprintf(s1, "wire or reg second range of %s", np->nsym->synam);
4472    if (np->nu.ct->nx2 == NULL || !__chkndx_expr(np->nu.ct->nx2, s1))
4473     goto bad_wire;
4474 
4475    wp = &(__contab[np->nu.ct->nx2->ru.xvi]);
4476    ival = (int32) wp[0];
4477    if (ival < 0)
4478     {
4479      __sgferr(902, "%s value %d illegal negative number", s1, ival);
4480      goto bad_wire;
4481     }
4482 
4483    /* know net ranges fit in 32 bits or will not get here */
4484    vwid = __get_netwide(np);
4485    if (vwid > MAXNUMBITS)
4486     {
4487      __sgferr(774,
4488       "wire or reg %s range width %d too wide (%d)", np->nsym->synam, vwid,
4489       MAXNUMBITS);
4490      np->n_isavec = FALSE;
4491      np->nu.ct->nx1 = np->nu.ct->nx2 = NULL;
4492      goto chk_arr;
4493     }
4494    /* DBG remove */
4495    if (np->nu.ct->nx1 == NULL || np->nu.ct->nx2 == NULL)
4496     __misc_terr(__FILE__, __LINE__);
4497    /* -- */
4498 
4499    /* for one pound param case, IS form possible but know all same */
4500    /* know only one place in source and only pound params used */
4501    /* all of what is seen as IS form same so check and fix here */
4502    ndp = np->nu.ct->nx1;
4503    ndp2 = np->nu.ct->nx2;
4504    if (ndp->optyp == ISNUMBER)
4505     {
4506      chg_rng_isnum_to_num(np, ndp, "first vector range");
4507     }
4508    if (ndp2->optyp == ISNUMBER)
4509     {
4510      chg_rng_isnum_to_num(np, ndp2, "second vector range");
4511     }
4512    if (ndp->optyp != NUMBER)
4513     {
4514      __sgfterr(329,
4515       "wire or reg %s in module %s impossible first vector range expression %s",
4516       np->nsym->synam, __inst_mod->msym->synam, __msgexpr_tostr(__xs, ndp));
4517     }
4518    if (ndp2->optyp != NUMBER)
4519     {
4520      __sgfterr(329,
4521       "wire or reg %s in module %s impossible second vector range expression %s",
4522       np->nsym->synam, __inst_mod->msym->synam, __msgexpr_tostr(__xs, ndp2));
4523     }
4524   }
4525  /* inconsistent scalar range */
4526  else if (np->nu.ct->nx1 != NULL || np->nu.ct->nx2 != NULL)
4527   __misc_terr(__FILE__, __LINE__);
4528 
4529  /* check array */
4530 chk_arr:
4531  if (np->n_isarr)
4532   {
4533    sprintf(s1, "array first range of %s", np->nsym->synam);
4534    if (!__chkndx_expr(np->nu.ct->ax1, s1))
4535     {
4536 bad_arr:
4537      np->n_isarr = FALSE;
4538      np->nu.ct->ax1 = np->nu.ct->ax2 = NULL;
4539      return;
4540     }
4541    wp = &(__contab[np->nu.ct->ax1->ru.xvi]);
4542    ival = (int32) wp[0];
4543    if (ival < 0)
4544     {
4545      __sgferr(902, "%s value %d illegal negative number", s1, ival);
4546      goto bad_arr;
4547     }
4548    sprintf(s1, "array second range of %s", np->nsym->synam);
4549    if (np->nu.ct->ax2 == NULL || !__chkndx_expr(np->nu.ct->ax2, s1))
4550     goto bad_arr;
4551 
4552    wp = &(__contab[np->nu.ct->ax2->ru.xvi]);
4553    ival = (int32) wp[0];
4554    if (ival < 0)
4555     {
4556      __sgferr(902, "%s value %d illegal negative number", s1, ival);
4557      goto bad_arr;
4558     }
4559 
4560    /* allowing up to 2*24 cells (SJM 11/13/00 - comment was wrong) */
4561    mwid = __get_arrwide(np);
4562    if (mwid < 0 || mwid > 0x00ffffff)
4563     {
4564      __sgfwarn(620,
4565       "array %s has %d cells - standard only requires maximum of %d",
4566       np->nsym->synam, mwid, 0x00ffffff);
4567     }
4568    /* DBG remove */
4569    if (np->nu.ct->ax1 == NULL || np->nu.ct->ax2 == NULL)
4570     __misc_terr(__FILE__, __LINE__);
4571 
4572    ndp = np->nu.ct->ax1;
4573    ndp2 = np->nu.ct->ax2;
4574    if (ndp->optyp == ISNUMBER)
4575     {
4576      chg_rng_isnum_to_num(np, ndp, "first array range");
4577     }
4578    if (ndp2->optyp == ISNUMBER)
4579     {
4580      chg_rng_isnum_to_num(np, ndp2, "second array range");
4581     }
4582    if (ndp->optyp != NUMBER)
4583     {
4584      __sgfterr(329,
4585       "wire or reg %s in module %s impossible first array range expression %s",
4586       np->nsym->synam, __inst_mod->msym->synam, __msgexpr_tostr(__xs, ndp));
4587     }
4588    if (ndp2->optyp != NUMBER)
4589     {
4590      __sgfterr(329,
4591       "wire or reg %s in module %s impossible second array range expression %s",
4592       np->nsym->synam, __inst_mod->msym->synam, __msgexpr_tostr(__xs, ndp2));
4593     }
4594    /* --- */
4595   }
4596 }
4597 
4598 /*
4599  * convert all same value range that is ISNUMBER to simple NUMBER
4600  * i.e. change expr type and check
4601  *
4602  * know first range element checked and good or will not be called
4603  */
chg_rng_isnum_to_num(struct net_t * np,struct expr_t * ndp,char * rngstr)4604 static void chg_rng_isnum_to_num(struct net_t *np, struct expr_t *ndp,
4605  char *rngstr)
4606 {
4607  register int32 iti;
4608  int32 wlen;
4609  word32 *wp, *wp0, *wp1;
4610 
4611  wlen = wlen_(ndp->szu.xclen);
4612  wp = &(__contab[ndp->ru.xvi]);
4613  wp0 = &(wp[0]);
4614  for (iti = 1; iti < __inst_mod->flatinum; iti++)
4615   {
4616    wp1 = &(wp[2*wlen*iti]);
4617    if (memcmp(wp0, wp1, 2*wlen*WRDBYTES) != 0)
4618     {
4619      __sgferr(902,
4620       "wire or reg %s in %s (inst. %d) %s value %s wrong - should be %s - one source instance pound param problem",
4621       np->nsym->synam, __inst_mod->msym->synam, iti, rngstr,
4622       __msgnumexpr_tostr(__xs, ndp, 0), __msgnumexpr_tostr(__xs2, ndp, iti));
4623     }
4624   }
4625  /* even if error change to num - i.e. just use first */
4626  /* change to number easy, just use first one for all - first xvi right */
4627  /* and all other fields right */
4628  ndp->optyp = NUMBER;
4629  /* DBG remove --- */
4630  if (__debug_flg)
4631   {
4632    __dbg_msg(
4633     "++ %s in %s %s set by pound param to %d converted to number - all insts same\n",
4634     np->nsym->synam, __inst_mod->msym->synam, rngstr, wp0[0]);
4635   }
4636  /* --- */
4637 }
4638 
4639 /*
4640  * routine to check a index style 32 bit non x/z expression
4641  * for declaration ranges - other routines for now for other things
4642  * caller must pass string for error message describing range type
4643  */
__chkndx_expr(struct expr_t * ndp,char * emsg)4644 extern int32 __chkndx_expr(struct expr_t *ndp, char *emsg)
4645 {
4646  /* must be 0 context - even though result is always 32 bits */
4647  __chk_rhsexpr(ndp, 0);
4648  /* even if errors, if number at end good returns T else F */
4649  if (!__nd_ndxnum(ndp, emsg, TRUE)) return(FALSE);
4650  return(TRUE);
4651 }
4652 
4653 /*
4654  * check task regs
4655  * must be done before any statement checking
4656  */
chk_taskvars(struct task_t * tskp,int32 tregbasi)4657 static void chk_taskvars(struct task_t *tskp, int32 tregbasi)
4658 {
4659  register int32 syi, ri;
4660  register struct sy_t *syp;
4661  register struct net_t *rp;
4662  struct sy_t **syms;
4663  struct symtab_t *sytp;
4664  struct net_t *rtab;
4665 
4666  /* if undefined must emit error */
4667  syp = tskp->tsksyp;
4668  if (!syp->sydecl)
4669   {
4670    __gferr(776, syp->syfnam_ind, syp->sylin_cnt,
4671     "task or function %s not declared", syp->synam);
4672    return;
4673   }
4674  sytp = tskp->tsksymtab;
4675  /* this will also set reg ranges */
4676  chk_undef_syms(sytp, tskp->tsktyp);
4677  /* parameters (including local) checked before defparam processing */
4678 
4679  if (tskp->trnum == 0) return;
4680 
4681  /* then point to right offset in module wide var table */
4682  rtab = &(__inst_mod->mnets[tregbasi]);
4683 
4684  /* must now convert all task regs with ranges to constants */
4685  /* possible return range of function will be here */
4686  for (ri = 0, syi = 0, syms = sytp->stsyms; syi < (int32) sytp->numsyms; syi++)
4687   {
4688    syp = syms[syi];
4689    if (syp->sytyp != SYM_N) continue;
4690    rp = syp->el.enp;
4691    /* build list of task variables */
4692    if (rp->n_isaparam) continue;
4693 
4694    rtab[ri] = *rp;
4695    __my_free((char *) rp, sizeof(struct net_t));
4696    rp = &(rtab[ri]);
4697    syp->el.enp = rp;
4698    ri++;
4699 
4700    /* --- DBG
4701    if (__debug_flg)
4702     {
4703      char s1[ECLEN], s2[RECLEN];
4704 
4705      __dbg_msg("--- module %s task %s linking net %s onto list\n",
4706       __inst_mod->msym->synam, tskp->tsksyp->synam, rp->nsym->synam);
4707     }
4708    --- */
4709 
4710    /* do not need to save these, never called with previous location */
4711    __sfnam_ind = rp->nsym->syfnam_ind;
4712    __slin_cnt = rp->nsym->sylin_cnt;
4713    chk_wire_rng(rp);
4714   }
4715  /* still need to point to address of task's reg region in mod table */
4716  tskp->tsk_regs = rtab;
4717 }
4718 
4719 /*
4720  * PORT WIDTH SETTING AND CHECKING ROUTINES
4721  */
4722 
4723 /*
4724  * set and check module port widths
4725  *
4726  * will not get here unless all ports good
4727  * requires that all I/O port net widths known - param subst. and const.
4728  * evaluation completed.
4729  */
__setchk_mpwidths(void)4730 extern void __setchk_mpwidths(void)
4731 {
4732  register int32 pi;
4733  register struct mod_pin_t *mpp;
4734  struct expr_t *mpx;
4735  int32 pnum;
4736 
4737  if ((pnum = __inst_mod->mpnum) == 0) return;
4738  __expr_rhs_decl = TRUE;
4739  for (pi = 0; pi < pnum; pi++)
4740   {
4741    mpp = &(__inst_mod->mpins[pi]);
4742    /* location here must be port header */
4743    __sfnam_ind = __inst_mod->msym->syfnam_ind;
4744    __slin_cnt = __inst_mod->msym->sylin_cnt;
4745 
4746    /* as a minimum port must be legal expr. */
4747    mpx = mpp->mpref;
4748 
4749    if (mpp->mptyp == IO_OUT) __chk_rhsexpr(mpx, mpp->mpwide);
4750    else
4751     {
4752      __chk_lhsexpr(mpx, LHS_DECL);
4753      if (mpp->mptyp == IO_BID) __set_expr_onrhs(mpx);
4754     }
4755 
4756    /* updates __pr_wid to right width - on error section width assumed 1 */
4757    __pr_wid = 0;
4758    /* this does more port expr. checking and sets __pr_wid */
4759    chk_prtwidth(mpp->mpref, mpp);
4760    mpp->mpwide = __pr_wid;
4761   }
4762  __expr_rhs_decl = FALSE;
4763 }
4764 
4765 /*
4766  * set a port width - previously checked before param values known
4767  * pr_wid must be set to 0 before this is called
4768  * on error uses a subcomponent port width of 1
4769  */
chk_prtwidth(struct expr_t * ndp,struct mod_pin_t * mpp)4770 static int32 chk_prtwidth(struct expr_t *ndp, struct mod_pin_t *mpp)
4771 {
4772  struct sy_t *syp;
4773  struct net_t *np;
4774 
4775  switch ((byte) ndp->optyp) {
4776   case ID:
4777    np = ndp->lu.sy->el.enp;
4778    __pr_wid += ndp->szu.xclen;
4779    break;
4780   case LSB:
4781    syp = ndp->lu.x->lu.sy;
4782    np = syp->el.enp;
4783    if (ndp->ru.x->optyp != NUMBER && ndp->ru.x->optyp != ISNUMBER)
4784     {
4785      __gferr(778, mpp->mpfnam_ind, mpp->mplin_cnt,
4786       "module declaration port %s bit select index must be constant",
4787       np->nsym->synam);
4788     }
4789    __pr_wid++;
4790    break;
4791   case PARTSEL:
4792    syp = ndp->lu.x->lu.sy;
4793    np = syp->el.enp;
4794    __pr_wid += ndp->szu.xclen;
4795    break;
4796   case LCB:
4797    /* notice legal port ref. expr. are always width self determined */
4798    {
4799     register struct expr_t *ndp2;
4800 
4801     /* notice concatenate syntax already checked */
4802     for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4803      {
4804       if (!chk_prtwidth(ndp2->lu.x, mpp)) return(FALSE);
4805      }
4806    }
4807    return(TRUE);
4808   case OPEMPTY:
4809    __pr_wid += 1;
4810    return(TRUE);
4811   default:
4812    __gferr(779, mpp->mpfnam_ind, mpp->mplin_cnt,
4813     "%s illegal in module header list of ports", __msgexpr_tostr(__xs, ndp));
4814    __pr_wid++;
4815    return(FALSE);
4816  }
4817  /* because of P1364 tran channel channel inout algorithm */
4818  /* inout ports can not be delayed wires */
4819  if (np->iotyp == IO_BID && np->nu.ct->n_dels_u.pdels != NULL)
4820   {
4821    __sgferr(728,
4822     "illegal for inout port %s to have wire delay - incompatible with P1364 tran model",
4823     np->nsym->synam);
4824   }
4825  return(TRUE);
4826 }
4827 
4828 /*
4829  * check shorted inouts for current module
4830  * notice this must be called only after port widths known
4831  */
__chk_shorted_bids(void)4832 extern void __chk_shorted_bids(void)
4833 {
4834  register int32 pi;
4835  int32 pnum, has_shorted;
4836  struct mod_pin_t *mpp;
4837 
4838  if ((pnum = __inst_mod->mpnum) == 0) return;
4839  for (has_shorted = FALSE, pi = 0; pi < pnum; pi++)
4840   {
4841    mpp = &(__inst_mod->mpins[pi]);
4842    /* this uses previously counted number of connected ports */
4843    if (!xhas_multconn_wire(mpp->mpref)) continue;
4844 
4845    /* emit inform for shorted that are not inouts */
4846    if (mpp->mptyp != IO_BID) emit_nonbid_shortwarn(mpp, mpp->mpref);
4847    mpp->mp_jmpered = TRUE;
4848    has_shorted = TRUE;
4849   }
4850  /* also emit informs for inouts */
4851  if (has_shorted) emit_shorted_informs(pnum);
4852 }
4853 
4854 /*
4855  * emit informs for all shorted ports - ok but good to know about
4856  */
emit_shorted_informs(int32 pnum)4857 static void emit_shorted_informs(int32 pnum)
4858 {
4859  register int32 pi;
4860  register struct expr_t *xp2;
4861  struct mod_pin_t *mpp;
4862  struct expr_t *xp, *xp3;
4863  struct net_t *np;
4864 
4865  for (pi = 0; pi < pnum; pi++)
4866   {
4867    mpp = &(__inst_mod->mpins[pi]);
4868    /* if previous error will not appear as jumpered */
4869    if (!mpp->mp_jmpered) continue;
4870    xp = mpp->mpref;
4871    switch ((byte) xp->optyp) {
4872     case ID: np = xp->lu.sy->el.enp; break;
4873     case LSB: case PARTSEL: np = xp->lu.x->lu.sy->el.enp; break;
4874     case LCB:
4875      for (xp2 = xp->ru.x; xp2 != NULL; xp2 = xp2->ru.x)
4876       {
4877        xp3 = xp2->lu.x;
4878        switch((byte) xp3->optyp) {
4879         case ID: np = xp3->lu.sy->el.enp; break;
4880         case LSB: case PARTSEL: np = xp3->lu.x->lu.sy->el.enp; break;
4881         default: continue;
4882        }
4883        emit_1net_shorted_informs(mpp, pi, np, pnum);
4884       }
4885      continue;
4886     default: continue;
4887    }
4888    emit_1net_shorted_informs(mpp, pi, np, pnum);
4889   }
4890 }
4891 
4892 /*
4893  * emit the shorted port informs for 1 net
4894  */
emit_1net_shorted_informs(struct mod_pin_t * mpp,int32 pi,struct net_t * np,int32 pnum)4895 static void emit_1net_shorted_informs(struct mod_pin_t *mpp,
4896  int32 pi, struct net_t *np, int32 pnum)
4897 {
4898  register int32 pi2;
4899  struct mod_pin_t *mpp2;
4900  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
4901 
4902  /* have jumpered into not in any equiv. class - it is master */
4903  for (pi2 = pi + 1; pi2 < pnum; pi2++)
4904   {
4905    mpp2 = &(__inst_mod->mpins[pi2]);
4906    /* if not jumpered to anything no need to check */
4907    if (!mpp2->mp_jmpered) continue;
4908    if (!net_in_expr(np, mpp2->mpref)) continue;
4909 
4910    __gfinform(454, mpp2->mpfnam_ind, mpp2->mplin_cnt,
4911     "%s %s in %s port %s also referenced in port %s at %s (shorted together)",
4912     __to_wtnam(s1, np), np->nsym->synam, __to_ptnam(s2, mpp2->mptyp),
4913     __to_mpnam(s3, mpp2->mpsnam), __to_mpnam(__xs2, mpp->mpsnam),
4914     __bld_lineloc(__xs, mpp->mpfnam_ind, mpp->mplin_cnt));
4915    }
4916 }
4917 
4918 /*
4919  * return T if net np is expr xp
4920  * return F for non lhs expr.
4921  */
net_in_expr(struct net_t * np,struct expr_t * xp)4922 static int32 net_in_expr(struct net_t *np, struct expr_t *xp)
4923 {
4924  register struct expr_t *xp2;
4925  struct net_t *np2;
4926 
4927  switch ((byte) xp->optyp) {
4928   case ID:
4929    np2 = xp->lu.sy->el.enp;
4930    break;
4931   case LSB: case PARTSEL:
4932    np2 = xp->lu.x->lu.sy->el.enp;
4933    break;
4934   case LCB:
4935    for (xp2 = xp->ru.x; xp2 != NULL; xp2 = xp2->ru.x)
4936     { if (net_in_expr(np, xp2->lu.x)) return(TRUE); }
4937    return(FALSE);
4938   /* if non lhs expr (error elsewhere , just return F */
4939   default: return(FALSE);
4940  }
4941  return(np == np2);
4942 }
4943 
4944 /*
4945  * return T if port contains wire that connects to other port
4946  * notice only called for ports and not called from interactive
4947  * also even though not checked here if inotu shorted must be wire name
4948  */
xhas_multconn_wire(struct expr_t * ndp)4949 static int32 xhas_multconn_wire(struct expr_t *ndp)
4950 {
4951  struct expr_t *ndp2;
4952  struct net_t *np;
4953 
4954  switch ((byte) ndp->optyp) {
4955   case ID:
4956    np = ndp->lu.sy->el.enp;
4957 chk_mult:
4958    if (np->nu.ct->num_prtconns == 2) return(TRUE);
4959    break;
4960   case PARTSEL: case LSB:
4961    np = ndp->lu.x->lu.sy->el.enp;
4962    goto chk_mult;
4963   case LCB:
4964    for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
4965     { if (xhas_multconn_wire(ndp2->lu.x)) return(TRUE); }
4966    break;
4967   case OPEMPTY: break;
4968   default: __case_terr(__FILE__, __LINE__);
4969  }
4970  return(FALSE);
4971 }
4972 
4973 /*
4974  * emit warn for shorted together feed thru ports that are not inouts
4975  */
emit_nonbid_shortwarn(struct mod_pin_t * mpp,struct expr_t * ndp)4976 static void emit_nonbid_shortwarn(struct mod_pin_t *mpp,
4977  struct expr_t *ndp)
4978 {
4979  struct expr_t *ndp2;
4980  struct net_t *np;
4981  char s1[RECLEN], s2[RECLEN];
4982 
4983  switch ((byte) ndp->optyp) {
4984   case ID:
4985    np = ndp->lu.sy->el.enp;
4986 chk_mult:
4987    if (np->iotyp != IO_BID)
4988     {
4989      __gfinform(476, mpp->mpfnam_ind, mpp->mplin_cnt,
4990       "%s port %s %s %s used in merged or shorted ports - if ranges overlap probably wrong",
4991       __to_ptnam(s2, np->iotyp), __to_mpnam(s1, mpp->mpsnam),
4992       __to_wtnam(__xs, np), np->nsym->synam);
4993     }
4994    break;
4995   case PARTSEL: case LSB:
4996    np = ndp->lu.x->lu.sy->el.enp;
4997    goto chk_mult;
4998   case LCB:
4999    for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
5000     emit_nonbid_shortwarn(mpp, ndp2->lu.x);
5001    break;
5002   default: __case_terr(__FILE__, __LINE__);
5003  }
5004 }
5005 
5006 /*
5007  * ROUTINES TO RECONNECT SCALAR GATES/INSTS PIN LISTS
5008  */
5009 
5010 /*
5011  * reconnect and check gates and instances according to LRM rules
5012  */
__reconn_gia_pins(void)5013 extern void __reconn_gia_pins(void)
5014 {
5015  register struct mod_t *mdp;
5016 
5017  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5018   {
5019    __push_wrkitstk(mdp, 0);
5020    if (mdp->mgarr != NULL) reconn_1mod_gateterms(mdp);
5021    if (mdp->miarr != NULL) reconn_1mod_instports(mdp);
5022    __pop_wrkitstk();
5023   }
5024 }
5025 
5026 /*
5027  * reconnect array of gates ports for one module
5028  * new expression put in each expanded bit of gate original free for each term
5029  *
5030  * know module has at least one arrayed gates or not called
5031  */
reconn_1mod_gateterms(struct mod_t * mdp)5032 static void reconn_1mod_gateterms(struct mod_t *mdp)
5033 {
5034  register int32 gi, pi, gi2;
5035  int32 giawid, bi, wid, r0;
5036  word32 av, bv, *wp;
5037  struct giarr_t *giap;
5038  struct gate_t *gp, *gp2;
5039  struct expr_t *xp;
5040  struct net_t *np;
5041  struct xstk_t *xsp;
5042 
5043  for (gi = 0; gi < mdp->mgnum;)
5044   {
5045    if ((giap = mdp->mgarr[gi]) == NULL) { gi++; continue; }
5046 
5047    gp = &(mdp->mgates[gi]);
5048    giawid = __get_giarr_wide(giap);
5049    /* DBG remove -- */
5050    if (giap->gia_bi != gi) __misc_terr(__FILE__, __LINE__);
5051    /* --- */
5052 
5053    /* for checking each gate has original entire array terms */
5054    /* allocate new tab of expr ptrs for each independent of how connected */
5055    for (gi2 = giap->gia_bi; gi2 < giap->gia_bi + giawid; gi2++)
5056     {
5057      gp2 = &(mdp->mgates[gi2]);
5058      gp2->gpins = (struct expr_t **)
5059       __my_malloc(gp->gpnum*sizeof(struct expr_t *));
5060     }
5061 
5062    /* handle each pin (terminal) in turn */
5063    for (pi = 0; pi < gp->gpnum; pi++)
5064     {
5065      xp = giap->giapins[pi];
5066      /* notice 0 context in case need to apportion */
5067      __chk_rhsexpr(xp, 0);
5068 
5069      /* FIXME - should allow global here? */
5070      if (__expr_has_glb(xp)) goto bad_conn_expr;
5071 
5072      if (xp->szu.xclen == 1)
5073       {
5074        /* exact copy expressions, this can be any expr. */
5075        for (gi2 = giap->gia_bi; gi2 < giap->gia_bi + giawid; gi2++)
5076         {
5077          gp2 = &(mdp->mgates[gi2]);
5078          gp2->gpins[pi] = __copy_expr(xp);
5079         }
5080       }
5081      else if (xp->szu.xclen == giawid)
5082       {
5083        /* hard apportioning case - know now width 1 and matches */
5084        /* only variable, part select, concat, or constant possible */
5085        switch ((byte) xp->optyp) {
5086         case ID:
5087          np = xp->lu.sy->el.enp;
5088          if (np->n_isarr)
5089           {
5090            __gferr(699, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
5091            "arrayed %s gate %s terminal %d array %s illegal - not selectable",
5092             gp->gmsym->synam, giap->gia_base_syp->synam, pi + 1,
5093             __msgexpr_tostr(__xs, xp));
5094            goto make_unc;
5095           }
5096          /* build bsel expression - apportion bits h to l from wire */
5097          /* array of gates may be stored either way but first (h) from wire */
5098          /* always gets first of array */
5099          gi2 = giap->gia_bi;
5100          wid = __get_netwide(np);
5101          for (bi = wid - 1; gi2 < giap->gia_bi + giawid; gi2++, bi--)
5102           {
5103            gp2 = &(mdp->mgates[gi2]);
5104            gp2->gpins[pi] = bld_bsel_expr(np, bi);
5105           }
5106          break;
5107         case PARTSEL:
5108          /* for part select know internal wire h:l - generating bit selects */
5109          /* normalized to it and h bit connects to first, etc */
5110          wp = &(__contab[xp->ru.x->lu.x->ru.xvi]);
5111          r0 = (int32) wp[0];
5112 
5113          /* AIV 06/08/06 - was getting the net from the wrong part of xpr */
5114          np = xp->lu.x->lu.sy->el.enp;
5115          gi2 = giap->gia_bi;
5116          for (bi = r0; gi2 < giap->gia_bi + giawid; gi2++, bi--)
5117           {
5118            gp2 = &(mdp->mgates[gi2]);
5119            gp2->gpins[pi] = bld_bsel_expr(np, bi);
5120           }
5121          break;
5122         case LCB:
5123          /* easy gate case - peels off 1 bit things from concat */
5124          /* concats always h:0 */
5125          if (!legal_giarr_conn_concat(xp))
5126           {
5127            __gferr(699, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
5128             "arrayed %s gate %s terminal %d concatenate %s illegal - contains non selectable lvalue",
5129             gp->gmsym->synam, giap->gia_base_syp->synam, pi + 1,
5130             __msgexpr_tostr(__xs, xp));
5131            goto make_unc;
5132           }
5133          conn_1gateterm_concat(mdp, giap, xp, pi);
5134          break;
5135         case NUMBER:
5136          xsp = __eval_xpr(xp);
5137 
5138          /* DBG remove -- */
5139          if (xsp->xslen != giawid) __misc_terr(__FILE__, __LINE__);
5140          /* --- */
5141          /* numbers always h:0 with low bit numbered 0 */
5142          bi = xsp->xslen - 1;
5143          for (gi2 = giap->gia_bi; gi2 < giap->gia_bi + giawid; gi2++, bi--)
5144           {
5145            av = rhsbsel_(xsp->ap, bi);
5146            bv = rhsbsel_(xsp->bp, bi);
5147            gp2 = &(mdp->mgates[gi2]);
5148            gp2->gpins[pi] = __bld_rng_numxpr(av, bv, 1);
5149            gp2->gpins[pi]->ibase = BDEC;
5150           }
5151          __pop_xstk();
5152          break;
5153         case ISNUMBER:
5154          /* must never see this means incorrect splitting somewhere */
5155          __misc_terr(__FILE__, __LINE__);
5156          break;
5157         default:
5158           __gferr(699, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
5159            "arrayed %s gate %s terminal %d expression %s illegal - not var, select, concat or number",
5160           gp->gmsym->synam, giap->gia_base_syp->synam, pi + 1,
5161           __msgexpr_tostr(__xs, xp));
5162           goto make_unc;
5163         }
5164       }
5165      else
5166       {
5167 bad_conn_expr:
5168        /* error width mis-match */
5169        __gferr(698, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
5170         "arrayed %s gate %s terminal %d connection width %d illegal - must be 1 or %d",
5171         gp->gmsym->synam, giap->gia_base_syp->synam, pi + 1, xp->szu.xclen,
5172         giawid);
5173        /* make each unc. */
5174 make_unc:
5175        for (gi2 = giap->gia_bi; gi2 < giap->gia_bi + giawid; gi2++)
5176         {
5177          gp2 = &(mdp->mgates[gi2]);
5178          __bld_unc_expr();
5179          gp2->gpins[pi] = __root_ndp;
5180         }
5181       }
5182     }
5183    gi += giawid;
5184   }
5185 }
5186 
5187 /*
5188  * routine to build a constant bit select expression
5189  *
5190  * passed ndx is h:0 normalized form because later expr. checking will assume
5191  * value is what appeared in source, must unnormalize to what is in
5192  * source so will get normalized later during expr. check then output
5193  * will reconvert to source - neede so caller can work only with internal h:0
5194  */
bld_bsel_expr(struct net_t * np,int32 ndx)5195 static struct expr_t *bld_bsel_expr(struct net_t *np, int32 ndx)
5196 {
5197  int32 ndx2;
5198  struct expr_t *xp, *xpid, *xpndx;
5199 
5200  xpid = __alloc_newxnd();
5201  xpid->optyp = ID;
5202  xpid->lu.sy = np->nsym;
5203  xpid->szu.xclen = __get_netwide(np);
5204 
5205  ndx2 = __unnormalize_ndx(np, ndx);
5206  xpndx = __bld_rng_numxpr((word32) ndx2, 0L, WBITS);
5207  xpndx->ibase = BDEC;
5208  if (ndx != ndx2) xpndx->ind_noth0 = TRUE;
5209 
5210  /* root of part select */
5211  xp = __alloc_newxnd();
5212  xp->optyp = LSB;
5213  xp->szu.xclen = 1;
5214 
5215  xp->lu.x = xpid;
5216  xp->ru.x = xpndx;
5217  return(xp);
5218 }
5219 
5220 /*
5221  * connect arrayed gate terms from a concat for one gate term (know 1 bit)
5222  *
5223  * notice here loop is through gate concat expression - peels off bits 1 by 1
5224  * and moved through instances
5225  */
conn_1gateterm_concat(struct mod_t * mdp,struct giarr_t * giap,struct expr_t * catxp,int32 pi)5226 static void conn_1gateterm_concat(struct mod_t *mdp, struct giarr_t *giap,
5227  struct expr_t *catxp, int32 pi)
5228 {
5229  register int32 gi2, bi;
5230  register struct expr_t *xp2, *xp3;
5231  int32 r0, r1, nwid;
5232  word32 av, bv;
5233  struct gate_t *gp;
5234  struct net_t *np;
5235  struct xstk_t *xsp;
5236 
5237  gi2 = giap->gia_bi;
5238  for (xp2 = catxp->ru.x; xp2 != NULL; xp2 = xp2->ru.x)
5239   {
5240    xp3 = xp2->lu.x;
5241    switch ((byte) xp3->optyp) {
5242     case ID:
5243      np = xp3->lu.sy->el.enp;
5244      nwid = __get_netwide(np);
5245      if (np->n_isavec)
5246       {
5247        for (bi = nwid - 1; bi >= 0; gi2++, bi--)
5248         {
5249          gp = &(mdp->mgates[gi2]);
5250          gp->gpins[pi] = bld_bsel_expr(np, bi);
5251         }
5252       }
5253      /* SJM 07/08/00 - if scalar in concatenate can't convert ot bsel */
5254      else
5255       {
5256        gp = &(mdp->mgates[gi2]);
5257        gp->gpins[pi] = __copy_expr(xp3);
5258        gi2++;
5259       }
5260      break;
5261     case LSB:
5262      gp = &(mdp->mgates[gi2]);
5263      gp->gpins[pi] = __copy_expr(xp3);
5264      gi2++;
5265      break;
5266     case PARTSEL:
5267      /* constants here normalized h:0 and need to apportion in that order */
5268      r0 = __contab[xp3->ru.x->lu.x->ru.xvi];
5269      r1 = __contab[xp3->ru.x->ru.x->ru.xvi];
5270      /* SJM 04/13/04 - since psel must get net from left ID of psel */
5271      np = xp3->lu.x->lu.sy->el.enp;
5272      for (bi = r0; bi >= r1; gi2++, bi--)
5273       {
5274        gp = &(mdp->mgates[gi2]);
5275        gp->gpins[pi] = bld_bsel_expr(np, bi);
5276       }
5277      break;
5278     case NUMBER:
5279      xsp = __eval_xpr(xp3);
5280 
5281      /* numbers always h:0 with low bit numbered 0 */
5282      bi = xsp->xslen - 1;
5283      for (bi = xsp->xslen - 1; bi >= 0; gi2++, bi--)
5284       {
5285        av = rhsbsel_(xsp->ap, bi);
5286        bv = rhsbsel_(xsp->bp, bi);
5287        gp = &(mdp->mgates[gi2]);
5288        gp->gpins[pi] = __bld_rng_numxpr(av, bv, 1);
5289        gp->gpins[pi]->ibase = BDEC;
5290       }
5291      __pop_xstk();
5292      break;
5293     default: __case_terr(__FILE__, __LINE__);
5294    }
5295   }
5296 }
5297 
5298 /*
5299  * check concat connected to gate/inst - only IDs, selects, and num
5300  *
5301  * nested concatenate illegal (maybe never can see by here)
5302  */
legal_giarr_conn_concat(struct expr_t * xp)5303 static int32 legal_giarr_conn_concat(struct expr_t *xp)
5304 {
5305  register struct expr_t *xp2;
5306  struct net_t *np;
5307 
5308  for (xp2 = xp->ru.x; xp2 != NULL; xp2 = xp2->ru.x)
5309   {
5310    switch ((byte) xp2->lu.x->optyp) {
5311     case ID:
5312      np = xp2->lu.x->lu.sy->el.enp;
5313      /* array illegal if apportioning because can not be selected from */
5314      if (np->n_isarr) return(FALSE);
5315      break;
5316     case LSB: case PARTSEL: case NUMBER:
5317      break;
5318     default: return(FALSE);
5319    }
5320   }
5321  return(TRUE);
5322 }
5323 
5324 /*
5325  * reconnect array of instances ports for one module
5326  * new expression put in each expanded bit of gate original free for each term
5327  *
5328  * know module has at least arrayed instances or not called
5329  */
reconn_1mod_instports(struct mod_t * mdp)5330 static void reconn_1mod_instports(struct mod_t *mdp)
5331 {
5332  register int32 ii, pi, ii2;
5333  register struct mod_pin_t *mpp;
5334  int32 giawid, bi, nwlen, wid, r0;
5335  struct giarr_t *giap;
5336  struct mod_t *imdp;
5337  struct inst_t *ip, *ip2;
5338  struct expr_t *xp, *xp2;
5339  struct xstk_t *xsp, *xsp2;
5340  struct net_t *np;
5341 
5342  for (ii = 0; ii < mdp->minum;)
5343   {
5344    if ((giap = mdp->miarr[ii]) == NULL) { ii++; continue; }
5345 
5346    giawid = __get_giarr_wide(giap);
5347    ip = &(mdp->minsts[ii]);
5348    imdp = ip->imsym->el.emdp;
5349 
5350    /* DBG remove -- */
5351    if (giap->gia_bi != ii) __misc_terr(__FILE__, __LINE__);
5352    /* --- */
5353    /* for checking each inst. has original array inst pins */
5354    /* allocate new tab of expr ptrs for each independent of how connected */
5355    for (ii2 = giap->gia_bi; ii2 < giap->gia_bi + giawid; ii2++)
5356     {
5357      ip2 = &(mdp->minsts[ii2]);
5358      /* SJM 10/17/99 - empty pin list possible */
5359      if (imdp->mpnum == 0) ip2->ipins = NULL;
5360      else
5361       {
5362        ip2->ipins = (struct expr_t **)
5363         __my_malloc(imdp->mpnum*sizeof(struct expr_t *));
5364       }
5365     }
5366 
5367    /* handle each pin (terminal) in turn */
5368    for (pi = 0; pi < imdp->mpnum; pi++)
5369     {
5370      xp = giap->giapins[pi];
5371      mpp = &(imdp->mpins[pi]);
5372      /* notice 0 context in case need to apportion */
5373      __chk_rhsexpr(xp, 0);
5374 
5375      /* FIXME - should allow global here? */
5376      if (__expr_has_glb(xp)) goto bad_conn_expr;
5377      if (xp->szu.xclen == mpp->mpwide)
5378       {
5379        /* exact match copy expression, any expr. allowed */
5380        for (ii2 = giap->gia_bi; ii2 < giap->gia_bi + giawid; ii2++)
5381         {
5382          ip2 = &(mdp->minsts[ii2]);
5383          ip2->ipins[pi] = __copy_expr(xp);
5384         }
5385       }
5386      /* port width times array of insts size exactly matches expr size */
5387      else if (xp->szu.xclen == giawid*mpp->mpwide)
5388       {
5389        /* hard apportioning case */
5390        /* only variable, part select, or constant possible */
5391        switch ((byte) xp->optyp) {
5392         case ID:
5393          np = xp->lu.sy->el.enp;
5394          if (np->n_isarr)
5395           {
5396            __gferr(699, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
5397             "arrayed %s instance %s port %d array %s illegal - not selectable",
5398             ip->imsym->synam, giap->gia_base_syp->synam, pi + 1,
5399             __msgexpr_tostr(__xs, xp));
5400            goto make_unc;
5401           }
5402          wid = __get_netwide(np);
5403 
5404          /* build bsel (for scalar ports) or psel expression */
5405          /* 2 cases - port width 1 bit or port width >1 bits */
5406          if (mpp->mpwide == 1)
5407           {
5408            /* build bsel expression - apportion bits h to l from wire */
5409            ii2 = giap->gia_bi;
5410            for (bi = wid - 1; ii2 < giap->gia_bi + giawid; ii2++, bi--)
5411             {
5412              ip2 = &(mdp->minsts[ii2]);
5413              ip2->ipins[pi] = bld_bsel_expr(np, bi);
5414             }
5415           }
5416          else
5417           {
5418            bi = wid - 1;
5419            ii2 = giap->gia_bi;
5420            for (; ii2 < giap->gia_bi + giawid; ii2++, bi -= mpp->mpwide)
5421             {
5422              ip2 = &(mdp->minsts[ii2]);
5423              /* build internal h:0 - on output would get unnormalized */
5424              ip2->ipins[pi] = bld_psel_expr(np, bi, bi - mpp->mpwide + 1);
5425             }
5426           }
5427          break;
5428         case PARTSEL:
5429          /* values normalized to h:0 wire during expr check */
5430          r0 = __contab[xp->ru.x->lu.x->ru.xvi];
5431          np = xp->lu.x->lu.sy->el.enp;
5432          if (mpp->mpwide == 1)
5433           {
5434            /* SJM 04/13/04 - core dumped because for loop one too many */
5435            /* scalar port */
5436            ii2 = giap->gia_bi;
5437            bi = r0;
5438            for (; ii2 < giap->gia_bi + giawid; ii2++, bi--)
5439             {
5440              ip2 = &(mdp->minsts[ii2]);
5441              ip2->ipins[pi] = bld_bsel_expr(np, bi);
5442             }
5443           }
5444          else
5445           {
5446            /* vector port */
5447            bi = r0;
5448            for (ii2 = giap->gia_bi; ii2 < giap->gia_bi + giawid; ii2++,
5449             bi -= mpp->mpwide)
5450             {
5451              ip2 = &(mdp->minsts[ii2]);
5452              ip2->ipins[pi] = bld_psel_expr(np, bi, bi - mpp->mpwide + 1);
5453             }
5454           }
5455          break;
5456         case LCB:
5457          /* easy gate case - peels off 1 bit things from concat */
5458          /* concats always h:0 */
5459          if (!legal_giarr_conn_concat(xp))
5460           {
5461            __gferr(699, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
5462             "arrayed %s instance %s port %d concatenate %s illegal - contains non selectable lvalue",
5463             ip->imsym->synam, giap->gia_base_syp->synam, pi + 1,
5464             __msgexpr_tostr(__xs, xp));
5465            goto make_unc;
5466           }
5467          conn_1instport_concat(mdp, giap, xp, pi, mpp->mpwide);
5468          break;
5469         case NUMBER:
5470          __push_wrkitstk(mdp, 0);
5471          xsp = __eval_xpr(xp);
5472          __pop_wrkitstk();
5473          push_xstk_(xsp2, mpp->mpwide);
5474 
5475          bi = xsp->xslen - 1;
5476          for (ii2 = giap->gia_bi; ii2 < giap->gia_bi + giawid;
5477           ii2++, bi -= mpp->mpwide)
5478           {
5479            /* could improve scalar case by using rhs bsel but this works */
5480            __rhspsel(xsp2->ap, xsp->ap, bi, mpp->mpwide);
5481            __rhspsel(xsp2->bp, xsp->bp, bi, mpp->mpwide);
5482 
5483            /* must allocate and fill because may be wider than WBITS */
5484            xp2 = __alloc_newxnd();
5485            xp2->optyp = NUMBER;
5486            nwlen = wlen_(mpp->mpwide);
5487            if (mpp->mpwide <= WBITS)
5488             {
5489              xp2->ru.xvi = __alloc_shareable_cval(xsp2->ap[0], xsp2->ap[1],
5490               mpp->mpwide);
5491             }
5492            else
5493             {
5494              /* each a and b part of constants fits in integral no. words */
5495              xp2->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, nwlen);
5496             }
5497            xp2->szu.xclen = mpp->mpwide;
5498 
5499            ip2 = &(mdp->minsts[ii2]);
5500            ip2->ipins[pi] = xp2;
5501           }
5502          __pop_xstk();
5503          __pop_xstk();
5504          break;
5505         case ISNUMBER:
5506          /* if this is seen bad splitting somewhere */
5507          __misc_terr(__FILE__, __LINE__);
5508          break;
5509         default:
5510          __gferr(699, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
5511           "arrayed %s instance %s port %d expression %s illegal - must be var, select, concat, or number",
5512           ip->imsym->synam, giap->gia_base_syp->synam, pi + 1,
5513           __msgexpr_tostr(__xs, xp));
5514          goto make_unc;
5515         }
5516       }
5517      else
5518       {
5519 bad_conn_expr:
5520        /* error width mis-match */
5521        __gferr(698, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
5522         "arrayed %s instance %s port %d connection width %d illegal - must be %d or %d",
5523         ip->imsym->synam, giap->gia_base_syp->synam, pi + 1, xp->szu.xclen,
5524         mpp->mpwide, mpp->mpwide*giawid);
5525 
5526        /* make each unc. */
5527 make_unc:
5528        for (ii2 = giap->gia_bi; ii2 < giap->gia_bi + giawid; ii2++)
5529         {
5530          ip2 = &(mdp->minsts[ii2]);
5531          __bld_unc_expr();
5532          ip2->ipins[pi] = __root_ndp;
5533         }
5534       }
5535     }
5536    ii += giawid;
5537   }
5538 }
5539 
5540 /*
5541  * routine to build a constant part select expression
5542  *
5543  * passed i1/i2 are h:0 normalized form because later expr. check will assume
5544  * value is what appeared in source, must actually normalize to what is in
5545  * source so will get unnormalized later during expr. check then output
5546  * will reconvert to source - neede so caller can work only with internal h:0
5547  */
bld_psel_expr(struct net_t * np,int32 i1,int32 i2)5548 static struct expr_t *bld_psel_expr(struct net_t *np, int32 i1, int32 i2)
5549 {
5550  int32 ndx1, ndx2;
5551  struct expr_t *xp, *xpid, *xp1, *xp2, *xpcol;
5552 
5553  xpid = __alloc_newxnd();
5554  xpid->optyp = ID;
5555  xpid->szu.xclen = __get_netwide(np);
5556  xpid->lu.sy = np->nsym;
5557 
5558  ndx1 = __unnormalize_ndx(np, i1);
5559  xp1 = __bld_rng_numxpr((word32) ndx1, 0L, WBITS);
5560  xp1->ibase = BDEC;
5561  if (i1 != ndx1) xp1->ind_noth0 = TRUE;
5562 
5563  ndx2 = __unnormalize_ndx(np, i2);
5564  xp2 = __bld_rng_numxpr((word32) ndx2, 0L, WBITS);
5565  xp2->ibase = BDEC;
5566  if (i2 != ndx2) xp1->ind_noth0 = TRUE;
5567 
5568  /* root of part select */
5569  xp = __alloc_newxnd();
5570  xp->optyp = PARTSEL;
5571  xp->szu.xclen = i1 - i2 + 1;
5572  xp->lu.x = xpid;
5573  xpcol = __alloc_newxnd();
5574  xpcol->optyp = COLON;
5575  xp->ru.x = xpcol;
5576  xpcol->lu.x = xp1;
5577  xpcol->ru.x = xp2;
5578  return(xp);
5579 }
5580 
5581 /*
5582  * connect arrayed inst port highconns from a concat for one non scalar port
5583  *
5584  * know width of concat is mpwid*(num insts)
5585  * tricky because may need to build new concats when concat exprs overlap
5586  * by here know all concatenates converted to one level
5587  *
5588  * concat width exactly matches width times inst array size (can't fail)
5589  * concat components already checked
5590  */
conn_1instport_concat(struct mod_t * mdp,struct giarr_t * giap,struct expr_t * catxp,int32 pi,int32 mpwid)5591 static void conn_1instport_concat(struct mod_t *mdp, struct giarr_t *giap,
5592  struct expr_t *catxp, int32 pi, int32 mpwid)
5593 {
5594  register int32 ii2;
5595  register struct exprlst_t *xplp;
5596  int32 giawid, gi1, cwidmore;
5597  struct exprlst_t *xplphd, *last_xplp;
5598  struct expr_t *xp2, *catxp2, *last_catxp;
5599  struct inst_t *ip;
5600 
5601  giawid = __get_giarr_wide(giap);
5602  gi1 = giap->gia_bi + giawid;
5603  /* this copies elements into list - need to leave concat since part of */
5604  /* original expr that stays in giap */
5605  xplphd = splt_icat_align_xlist(catxp, mpwid);
5606  xplp = xplphd;
5607  for (ii2 = giap->gia_bi; ii2 < gi1; ii2++)
5608   {
5609    ip = &(mdp->minsts[ii2]);
5610    /* cat element can never be too wide */
5611    /* DBG remove --- */
5612    if (xplp->xp->szu.xclen > mpwid) __misc_terr(__FILE__, __LINE__);
5613    /* --- */
5614    /* case 1: element of concat exactly matches one inst port width */
5615    if (xplp->xp->szu.xclen == mpwid)
5616     {
5617      ip->ipins[pi] = xplp->xp;
5618      xplp = xplp->xpnxt;
5619      continue;
5620     }
5621    /* case 2: concatenate combined from elements of array concat needed */
5622    catxp2 = __alloc_newxnd();
5623    catxp2->optyp = LCB;
5624    catxp2->szu.xclen = mpwid;
5625    cwidmore = mpwid;
5626    for (last_catxp = NULL;;)
5627     {
5628      xp2 = __alloc_newxnd();
5629      xp2->optyp = CATCOM;
5630      if (last_catxp == NULL) catxp2->ru.x = xp2; else last_catxp->ru.x = xp2;
5631      last_catxp = xp2;
5632 
5633      /* CAT COM len is distant from high bit to low bit (right end) */
5634      xp2->szu.xclen = cwidmore;
5635      xp2->lu.x = xplp->xp;
5636      cwidmore -= xp2->lu.x->szu.xclen;
5637      if (cwidmore == 0) break;
5638      xplp = xplp->xpnxt;
5639      /* DBG remove --- */
5640      if (xplp == NULL) __misc_terr(__FILE__, __LINE__);
5641      /* --- */
5642     }
5643    ip->ipins[pi] = catxp2;
5644    xplp = xplp->xpnxt;
5645   }
5646  /* DBG remove --- */
5647  if (xplp != NULL) __misc_terr(__FILE__, __LINE__);
5648  /* --- */
5649  /* need to free concat expr list (but not expressions that are used) */
5650  for (xplp = xplphd; xplp != NULL;)
5651   {
5652    last_xplp = xplp->xpnxt;
5653    __my_free((char *) xplp, sizeof(struct exprlst_t));
5654    xplp = last_xplp;
5655   }
5656 }
5657 
5658 /*
5659  * build expression list with any overlaps eliminated
5660  *
5661  * when done all expressions copied (so can just conn to insts) and
5662  * never overlaps (may need to build concats but never a need to split)
5663  */
splt_icat_align_xlist(struct expr_t * catxp,int32 mpwid)5664 static struct exprlst_t *splt_icat_align_xlist(struct expr_t *catxp, int32 mpwid)
5665 {
5666  register struct expr_t *xp2, *xp3;
5667  int32 prtbi, cxlen, r1, endlen, overlaplen;
5668  word32 *wp;
5669  struct exprlst_t *xplphd, *xplp, *xplp_last;
5670  struct net_t *np;
5671  struct xstk_t *xsp, *xsp2;
5672 
5673  xsp = NULL;
5674  xplphd = xplp_last = NULL;
5675  /* work one by one thru elements of concatenate */
5676  for (prtbi = 0, xp2 = catxp->ru.x; xp2 != NULL; xp2 = xp2->ru.x)
5677   {
5678    xp3 = xp2->lu.x;
5679    cxlen = xp3->szu.xclen;
5680    /* case 1: entire expr connects to current instance */
5681    if (prtbi + cxlen <= mpwid)
5682     {
5683      xplp = __alloc_xprlst();
5684      xplp->xp = __copy_expr(xp3);
5685      if (xplphd == NULL) xplphd = xplp; else xplp_last->xpnxt = xplp;
5686      xplp_last = xplp;
5687      prtbi += cxlen;
5688      if (prtbi == mpwid) prtbi = 0;
5689      continue;
5690     }
5691    /* case 2: hard need to split expr because element crosses inst. */
5692    /* prtbi + cxlen wider than mpwid */
5693    endlen = mpwid - prtbi;
5694    overlaplen = cxlen - endlen;
5695    /* if number, must compute value for use below */
5696    if (xp3->optyp == NUMBER)
5697     {
5698      xsp = __eval_xpr(xp3);
5699     }
5700    /* build expr. list element for high bits of expr overlapping inst */
5701    xplp = __alloc_xprlst();
5702    if (xplphd == NULL) xplphd = xplp; else xplp_last->xpnxt = xplp;
5703    xplp_last = xplp;
5704    switch ((byte) xp3->optyp) {
5705     case ID:
5706      np = xp3->lu.sy->el.enp;
5707      r1 = cxlen - 1;
5708      /* SJM 07/08/00 - if scalar in concatenate can't convert ot bsel */
5709      if (!np->n_isavec)
5710       {
5711        xplp->xp = __copy_expr(xp3);
5712        break;
5713       }
5714      goto bld_select;
5715     case PARTSEL:
5716      np = xp3->lu.x->lu.sy->el.enp;
5717      wp = &(__contab[xp3->ru.x->lu.x->ru.xvi]);
5718      r1 = (int32) wp[0];
5719 
5720 bld_select:
5721      /* split off first part that will then fill to end */
5722      if (endlen == 1) xplp->xp = bld_bsel_expr(np, r1);
5723      else xplp->xp = bld_psel_expr(np, r1, r1 - endlen + 1);
5724      break;
5725     case NUMBER:
5726      /* make work xsp big enough for both */
5727      push_xstk_(xsp2, endlen);
5728      /* split off high part of number for first, new part for overlap */
5729      /* 3rd argument is length not low end */
5730      __rhspsel(xsp2->ap, xsp->ap, cxlen - 1, endlen);
5731      __rhspsel(xsp2->bp, xsp->bp, cxlen - 1, endlen);
5732      xplp->xp = bld_num_expr(xsp2);
5733      __pop_xstk();
5734      break;
5735      /* bit select impossible because always fits */
5736     default: __case_terr(__FILE__, __LINE__);
5737    }
5738    if (overlaplen > mpwid)
5739     {
5740      /* case 2a: overlap continues for more than one inst */
5741      for (;;)
5742       {
5743        xplp = __alloc_xprlst();
5744        if (xplphd == NULL) xplphd = xplp; else xplp_last->xpnxt = xplp;
5745        xplp_last = xplp;
5746        switch ((byte) xp3->optyp) {
5747         case ID:
5748          np = xp3->lu.sy->el.enp;
5749          /* SJM 07/08/00 - if scalar in concatenate can't convert ot bsel */
5750          if (!np->n_isavec)
5751           {
5752            xplp->xp = __copy_expr(xp3);
5753            break;
5754           }
5755          r1 = overlaplen - 1;
5756          goto bld2_selects;
5757         case PARTSEL:
5758          np = xp3->lu.x->lu.sy->el.enp;
5759          /* here need right range end */
5760          wp = &(__contab[xp3->ru.x->ru.x->ru.xvi]);
5761          r1 = (int32) wp[0] + overlaplen - 1;
5762 bld2_selects:
5763          if (mpwid == 1) xplp->xp = bld_bsel_expr(np, r1);
5764          else xplp->xp = bld_psel_expr(np, r1, r1 - mpwid + 1);
5765          break;
5766         case NUMBER:
5767          /* make work xsp big enough for both */
5768          push_xstk_(xsp2, mpwid);
5769          __rhspsel(xsp2->ap, xsp->ap, overlaplen - 1, mpwid);
5770          __rhspsel(xsp2->bp, xsp->bp, overlaplen - 1, mpwid);
5771          /* must allocate and fill because may be wider than WBITS */
5772          xplp->xp = bld_num_expr(xsp2);
5773          __pop_xstk();
5774          break;
5775         /* bit select impossible because always fits */
5776         default: __case_terr(__FILE__, __LINE__);
5777        }
5778        overlaplen -= mpwid;
5779        /* DBG remove --- */
5780        if (overlaplen < 0) __misc_terr(__FILE__, __LINE__);
5781        /* ---*/
5782        if (overlaplen == 0) goto nxt_catel;
5783        if (overlaplen < mpwid) break;
5784        /* if corrected overlap length equal to or wider than port continue */
5785       }
5786     }
5787    /* final or only end part (if narrower than mpwid) */
5788    xplp = __alloc_xprlst();
5789    if (xplphd == NULL) xplphd = xplp; else xplp_last->xpnxt = xplp;
5790    xplp_last = xplp;
5791    switch ((byte) xp3->optyp) {
5792     case ID:
5793      np = xp3->lu.sy->el.enp;
5794      /* SJM 07/08/00 - if scalar in concatenate can't convert ot bsel */
5795      if (!np->n_isavec)
5796       {
5797        xplp->xp = __copy_expr(xp3);
5798        break;
5799       }
5800      r1 = overlaplen - 1;
5801      goto bld3_selects;
5802     case PARTSEL:
5803      np = xp3->lu.x->lu.sy->el.enp;
5804      /* here need right range end */
5805      wp = &(__contab[xp3->ru.x->ru.x->ru.xvi]);
5806      r1 = (int32) wp[0] + overlaplen - 1;
5807 bld3_selects:
5808      /* split off first part that will then fill to end */
5809      if (overlaplen == 1) xplp->xp = bld_bsel_expr(np, r1);
5810      else xplp->xp = bld_psel_expr(np, r1, r1 - overlaplen + 1);
5811      break;
5812     case NUMBER:
5813      /* make work xsp big enough for both */
5814      push_xstk_(xsp2, overlaplen);
5815      __rhspsel(xsp2->ap, xsp->ap, overlaplen - 1, overlaplen);
5816      __rhspsel(xsp2->bp, xsp->bp, overlaplen - 1, overlaplen);
5817      xplp->xp = bld_num_expr(xsp2);
5818      __pop_xstk();
5819      break;
5820     /* bit select impossible because always fits */
5821     default: __case_terr(__FILE__, __LINE__);
5822    }
5823 nxt_catel:
5824    if (xp3->optyp == NUMBER) __pop_xstk();
5825   }
5826  return(xplphd);
5827 }
5828 
5829 /*
5830  * build a new number expression from a expression stack element
5831  */
bld_num_expr(struct xstk_t * xsp)5832 static struct expr_t *bld_num_expr(struct xstk_t *xsp)
5833 {
5834  int32 nwlen;
5835  struct expr_t *xp;
5836 
5837  xp = __alloc_newxnd();
5838  xp->optyp = NUMBER;
5839  xp->szu.xclen = xsp->xslen;
5840  nwlen = wlen_(xsp->xslen);
5841  if (xsp->xslen <= WBITS)
5842   {
5843    xp->ru.xvi = __alloc_shareable_cval(xsp->ap[0], xsp->ap[1], xsp->xslen);
5844   }
5845  else
5846   {
5847    xp->ru.xvi = __allocfill_cval_new(xsp->ap, xsp->bp, nwlen);
5848   }
5849  return(xp);
5850 }
5851 
5852 /*
5853  * ROUTINES TO RESET AS FIXUP MODULE PORT STRENGTHS AFTER PORT EXPANDING
5854  */
5855 
5856 /*
5857  * set module port strength expression bits
5858  *
5859  * needed because must check expressions to set widths before apportioning
5860  * I/O ports to iconns, but can not propagate strengths until apportioning
5861  * done, so now must go back and set expr x_stren bit if module port
5862  * exprs contains stren wires, all other expressions checked after stren
5863  * propagation so only need to fix up for module ports
5864  */
__reset_modport_strens(void)5865 extern void __reset_modport_strens(void)
5866 {
5867  register int32 pi;
5868  register struct mod_t *mdp;
5869  register struct mod_pin_t *mpp;
5870  int32 pnum;
5871 
5872  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5873   {
5874    /* SJM 12/26/02 - this was wrong - not marking all port strens so */
5875    /* iop gen wasn't working */
5876    if ((pnum = mdp->mpnum) == 0) continue;
5877 
5878    for (pi = 0; pi < pnum; pi++)
5879     {
5880      mpp = &(mdp->mpins[pi]);
5881      set_1mpx_stren(mpp->mpref);
5882     }
5883   }
5884 }
5885 
5886 /*
5887  * set expr. strength bits for module port exprs with strength wires
5888  *
5889  * used recursively on subexprs of ports exprs (not iconn exprs)
5890  */
set_1mpx_stren(struct expr_t * mpx)5891 static void set_1mpx_stren(struct expr_t *mpx)
5892 {
5893  int32 cat_stren;
5894  struct net_t *np;
5895  struct sy_t *syp;
5896 
5897  switch ((byte) mpx->optyp) {
5898   case ID: case GLBREF:
5899    np = mpx->lu.sy->el.enp;
5900    if (np->n_stren) mpx->x_stren = TRUE;
5901    break;
5902   case NUMBER: case ISNUMBER: case OPEMPTY: case REALNUM: case ISREALNUM:
5903    break;
5904   case LSB:
5905    syp = mpx->lu.x->lu.sy;
5906    np = syp->el.enp;
5907    if (np->n_stren) mpx->x_stren = TRUE;
5908    set_1mpx_stren(mpx->ru.x);
5909    break;
5910   case PARTSEL:
5911    syp = mpx->lu.x->lu.sy;
5912    np = syp->el.enp;
5913    if (np->n_stren) mpx->x_stren = TRUE;
5914    set_1mpx_stren(mpx->ru.x->lu.x);
5915    set_1mpx_stren(mpx->ru.x->ru.x);
5916    break;
5917   case QUEST:
5918    set_1mpx_stren(mpx->lu.x);
5919    set_1mpx_stren(mpx->ru.x->ru.x);
5920    set_1mpx_stren(mpx->ru.x->lu.x);
5921    break;
5922   case FCALL: return;
5923   case LCB:
5924    {
5925     register struct expr_t *ndp2;
5926     struct expr_t *catxp;
5927 
5928     /* know concatenates never nested by here */
5929     for (cat_stren = FALSE, ndp2 = mpx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
5930      {
5931       catxp = ndp2->lu.x;
5932       set_1mpx_stren(catxp);
5933       if (catxp->x_stren) { ndp2->x_stren = TRUE; cat_stren = TRUE; }
5934      }
5935     if (cat_stren) mpx->x_stren = TRUE;
5936    }
5937    break;
5938   default:
5939    if (mpx->lu.x != NULL) set_1mpx_stren(mpx->lu.x);
5940    if (mpx->ru.x != NULL) set_1mpx_stren(mpx->ru.x);
5941  }
5942 }
5943 
5944 /*
5945  * MODULE COMPONENT SEMANTIC CHECKING ROUTINES
5946  */
5947 
5948 /*
5949  * check module - also call procedure checking routines
5950  * does the following:
5951  *  1) global refs. hanged to ids
5952  *  2) constant expr. folded and node widths set
5953  *
5954  * notice all code called from here requires __inst_mod to be set for
5955  * finding size of IS form parmeters that are converted to constants here
5956  */
__chk_mod(void)5957 extern void __chk_mod(void)
5958 {
5959  register struct task_t *tskp;
5960 
5961  /* check inst. conns. and gates */
5962  chk_inst_conns();
5963  chk_gates();
5964  chk_contas();
5965 
5966  /* SJM 09/30/04 - although variable assign initialize decls require */
5967  /* constant rhs expr, not checking the expression until here */
5968  /* because semantics is same as decl followed by initial [var] = [expr]; */
5969  chk_varinits();
5970 
5971  /* check init/always statements */
5972  chk_stmts();
5973 
5974  /* finally check user tasks and function statements */
5975  for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
5976   {
5977    switch ((byte) tskp->tsktyp) {
5978     case FUNCTION:
5979      /* named blocks checked in context */
5980      chk_funcdef(tskp);
5981      tskp->thas_outs = FALSE;
5982      tskp->thas_tskcall = FALSE;
5983      break;
5984     case TASK:
5985      chk_1tsk(tskp);
5986      break;
5987     /* named block task checked when statement seen */
5988     case Begin: case FORK: break;
5989     default: __case_terr(__FILE__, __LINE__);
5990    }
5991   }
5992 }
5993 
5994 /*
5995  * check 1 task
5996  * notice this is task definition so cannot be called from iact
5997  */
chk_1tsk(struct task_t * tskp)5998 static void chk_1tsk(struct task_t *tskp)
5999 {
6000  register struct task_pin_t *tpp;
6001  int32 ai;
6002  struct net_t *np;
6003  struct sy_t *syp;
6004 
6005  __cur_tsk = tskp;
6006  /* variables checked, chk statements & look for non thread optimizations */
6007  for (ai = 1, tpp = tskp->tskpins; tpp != NULL; tpp = tpp->tpnxt, ai++)
6008   {
6009    np = tpp->tpsy->el.enp;
6010    /* SJM 01/14/1999 - arrays illegal formal function arguments */
6011    if (np->n_isarr)
6012     {
6013      syp = tpp->tpsy;
6014      __gferr(869, syp->syfnam_ind, syp->sylin_cnt,
6015       "task %s definition entire array formal argument %s (pos. %d) illegal - must be simple variable",
6016       tskp->tsksyp->synam, syp->synam, ai);
6017      continue;
6018     }
6019 
6020    /* notice task ports must be regs so no need to set 2nd on lhs */
6021    if (tpp->trtyp != IO_IN)
6022     {
6023      if (np->nrngrep == NX_CT)
6024       {
6025        if (tpp->trtyp == IO_BID) np->nu.ct->n_onlhs = TRUE;
6026        np->nu.ct->n_onrhs = TRUE;
6027       }
6028      tskp->thas_outs = TRUE;
6029     }
6030    else if (np->nrngrep == NX_CT) np->nu.ct->n_onlhs = TRUE;
6031   }
6032  /* notice that task can take any legal variables no argument */
6033  /* requirements - this finds any named block no delay cases */
6034  __chk_lstofsts(tskp->tskst);
6035 
6036  /* finally do checking to determine if 0 delay or has task call */
6037  __task_has_delay = FALSE;
6038  __task_has_tskcall = FALSE;
6039  __nbsti = -1;
6040  __chk_nodel_lstofsts(tskp->tskst);
6041  __cur_tsk = NULL;
6042 }
6043 
6044 /*
6045  * check module instance connections
6046  * expression here can be numbers with IS form so need to check
6047  * all instances in that case
6048  * this frees cell_pin_t since not used after here
6049  */
chk_inst_conns(void)6050 static void chk_inst_conns(void)
6051 {
6052  register int32 pi, ii;
6053  register struct mod_pin_t *mpp;
6054  int32 iotyp, sav_enum;
6055  int32 pnum, pwid;
6056  struct inst_t *ip;
6057  struct mod_t *imdp;
6058  struct expr_t *pxp;
6059  struct srcloc_t *slocp;
6060  struct net_t *np;
6061 
6062  __expr_rhs_decl = TRUE;
6063  for (ii = 0; ii < __inst_mod->minum; ii++)
6064   {
6065    ip = &(__inst_mod->minsts[ii]);
6066    imdp = ip->imsym->el.emdp;
6067    if ((pnum = imdp->mpnum) == 0) continue;
6068    slocp = __inst_mod->iploctab[ii];
6069 
6070    for (pi = 0; pi < pnum; pi++)
6071     {
6072      mpp = &(imdp->mpins[pi]);
6073      pxp = ip->ipins[pi];
6074      __sfnam_ind = slocp[pi].sl_fnam_ind;
6075      __slin_cnt = slocp[pi].sl_lin_cnt;
6076 
6077      /* this should always be at least OPEMPTY by here */
6078      /* change to special unc. indicator and check/fix here */
6079      /* instance one port missing 'bx for unconnect */
6080      /* DBG remove --- */
6081      if (pxp == NULL) __misc_sgfterr(__FILE__, __LINE__);
6082      /* --- */
6083 
6084      /* module port iconn cannot have real connection */
6085      if (pxp->is_real)
6086       __sgferr(780,
6087        "instance %s port %s (pos. %d) illegally connects to real number",
6088        ip->isym->synam, __msgexpr_tostr(__xs, pxp), pi + 1);
6089 
6090      /* cannot be xmr that references down into same inst. */
6091      sav_enum = __pv_err_cnt;
6092      chk_iconn_downxmr(ip, pxp);
6093      if (sav_enum < __pv_err_cnt) continue;
6094 
6095      pwid = mpp->mpwide;
6096      /* if first time implicitly declared wire used change to port width */
6097      /* if first use if as scalar and later other must still fix here */
6098      if (pxp->optyp == ID)
6099       {
6100        /* SJM 03/15/00 - must catch passing non wire ID as error */
6101        if (pxp->lu.sy->sytyp != SYM_N)
6102         {
6103          __sgferr(789, "instance %s port pos. %d illegally connects to %s %s",
6104           ip->isym->synam, pi + 1, __to_sytyp(__xs, pxp->lu.sy->sytyp),
6105           __msgexpr_tostr(__xs2, pxp));
6106          continue;
6107         }
6108        np = pxp->lu.sy->el.enp;
6109        if (np->nu.ct->n_impldecl && !np->nu.ct->n_rngknown)
6110         {
6111          /* change to vectored wire with same direction range as port */
6112          if (pwid > 1)
6113           {
6114            np->nu.ct->nx1 = __bld_rng_numxpr((word32) (pwid - 1), 0L, WBITS);
6115            np->nu.ct->nx2 = __bld_rng_numxpr(0L, 0L, WBITS);
6116            np->n_isavec = TRUE;
6117            np->nwid = pwid;
6118            /* vectored/scalared set to default scalared state at prep time */
6119            __sgfinform(472,
6120             "implicitly declared %s %s width changed to %d to match port width",
6121             __to_wtnam(__xs, np), np->nsym->synam, pwid);
6122           }
6123          np->nu.ct->n_rngknown = TRUE;
6124          __chg_rng_direct = TRUE;
6125         }
6126       }
6127 
6128      iotyp = mpp->mptyp;
6129      if (iotyp == IO_IN)
6130       {
6131        /* fix unc. drive to special type of constant */
6132        if (pxp->optyp == OPEMPTY)
6133         {
6134          pxp->szu.xclen = pwid;
6135          /* change node type so will eval. to right value */
6136          if (pxp->unc_pull != NO_UNCPULL) pxp->optyp = UNCONNPULL;
6137 
6138          __sgfinform(473,
6139           "instance %s input port %s (pos. %d) width %d unconnected",
6140           ip->isym->synam, __to_mpnam(__xs, mpp->mpsnam), pi + 1, pwid);
6141 
6142          continue;
6143         }
6144        /* notice for IS forms checks each */
6145        __chk_rhsexpr(pxp, pwid);
6146       }
6147      else
6148       {
6149        /* either output or inout */
6150        /* make OPEMPTY not unconn. drive strength form */
6151        if (pxp->optyp == OPEMPTY)
6152         {
6153          pxp->szu.xclen = pwid;
6154          if (pxp->x_stren) { pxp->x_stren = FALSE; pxp->ru.xvi = -1; }
6155          if (mpp->mptyp == IO_BID && !mpp->mp_jmpered)
6156           {
6157            __sgfinform(473,
6158             "instance %s inout port %s (pos. %d) width %d unconnected",
6159             ip->isym->synam, __to_mpnam(__xs, mpp->mpsnam), pi + 1, pwid);
6160           }
6161          /* already emitted special case inout unc. - not jumpered, etc. */
6162          /* 11/06/00 SJM - to match XL emit inform for every unc. port */
6163          if (mpp->mptyp != IO_BID)
6164           {
6165            __sgfinform(473,
6166             "instance %s output port %s (pos. %d) width %d unconnected",
6167             ip->isym->synam, __to_mpnam(__xs, mpp->mpsnam), pi + 1, pwid);
6168           }
6169          continue;
6170         }
6171        pxp->szu.xclen = pwid;
6172        __chk_lhsexpr(pxp, LHS_DECL);
6173        /* inout is also rhs expression */
6174        if (iotyp == IO_BID) __set_expr_onrhs(pxp);
6175       }
6176      /* if error in expr., do not emit size warning */
6177      if (sav_enum < __pv_err_cnt) continue;
6178 
6179      /* check port width mismatch */
6180      if (pxp->szu.xclen != pwid)
6181       {
6182        char s2[20], s3[RECLEN];
6183 
6184        __sgfwarn(602,
6185         "%s(%s) %s port %s (line %s) width %d mismatch with %s width %d",
6186         ip->isym->synam, ip->imsym->synam, __to_ptnam(s2, mpp->mptyp),
6187         __to_mpnam(s3, mpp->mpsnam), __bld_lineloc(__xs, mpp->mpfnam_ind,
6188         mpp->mplin_cnt), pwid, __msgexpr_tostr(__xs2, pxp), pxp->szu.xclen);
6189       }
6190 
6191      /* check same wire directions - if either concat do not check */
6192      /* know now both mod and inst port exprs checked */
6193      chk_iconn_mixeddirrng(ip, mpp, pxp);
6194      /* SJM - 10/08/99 - always turn off impl decl change dir since */
6195      /* if implicit scalar will not go through reverse code */
6196      __chg_rng_direct = FALSE;
6197     }
6198   }
6199  __expr_rhs_decl = FALSE;
6200 }
6201 
6202 /*
6203  * for inout I/O port expr. must set both rhs bits
6204  */
__set_expr_onrhs(struct expr_t * ndp)6205 extern void __set_expr_onrhs(struct expr_t *ndp)
6206 {
6207  struct net_t *np;
6208 
6209  if (__isleaf(ndp))
6210   {
6211    if (ndp->optyp == ID || ndp->optyp == GLBREF)
6212     {
6213      np = ndp->lu.sy->el.enp;
6214      if (np->nrngrep == NX_CT)
6215       {
6216        if (np->iotyp == NON_IO) np->nu.ct->n_onrhs = TRUE;
6217       }
6218      if (!__expr_rhs_decl) np->n_onprocrhs = TRUE;
6219     }
6220    return;
6221   }
6222  if (ndp->lu.x != NULL) __set_expr_onrhs(ndp->lu.x);
6223  if (ndp->ru.x != NULL) __set_expr_onrhs(ndp->ru.x);
6224 }
6225 
6226 /*
6227  * check for all xmrs in expr. and emit error if xmr into instance
6228  * know expr. is instance connection
6229  */
chk_iconn_downxmr(struct inst_t * ip,struct expr_t * ndp)6230 static void chk_iconn_downxmr(struct inst_t *ip, struct expr_t *ndp)
6231 {
6232  register int32 pthi;
6233  struct sy_t *syp;
6234 
6235  if (__isleaf(ndp))
6236   {
6237    if (ndp->optyp == GLBREF)
6238     {
6239      struct gref_t *grp;
6240 
6241      grp = ndp->ru.grp;
6242      if (grp->upwards_rel || grp->gr_gone || grp->gr_err) return;
6243      for (pthi = 0; pthi <= grp->last_gri; pthi++)
6244       {
6245        syp = grp->grcmps[pthi];
6246        if (syp == ip->isym)
6247         {
6248          __sgferr(788,
6249           "in module %s: instance %s port list contains hierarchical reference %s into same instance",
6250           __inst_mod->msym->synam, ip->isym->synam, grp->gnam);
6251         }
6252       }
6253     }
6254    return;
6255   }
6256  if (ndp->lu.x != NULL) chk_iconn_downxmr(ip, ndp->lu.x);
6257  if (ndp->ru.x != NULL) chk_iconn_downxmr(ip, ndp->ru.x);
6258 }
6259 
6260 /*
6261  * check for mixed direction range instance
6262  */
chk_iconn_mixeddirrng(struct inst_t * ip,struct mod_pin_t * mpp,struct expr_t * ipxp)6263 static void chk_iconn_mixeddirrng(struct inst_t *ip,
6264  struct mod_pin_t *mpp, struct expr_t *ipxp)
6265 {
6266  int32 one_is_bsel, porthl, iphl, tmp;
6267  int32 portr1, portr2, ipr1, ipr2;
6268  struct net_t *portnp, *ipnp;
6269  char porthls[20], iphls[20];
6270 
6271  /* only check for both psel, id or global, if either bsel, 1 inform */
6272  one_is_bsel = FALSE;
6273  switch ((byte) mpp->mpref->optyp) {
6274   case ID: case GLBREF: portnp = mpp->mpref->lu.sy->el.enp; break;
6275   case PARTSEL:
6276 get_portsel_np:
6277    portnp = mpp->mpref->lu.x->lu.sy->el.enp;
6278    break;
6279   case LSB:
6280    one_is_bsel = TRUE;
6281    goto get_portsel_np;
6282   default: return;
6283  }
6284  if (!portnp->n_isavec) return;
6285  switch ((byte) ipxp->optyp) {
6286   case ID: case GLBREF: ipnp = ipxp->lu.sy->el.enp; break;
6287   case PARTSEL:
6288 get_ipsel_np:
6289    ipnp = ipxp->lu.x->lu.sy->el.enp;
6290    break;
6291   case LSB:
6292    one_is_bsel = TRUE;
6293    goto get_ipsel_np;
6294   default: return;
6295  }
6296  if (!ipnp->n_isavec) return;
6297  __getwir_range(portnp, &portr1, &portr2);
6298  __getwir_range(ipnp, &ipr1, &ipr2);
6299 
6300  /* if either is 1 bit range, no warn/inform */
6301  if (portr1 == portr2 || ipr1 == ipr2) return;
6302 
6303  /* here if this is implicitly declared from inst. conn. wire, just fix */
6304  if (__chg_rng_direct)
6305   {
6306    /* if port really low high, reverse range */
6307    if (portr1 < portr2)
6308     {
6309      /* only need to reverse con tab pointers */
6310      tmp = ipnp->nu.ct->nx1->ru.xvi;
6311      ipnp->nu.ct->nx1->ru.xvi = ipnp->nu.ct->nx2->ru.xvi;
6312      ipnp->nu.ct->nx2->ru.xvi = tmp;
6313     }
6314    __chg_rng_direct = FALSE;
6315    return;
6316   }
6317 
6318  if (portr1 >= portr2)
6319   { porthl = TRUE; strcpy(porthls, "high to low"); }
6320  else { porthl = FALSE; strcpy(porthls, "low to high"); }
6321  if (ipr1 >= ipr2)
6322   { iphl = TRUE; strcpy(iphls, "high to low"); }
6323  else { iphl = FALSE; strcpy(iphls, "low to high"); }
6324 
6325  if (porthl != iphl)
6326   {
6327    char s1[2*IDLEN], s2[20];
6328 
6329    sprintf(s1, "%s [%d:%d] %s at %s",
6330     __to_ptnam(s2, mpp->mptyp), portr1, portr2, portnp->nsym->synam,
6331     __bld_lineloc(__xs, mpp->mpfnam_ind, mpp->mplin_cnt));
6332    if (one_is_bsel)
6333     {
6334      __sgfinform(412,
6335       "type %s instance %s range [%d:%d] direction mismatch with %s",
6336       ip->imsym->synam, ip->isym->synam, ipr1, ipr2, s1);
6337     }
6338    else
6339     {
6340      __sgfwarn(556,
6341       "type %s instance %s range [%d:%d] direction mismatch with %s",
6342       ip->imsym->synam, ip->isym->synam, ipr1, ipr2, s1);
6343     }
6344   }
6345 }
6346 
6347 /*
6348  * free module port line no.s for one module if not already freed
6349  * for split all will share so only one needs to be freed
6350  */
__free_icptab(void)6351 extern void __free_icptab(void)
6352 {
6353  register int32 ii;
6354  int32 pnum;
6355  struct srcloc_t *iplocs;
6356  struct inst_t *ip;
6357  struct mod_t *imdp;
6358 
6359  /* only free module from original source list */
6360  if (!__inst_mod->msplit && !__inst_mod->mpndsplit)
6361   {
6362    for (ii = 0; ii < __inst_mod->minum; ii++)
6363     {
6364      /* ptr to table of actual src loc records */
6365      iplocs = __inst_mod->iploctab[ii];
6366 
6367      ip = &(__inst_mod->minsts[ii]);
6368      imdp = ip->imsym->el.emdp;
6369      /* number of ports if number for contained inst */
6370      if ((pnum = imdp->mpnum) != 0)
6371       __my_free((char *) iplocs, pnum*sizeof(struct srcloc_t));
6372     }
6373    if (__inst_mod->minum != 0)
6374     {
6375      __my_free((char *) __inst_mod->iploctab,
6376       __inst_mod->minum*sizeof(struct srcloc_t **));
6377     }
6378   }
6379  __inst_mod->iploctab = NULL;
6380 }
6381 
6382 /*
6383  * check gate and continuous assigns
6384  * notice at this point continuous assignments still not split off
6385  */
chk_gates(void)6386 static void chk_gates(void)
6387 {
6388  register int32 gi, pi;
6389  register struct gate_t *gp;
6390  int32 dnum, nins;
6391  struct expr_t *xp;
6392  struct net_t *np;
6393  struct paramlst_t *dhdr;
6394 
6395  /* check gates first */
6396  __expr_rhs_decl = TRUE;
6397  for (gi = 0; gi < __inst_mod->mgnum; gi++)
6398   {
6399    gp = &(__inst_mod->mgates[gi]);
6400 
6401    __sfnam_ind = gp->gsym->syfnam_ind;
6402    __slin_cnt = gp->gsym->sylin_cnt;
6403    if (gp->g_class != GC_UDP)
6404     {
6405      /* returns FALSE if special gate (pull?), will then not check ports */
6406      /* know output port checked later */
6407      if (!chk_1bltingate(gp)) continue;
6408      nins = gp->gpnum - 1;
6409     }
6410    else
6411     {
6412      /* SJM 07/02/03 - if error here will core dump if keeps checking */
6413      if (!chk_1udp(gp)) continue;
6414      nins = gp->gmsym->el.eudpp->numins;
6415     }
6416 
6417    /* returns F on fail, must convert to unc. OPEMPTY */
6418    if (!chk_gate_source(gp, gp->gpins[0], TRUE, FALSE, &np))
6419     { __free_xtree(gp->gpins[0]); set_unc_gateterm(gp, 0); }
6420    for (pi = 0; pi < nins; pi++)
6421     {
6422      /* can tell i/o type from gate order */
6423      xp = gp->gpins[pi + 1];
6424      __chk_rhsexpr(xp, 1);
6425      if (xp->is_real)
6426       __sgferr(781,
6427        "gate or udp %s input terminal %s (pos. %d) cannot have real value",
6428        gp->gmsym->synam, __msgexpr_tostr(__xs2, xp), pi + 1);
6429      /* for implicitly declared must mark as scalar if first use */
6430      if (xp->optyp == ID)
6431       {
6432        np = xp->lu.sy->el.enp;
6433        if (np->nu.ct->n_impldecl && !np->nu.ct->n_rngknown)
6434         np->nu.ct->n_rngknown = TRUE;
6435       }
6436     }
6437    if (gp->g_du.pdels == NULL) continue;
6438 
6439    /* check delay params, sim array built later */
6440    if (gp->g_class == GC_UDP)
6441     {
6442      dhdr = __copy_dellst(gp->g_du.pdels);
6443      if ((dnum = __chk_delparams(dhdr, "udp delay", FALSE)) == -1)
6444       gp->g_du.pdels = NULL;
6445      else if (dnum > 2)
6446       {
6447        __sgferr(782, "udp has more than 2 delays (%d)", dnum);
6448        gp->g_du.pdels = NULL;
6449       }
6450      __free_dellst(dhdr);
6451     }
6452    else
6453     {
6454      dhdr = __copy_dellst(gp->g_du.pdels);
6455      if ((dnum = __chk_delparams(dhdr, "built-in gate delay", FALSE)) == -1)
6456       gp->g_du.pdels = NULL;
6457      else if (gp->g_class == GC_LOGIC)
6458       {
6459        if (dnum > 2)
6460         {
6461          __sgferr(783, "%s logic gate has more than 2 delays (%d)",
6462           gp->gmsym->synam, dnum);
6463           gp->g_du.pdels = NULL;
6464         }
6465       }
6466      else if (dnum > 3)
6467       {
6468        __sgferr(775, "%s gate has more than 3 delays (%d)",
6469         gp->gmsym->synam, dnum);
6470        gp->g_du.pdels = NULL;
6471       }
6472      __free_dellst(dhdr);
6473     }
6474   }
6475  /* unless looking for declarative, must leave in off state */
6476  __expr_rhs_decl = FALSE;
6477 }
6478 
6479 /*
6480  * check 1 built in gate (not udps and 1 bit contas still not gates)
6481  * notice normal gate just falls through and only terminal list checked
6482  * return F to prevent normal 1st only output gate expression checking
6483  * if returns F must call expression checking for each port itself
6484  *
6485  */
chk_1bltingate(struct gate_t * gp)6486 static int32 chk_1bltingate(struct gate_t *gp)
6487 {
6488  int32 pnum;
6489  struct primtab_t *ptp;
6490 
6491  pnum = gp->gpnum;
6492  ptp = gp->gmsym->el.eprimp;
6493  switch ((byte) ptp->gateid) {
6494   case G_BUF: case G_NOT:
6495    if (pnum == 1) __sgferr(784,
6496     "%s gate requires at least 2 terminals", ptp->gatnam);
6497    else if (pnum != 2)
6498     __sgferr(785, "%s gate with multiple outputs unsupported", ptp->gatnam);
6499    break;
6500   case G_BUFIF0: case G_BUFIF1: case G_NOTIF0: case G_NOTIF1:
6501    if (pnum != 3) gate_errifn(gp, 3);
6502    break;
6503   case G_RPMOS: case G_RNMOS:
6504    /*FALLTHRU */
6505   case G_NMOS: case G_PMOS:
6506    chk_gate_nostren(gp);
6507    if (pnum != 3) gate_errifn(gp, 3);
6508    break;
6509   case G_RCMOS:
6510    /*FALLTHRU */
6511   case G_CMOS:
6512    chk_gate_nostren(gp);
6513    if (pnum != 4) gate_errifn(gp, 4);
6514    break;
6515   case G_PULLDOWN: case G_PULLUP:
6516    chk_pull_gate(gp);
6517    /* this inhibits normal checking of ports */
6518    return(FALSE);
6519   case G_TRAN: case G_RTRAN:
6520    chk_tran_gate(gp);
6521    return(FALSE);
6522   case G_TRANIF0: case G_TRANIF1: case G_RTRANIF0: case G_RTRANIF1:
6523    chk_tranif_gate(gp);
6524    return(FALSE);
6525   default:
6526    if (pnum < 2)
6527     {
6528      __sgferr(786, "%s gate requires at least 2 terminals", gp->gmsym->synam);
6529     }
6530    else if (pnum < 3)
6531     {
6532      __sgfwarn(573, "%s gate has only %d terminals - should have at least 3",
6533       gp->gmsym->synam, pnum);
6534     }
6535   }
6536  return(TRUE);
6537 }
6538 
6539 /*
6540  * write a message for a if type gate that needs 3 terminals
6541  */
gate_errifn(struct gate_t * gp,int32 n)6542 static void gate_errifn(struct gate_t *gp, int32 n)
6543 {
6544  __sgferr(787, "%s gate does not have required %d terminals",
6545   gp->gmsym->synam, n);
6546 }
6547 
6548 /*
6549  * emit warning and remove strength on gate that should not have it
6550  */
chk_gate_nostren(struct gate_t * gp)6551 static void chk_gate_nostren(struct gate_t *gp)
6552 {
6553  if (gp->g_hasst)
6554   {
6555    __sgfwarn(537, "%s gate cannot have strength", gp->gmsym->synam);
6556    gp->g_hasst = FALSE;
6557    gp->g_stval = ST_STRVAL;
6558   }
6559 }
6560 
6561 /*
6562  * check a tran style gate
6563  */
chk_tran_gate(struct gate_t * gp)6564 static void chk_tran_gate(struct gate_t *gp)
6565 {
6566  int32 pnum;
6567  struct expr_t *px1, *px2;
6568  struct net_t *np1, *np2;
6569 
6570  np1 = np2 = NULL;
6571  /* first cannot have delay */
6572  if (gp->g_du.pdels != NULL)
6573   {
6574    __sgferr(816, "%s cannot have delay", gp->gmsym->synam);
6575    __free_dellst(gp->g_du.pdels);
6576    gp->g_du.pdels = NULL;
6577   }
6578  /* must mark as no del since later expression checking expects no delay */
6579  gp->g_delrep = DT_NONE;
6580 
6581  /* any tran can't have strength - signal strength is preserved according */
6582  /* to resistive or not mos table */
6583  chk_gate_nostren(gp);
6584  px1 = px2 = NULL;
6585  pnum = gp->gpnum;
6586  if (pnum != 2) gate_errifn(gp, 2);
6587  if (pnum >= 1) px1 = gp->gpins[0];
6588  if (pnum >= 2) px2 = gp->gpins[1];
6589  /* for these both terminals must be lhs */
6590  if (px1 != NULL)
6591   {
6592    if (!chk_gate_source(gp, px1, TRUE, TRUE, &np1))
6593     {
6594     __free_xtree(px1);
6595      /* this cannot build unc expr since cannot set pull only for inst */
6596      set_unc_gateterm(gp, 0);
6597     }
6598    else chk_1bit_tran(gp, px1, np1, 1);
6599   }
6600 
6601  if (px2 != NULL)
6602   {
6603    if (!chk_gate_source(gp, px2, TRUE, TRUE, &np2))
6604     { __free_xtree(px2); set_unc_gateterm(gp, 1); }
6605    else chk_1bit_tran(gp, px2, np2, 2);
6606   }
6607  __inst_mod->mod_gatetran = TRUE;
6608  /* SJM 04/26/01 - if both terminals same, emit warning and mark as gone */
6609  chk_tran_terms_same(gp);
6610 }
6611 
6612 /*
6613  * check for tran or tranif with both inout terminals same expr
6614  * if so emit warning and mark deleted from net list
6615  * return T if deleted
6616  */
chk_tran_terms_same(struct gate_t * gp)6617 static int32 chk_tran_terms_same(struct gate_t *gp)
6618 {
6619  struct expr_t *xp1, *xp2;
6620  struct net_t *np1, *np2;
6621  int32 i1, i2;
6622 
6623  xp1 = gp->gpins[0];
6624  xp2 = gp->gpins[1];
6625  if (xp1->optyp == ID && xp2->optyp == ID)
6626   {
6627    np1 = xp1->lu.sy->el.enp;
6628    np2 = xp2->lu.sy->el.enp;
6629    /* since not xmr, can compare net addrs */
6630    if (np1 == np2)
6631     {
6632      __gfwarn(3117, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
6633       "%s %s inout terminals (%s) identical - removed because has no effect",
6634       gp->gmsym->synam, gp->gsym->synam, np1->nsym->synam);
6635      gp->g_gone = TRUE;
6636     }
6637    return(TRUE);
6638   }
6639  if (xp1->optyp == LSB && xp2->optyp == LSB)
6640   {
6641    np1 = xp1->lu.x->lu.sy->el.enp;
6642    np2 = xp2->lu.x->lu.sy->el.enp;
6643    /* know same net */
6644    if (np1 != np2) return(FALSE);
6645 
6646    if (xp1->ru.x->optyp != NUMBER || xp2->ru.x->optyp != NUMBER)
6647     return(FALSE);
6648    i1 = __contab[xp1->ru.x->ru.xvi];
6649    i2 = __contab[xp2->ru.x->ru.xvi];
6650    if (i1 == i2)
6651     {
6652      __gfwarn(3117, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
6653       "%s %s inout terminals (%s[%d]) identical - gate removed because has not effect",
6654       gp->gmsym->synam, gp->gsym->synam, np1->nsym->synam, i1);
6655      gp->g_gone = TRUE;
6656     }
6657   }
6658  return(FALSE);
6659 }
6660 
6661 /*
6662  * set unc (OPEMPTY) for gate terminal
6663  */
set_unc_gateterm(struct gate_t * gp,int32 pi)6664 static void set_unc_gateterm(struct gate_t *gp, int32 pi)
6665 {
6666  /* cannot use bld unc expr here since sets pull but that only for */
6667  /* for instances */
6668  __root_ndp = __alloc_newxnd();
6669  __root_ndp->optyp = OPEMPTY;
6670  __root_ndp->folded = TRUE;
6671  __root_ndp->szu.xclen = 1;
6672  gp->gpins[pi] = __root_ndp;
6673 }
6674 
6675 /*
6676  * check to make sure tran bidirectional terminal only connect to scalar
6677  * nets or bit selects
6678  */
chk_1bit_tran(struct gate_t * gp,struct expr_t * px,struct net_t * np,int32 termno)6679 static void chk_1bit_tran(struct gate_t *gp, struct expr_t *px,
6680  struct net_t *np, int32 termno)
6681 {
6682  if (px->optyp == OPEMPTY)
6683   {
6684    __sgfwarn(581, "%s terminal %d unconnected - switch has no effect",
6685     gp->gmsym->synam, termno);
6686    return;
6687   }
6688  /* 07/08/00 SJM - because of complexity with switch channal also can't be */
6689  /* ID must be select of ID */
6690  if (px->optyp == PARTSEL || (px->optyp != LSB && np->n_isavec)
6691   || ((px->optyp == GLBREF || px->optyp == ID)
6692   && px->lu.sy->el.enp->nwid > 1))
6693   {
6694    __sgferr(1237, "%s terminal %d - %s not scalar or scalared bit select",
6695     gp->gmsym->synam, termno, __msgexpr_tostr(__xs, px));
6696    return;
6697   }
6698  /* by here any constant converted to empty and caught above */
6699  if (np->nu.ct->n_dels_u.pdels != NULL)
6700   {
6701    __sgferr(1238,
6702     "%s terminal %d (%s) - wire %s in tran channel illegally has wire delay",
6703     gp->gmsym->synam, termno, __msgexpr_tostr(__xs, px), np->nsym->synam);
6704   }
6705 }
6706 
6707 /*
6708  * check a tranif style gate
6709  */
chk_tranif_gate(struct gate_t * gp)6710 static void chk_tranif_gate(struct gate_t *gp)
6711 {
6712  int32 dnum, pnum;
6713  struct paramlst_t *dhdr;
6714  struct net_t *np1, *np2;
6715  struct expr_t *px1, *px2, *px3;
6716 
6717  np1 = np2 = NULL;
6718  if (gp->g_du.pdels != NULL)
6719   {
6720    /* can have 0,1 or 2 delays */
6721    dhdr = __copy_dellst(gp->g_du.pdels);
6722    if ((dnum = __chk_delparams(dhdr, "tranif enable delay", TRUE)) == -1)
6723     gp->g_du.pdels = NULL;
6724    else if (dnum > 2)
6725     {
6726      __sgferr(799, "%s gate has more than 2 delays (%d)", gp->gmsym->synam,
6727       dnum);
6728      gp->g_du.pdels = NULL;
6729     }
6730    __free_dellst(dhdr);
6731   }
6732 
6733  /* any tran can't have strength - signal strength is preserved according */
6734  /* to resistive or not mos table */
6735  chk_gate_nostren(gp);
6736  px1 = px2 = NULL;
6737  pnum = gp->gpnum;
6738  if (pnum != 3) gate_errifn(gp, 3);
6739  if (pnum >= 1) px1 = gp->gpins[0];
6740  if (pnum >= 2) px2 = gp->gpins[1];
6741  /* for these both terminal must be lhs */
6742  if (px1 != NULL)
6743   {
6744    if (!chk_gate_source(gp, px1, TRUE, TRUE, &np1))
6745     { __free_xtree(px1); set_unc_gateterm(gp, 0); }
6746    else chk_1bit_tran(gp, px1, np1, 1);
6747   }
6748  if (px2 != NULL)
6749   {
6750    if (!chk_gate_source(gp, px2, TRUE, TRUE, &np2))
6751     { __free_xtree(px2); set_unc_gateterm(gp, 1); }
6752    else chk_1bit_tran(gp, px2, np2, 2);
6753   }
6754  if (pnum < 3) return;
6755 
6756  /* check 3rd control normal input terminal */
6757  px3 = gp->gpins[2];
6758  __chk_rhsexpr(px3, 1);
6759  if (px3->is_real)
6760   __sgferr(781, "%s gate input terminal value %s cannot be real",
6761    gp->gmsym->synam, __msgexpr_tostr(__xs2, px3));
6762  __inst_mod->mod_gatetran = TRUE;
6763 
6764  /* SJM 04/26/01 - if both terminals same, emit warning and mark as gone */
6765  chk_tran_terms_same(gp);
6766 }
6767 
6768 /*
6769  * check a pull gate - can any any length list of lhs sources
6770  * all pull pins are outputs
6771  */
chk_pull_gate(struct gate_t * gp)6772 static void chk_pull_gate(struct gate_t *gp)
6773 {
6774  register int32 i;
6775  struct expr_t *xp;
6776  struct net_t *np;
6777 
6778  /* first cannot have delay */
6779  if (gp->g_du.pdels != NULL)
6780   {
6781    __sgferr(816, "%s source cannot have delay", gp->gmsym->synam);
6782    __free_dellst(gp->g_du.pdels);
6783    gp->g_du.pdels = NULL;
6784   }
6785  /* must mark as no del since later expression checking expects no delay */
6786  gp->g_delrep = DT_NONE;
6787 
6788  /* for pull sources, stength defaults to pull not strong */
6789  /* LOOKATME - pull gate always has strength so g_hasst not checked */
6790  if (!gp->g_hasst) gp->g_stval = 0x2d;
6791  else if (gp->g_stval == 0x00)
6792   {
6793    __sgferr(1151, "%s source highz[01] strength illegal",
6794     gp->gmsym->synam);
6795   }
6796  else if (gp->g_stval == 0x3f)
6797   {
6798    __sgfwarn(546, "%s source supply[01] strength same as supply declaration",
6799     gp->gmsym->synam);
6800   }
6801 
6802  /* all ports must be legal lhs expressions except no concat and xmr */
6803  /* notice constant bit and part selects ok */
6804  for (i = 0; i < (int32) gp->gpnum; i++)
6805   {
6806    xp = gp->gpins[i];
6807    __chk_lhsexpr(xp, LHS_DECL);
6808    if (xp->optyp == LCB)
6809     {
6810      __sgferr(951, "%s source %s (pos. %d) cannot drive concatenate",
6811       gp->gmsym->synam, __msgexpr_tostr(__xs, xp), i + 1);
6812      continue;
6813     }
6814    if (xp->optyp == GLBREF)
6815     {
6816      __sgferr(959,
6817       "%s source cannot drive cross module reference %s (pos. %d)",
6818       gp->gmsym->synam, __msgexpr_tostr(__xs, xp), i + 1);
6819      continue;
6820     }
6821    else if (xp->optyp == OPEMPTY)
6822     {
6823      __sgferr(965,
6824       "%s source empty (,,) terminal list element (pos. %d) illegal",
6825       gp->gmsym->synam, i + 1);
6826      continue;
6827     }
6828    /* source must be wire */
6829    if (xp->optyp == LSB || xp->optyp == PARTSEL)
6830     np = xp->lu.x->lu.sy->el.enp;
6831    else np = xp->lu.sy->el.enp;
6832    if (np->ntyp >= NONWIRE_ST)
6833     {
6834      __sgferr(969,
6835       "%s source net %s (pos. %d) type %s illegal - must be wire type",
6836       gp->gmsym->synam, np->nsym->synam, i + 1, __to_wtnam(__xs, np));
6837      continue;
6838     }
6839    if (np->ntyp == N_TRIREG)
6840     {
6841      __sgfinform(443, "%s source on trireg wire %s (pos. %d)",
6842       gp->gmsym->synam, np->nsym->synam, i+ 1);
6843      continue;
6844     }
6845    if (np->ntyp == N_SUPPLY0 || np->ntyp == N_SUPPLY1 || np->ntyp == N_TRI0
6846     || np->ntyp == N_TRI1)
6847     {
6848      __sgfwarn(536, "%s source on %s wire %s (pos. %d) has no effect",
6849       gp->gmsym->synam, np->nsym->synam, __to_wtnam(__xs, np), i+ 1);
6850      continue;
6851     }
6852   }
6853 }
6854 
6855 /*
6856  * check a udp
6857  * notice nins here includes output state if non comb.
6858  */
chk_1udp(struct gate_t * gp)6859 static int32 chk_1udp(struct gate_t *gp)
6860 {
6861  struct udp_t *udpp;
6862 
6863  udpp = gp->gmsym->el.eudpp;
6864  udpp->u_used = TRUE;
6865  /* numins includes state that does not appear in udp instantiation */
6866  if (gp->gpnum - 1 != udpp->numins)
6867   {
6868    __sgferr(790, "udp %s has wrong number of terminals (%d) should be %d",
6869     gp->gmsym->synam, gp->gpnum, udpp->numins + 1);
6870    return(FALSE);
6871   }
6872  /* more checking */
6873  return(TRUE);
6874 }
6875 
6876 /*
6877  * check a gate output (source) driving terminal more than one
6878  */
chk_gate_source(struct gate_t * gp,struct expr_t * xp,int32 nd_lhs_chk,int32 nd_1bit,struct net_t ** ret_np)6879 static int32 chk_gate_source(struct gate_t *gp, struct expr_t *xp,
6880  int32 nd_lhs_chk, int32 nd_1bit, struct net_t **ret_np)
6881 {
6882  int32 rv;
6883  struct net_t *np;
6884  char s1[RECLEN];
6885 
6886  if (gp->g_class == GC_UDP) strcpy(s1, "udp"); else strcpy(s1, "gate");
6887  np = NULL;
6888  *ret_np = NULL;
6889  /* real driven by gate output caught also bit select from vectored wire */
6890  if (nd_lhs_chk)
6891   {
6892    rv = __chk_lhsexpr(xp, LHS_DECL);
6893    if (!rv) return(FALSE);
6894   }
6895  switch ((byte) xp->optyp) {
6896   case ID: case GLBREF:
6897    np = xp->lu.sy->el.enp;
6898    if (__get_netwide(np) > 1 && !nd_1bit)
6899     {
6900      __sgfwarn(538,
6901       "%s %s output %s wider than 1 bit - assuming select of low bit",
6902       gp->gmsym->synam, s1, __to_idnam(xp));
6903      /* cannot be vectored vector since implied select */
6904      __chk_lhsdecl_scalared(xp);
6905     }
6906    break;
6907   case OPEMPTY: break;
6908   case ISNUMBER:
6909    if (xp->is_real) goto is_real;
6910    /*FALLTHRU */
6911   case NUMBER:
6912    __sgfwarn(539,
6913     "%s %s output drives constant - made unconnected",
6914     gp->gmsym->synam, s1);
6915    return(FALSE);
6916   case REALNUM:
6917   case ISREALNUM:
6918 is_real:
6919    __sgferr(793,
6920     "%s %s output cannot connect to real number", gp->gmsym->synam, s1);
6921    return(FALSE);
6922   case LSB:
6923    np = xp->lu.x->lu.sy->el.enp;
6924    break;
6925   case PARTSEL:
6926    /* if part select, must change to bit select with warning */
6927    /* done after check psel called - needs normalized indices */
6928    if (!nd_1bit)
6929     {
6930      __sgfwarn(540, "%s %s output drives part select - assign to low bit",
6931       gp->gmsym->synam, s1);
6932     }
6933    np = xp->lu.x->lu.sy->el.enp;
6934    break;
6935   case LCB:
6936    __sgferr(794, "%s %s output terminal cannot be connected to concatenate",
6937     gp->gmsym->synam, s1);
6938    return(FALSE);
6939   default:
6940    __sgferr(795, "%s %s output expression %s illegal",
6941     gp->gmsym->synam, s1,  __msgexpr_tostr(__xs, xp));
6942    return(FALSE);
6943   }
6944  *ret_np = np;
6945  return(TRUE);
6946 }
6947 
6948 /*
6949  * check declarative type continuous assignments from one module
6950  * know cmsym NULL to get here
6951  *
6952  * this is point where 1 bit continuous assignments removed and added
6953  * as gates of type (token ASSIGN)
6954  *
6955  * quasi cont. assign checked in statement checking code
6956  */
chk_contas(void)6957 static void chk_contas(void)
6958 {
6959  register struct conta_t *cap;
6960  int32 lhs_gd, dnum, sav_ecnt, cwid, num_gd1bca, cai, num_cas;
6961  struct conta_t *last_cap, *cap2, *ca1bit_hd, *last_1bcap, *catab;
6962  struct expr_t *lhsx, *rhsx;
6963  struct paramlst_t *dhdr;
6964 
6965  last_cap = NULL;
6966  ca1bit_hd = NULL;
6967  last_1bcap = NULL;
6968  __expr_rhs_decl = TRUE;
6969  num_cas = 0;
6970  for (cap = __inst_mod->mcas, num_gd1bca = 0; cap != NULL;)
6971   {
6972    __sfnam_ind = cap->casym->syfnam_ind;
6973    __slin_cnt = cap->casym->sylin_cnt;
6974 
6975    num_cas++;
6976    /* error if cont. assign lhs not a wire */
6977    lhsx = cap->lhsx;
6978    rhsx = cap->rhsx;
6979 
6980    sav_ecnt = __pv_err_cnt;
6981    lhs_gd = __chk_lhsexpr(lhsx, LHS_DECL);
6982    /* index error still allow return of T from chk lhs expr */
6983    if (__pv_err_cnt > sav_ecnt) lhs_gd = FALSE;
6984 
6985    cwid = lhsx->szu.xclen;
6986    __chking_conta = TRUE;
6987    __rhs_isgetpat = FALSE;
6988    /* notice rhs here may be left as the $getpattern function call */
6989    __chk_rhsexpr(rhsx, cwid);
6990 
6991    if (rhsx->is_real || lhsx->is_real)
6992     __sgferr(796,
6993      "real expression illegal on either side of continuous assign");
6994    __chking_conta = FALSE;
6995    if (__rhs_isgetpat)
6996     {
6997      nd_1bit_concat(lhsx);
6998      if (cap->ca_du.pdels != NULL)
6999       __sgferr(797,
7000        "continuous assign with $getpattern on right cannot have delay");
7001      lhsx->getpatlhs = TRUE;
7002      __rhs_isgetpat = FALSE;
7003      goto nxt_ca;
7004     }
7005    if (cap->ca_du.pdels != NULL)
7006     {
7007      dhdr = __copy_dellst(cap->ca_du.pdels);
7008      if ((dnum = __chk_delparams(dhdr, "continuous assignment delay",
7009       FALSE)) == -1) cap->ca_du.pdels = NULL;
7010      else if (dnum > 3)
7011       {
7012        __sgferr(798, "continuous assign has more than 3 delays (%d)", dnum);
7013        cap->ca_du.pdels = NULL;
7014       }
7015      /* SJM 09/28/02 - anything but 1v need 4v table so conta del all bits */
7016      __free_dellst(dhdr);
7017     }
7018    /* must convert to 1 bit form if needed */
7019    if (lhs_gd && lhsx->szu.xclen == 1)
7020     {
7021      /* link out 1 bit ca onto tmp list */
7022      cap2 = cap->pbcau.canxt;
7023 
7024      num_gd1bca++;
7025      if (last_1bcap == NULL) ca1bit_hd = cap;
7026      else last_1bcap->pbcau.canxt = cap;
7027      cap->pbcau.canxt = NULL;
7028      last_1bcap = cap;
7029 
7030      if (last_cap == NULL) __inst_mod->mcas = cap2;
7031      else last_cap->pbcau.canxt = cap2;
7032      /* notice last_cap stays same when splicing out */
7033      cap = cap2;
7034      continue;
7035     }
7036 
7037 nxt_ca:
7038    /* only get here is lhs wider than 1 bit */
7039    if (cap->ca_hasst)
7040     {
7041      if ((cap->ca_stval & 7) == 0 || (cap->ca_stval & 0x38) == 0)
7042       __sgferr(1276,
7043        "wider than one bit vector continuous assign highz[01] strength unsupported");
7044     }
7045    last_cap = cap;
7046    cap = cap->pbcau.canxt;
7047   }
7048  __expr_rhs_decl = FALSE;
7049  /* next re-allocate 1bit cas on end of mgates array */
7050  /* since conta already checked can convert and not apply gaet checks */
7051  if (num_gd1bca > 0)
7052   {
7053    cnv_1bcas_into_garr(num_gd1bca, ca1bit_hd);
7054    num_cas -= num_gd1bca;
7055   }
7056 
7057  /* final step is to convert conta to array same as m nets conversion */
7058  /* from now on (same as with nets) - must index through array to traverse */
7059  /* contas */
7060  catab = NULL;
7061  __inst_mod->mcanum = num_cas;
7062  if (__inst_mod->mcanum != 0)
7063   {
7064    catab = (struct conta_t *)
7065     __my_malloc(__inst_mod->mcanum*sizeof(struct conta_t));
7066   }
7067  for (cai = 0, cap = __inst_mod->mcas; cai < __inst_mod->mcanum; cai++)
7068   {
7069    cap2 = cap->pbcau.canxt;
7070 
7071    catab[cai] = *cap;
7072    __my_free((char *) cap, sizeof(struct conta_t));
7073    catab[cai].pbcau.canxt = NULL;
7074 
7075    cap = cap2;
7076   }
7077  __inst_mod->mcas = catab;
7078 }
7079 
7080 /*
7081  * convert the separated out 1 bit cas to gates and free cas
7082  *
7083  * tricky step required to point all symbols for name back to gate which
7084  * may (probably will) be moved by re-alloc
7085  */
cnv_1bcas_into_garr(int32 n1bcas,struct conta_t * ca1bit_hd)7086 static void cnv_1bcas_into_garr(int32 n1bcas, struct conta_t *ca1bit_hd)
7087 {
7088  register int32 gi;
7089  struct conta_t *cap, *cap2;
7090  int32 osize, nsize;
7091  struct gate_t *gp;
7092  struct net_t *dum_np;
7093 
7094  dum_np = NULL;
7095  /* mark needed because must change back to conta for vpi_ */
7096  __inst_mod->mod_1bcas  = TRUE;
7097 
7098  /* reallocate mgates to add room at end */
7099  osize = __inst_mod->mgnum*sizeof(struct gate_t);
7100  nsize = osize + n1bcas*sizeof(struct gate_t);
7101  /* common for no gates in design - only 1 bit contas */
7102  /* know nsize at least one or will not get here */
7103  if (osize == 0) { gp = (struct gate_t *) __my_malloc(nsize); }
7104  else
7105   {
7106    gp = (struct gate_t *) __my_realloc((char *) __inst_mod->mgates,
7107     osize, nsize);
7108   }
7109  __inst_mod->mgates = gp;
7110  /* reset each el egp field */
7111  for (gi = 0; gi < __inst_mod->mgnum; gi++)
7112   {
7113    gp = &(__inst_mod->mgates[gi]);
7114    gp->gsym->el.egp = gp;
7115   }
7116 
7117  /* notice number is index of one after */
7118  gi = __inst_mod->mgnum;
7119  __inst_mod->mgnum += n1bcas;
7120  for (cap = ca1bit_hd; cap != NULL; gi++)
7121   {
7122    gp = &(__inst_mod->mgates[gi]);
7123    convert_1bca_togate(gp, cap);
7124 
7125    /* just move the conta built inst. */
7126    gp->gsym = cap->casym;
7127    gp->gsym->el.egp = gp;
7128    gp->gsym->sytyp = SYM_PRIM;
7129    if (!chk_gate_source(gp, gp->gpins[0], FALSE, FALSE, &dum_np))
7130     {
7131      __free_xtree(gp->gpins[0]);
7132      set_unc_gateterm(gp, 0);
7133     }
7134    /* free and link out conta */
7135    cap2 = cap->pbcau.canxt;
7136    /* ca scheduled event array not yet allocated */
7137    __my_free((char *) cap, sizeof(struct conta_t));
7138    cap = cap2;
7139   }
7140 }
7141 
7142 /*
7143  * convert a 1 bit continuous assign to a gate and link on end
7144  * of module's gate list - returns F if not converted
7145  *
7146  * this fills passed gate struct from within mgates
7147  * notice this can not return nil
7148  * other fields initialized later
7149  */
convert_1bca_togate(struct gate_t * gp,struct conta_t * cap)7150 static struct gate_t *convert_1bca_togate(struct gate_t *gp,
7151  struct conta_t *cap)
7152 {
7153  /* caller sets gsym */
7154  gp->gsym = NULL;
7155  gp->gmsym = __ca1bit_syp;
7156 
7157  gp->gpnum = 2;
7158  gp->g_hasst = cap->ca_hasst;
7159  gp->g_stval = cap->ca_stval;
7160  gp->g_delrep = cap->ca_delrep;
7161  /* assign delay union */
7162  gp->g_du = cap->ca_du;
7163  gp->schd_tevs = NULL;
7164  gp->g_class = GC_LOGIC;
7165  gp->g_pdst = FALSE;
7166  gp->g_unam = FALSE;
7167  gp->g_gone = FALSE;
7168  gp->gstate.wp = NULL;
7169  gp->gattrs = NULL;
7170 
7171  /* build the special output, temp form */
7172  gp->gpins = (struct expr_t **) __my_malloc(2*sizeof(struct expr_t *));
7173  gp->gpins[0] = cap->lhsx;
7174  gp->gpins[1] = cap->rhsx;
7175  /* caller must free and unlink continuous assign */
7176  return(gp);
7177 }
7178 
7179 /*
7180  * for get pattern continuous assigment must be scalar wire or concat of
7181  * scalar wires (lhs of conta assign non wire already caught)
7182  */
nd_1bit_concat(struct expr_t * lhsx)7183 static void nd_1bit_concat(struct expr_t *lhsx)
7184 {
7185  register struct expr_t *catndp;
7186 
7187  if (lhsx->optyp == LCB)
7188   {
7189    for (catndp = lhsx->ru.x; catndp != NULL; catndp = catndp->ru.x)
7190     chk_getpat_nonscal(catndp->lu.x);
7191    return;
7192   }
7193  __sgferr(800,
7194   "$getpattern continous assign lvalue must be concatenate of scalar wires");
7195 }
7196 
7197 /*
7198  * error if non scalar net
7199  * know this is wire
7200  */
chk_getpat_nonscal(struct expr_t * lhsx)7201 static void chk_getpat_nonscal(struct expr_t *lhsx)
7202 {
7203  struct net_t *np;
7204 
7205  if (lhsx->optyp == GLBREF)
7206   {
7207    __sgferr(801,
7208     "$getpattern assign lvalue hierarchical path reference %s illegal",
7209     __to_idnam(lhsx));
7210    return;
7211   }
7212  if (lhsx->optyp != ID)
7213   {
7214    __sgferr(802, "$getpattern assign lvalue element %s not a simple wire",
7215      __msgexpr_tostr(__xs, lhsx));
7216    return;
7217   }
7218  np = lhsx->lu.sy->el.enp;
7219  if (np->n_isavec)
7220   __sgferr(966,
7221    "$getpattern continous assign lvalue element %s not a scalar",
7222    __to_idnam(lhsx));
7223  if (np->n_stren)
7224   __sgferr(967,
7225    "$getpattern continous assign lvalue element %s has strength",
7226    __to_idnam(lhsx));
7227 }
7228 
7229 /*
7230  * check a user function definition
7231  * this must undeclare if error because cannot check call
7232  * know function defined at top level of __inst_mod
7233  */
chk_funcdef(struct task_t * tskp)7234 static void chk_funcdef(struct task_t *tskp)
7235 {
7236  int32 saverr_cnt;
7237 
7238  __cur_tsk = tskp;
7239  saverr_cnt = __pv_err_cnt;
7240  /* check definition args */
7241  chk_fdef_args(tskp);
7242 
7243  /* SJM 09/28/01 - see if func call other non sys func */
7244  __func_has_fcall = FALSE;
7245 
7246  /* first check all statements normally */
7247  __chk_lstofsts(tskp->tskst);
7248  if (__func_has_fcall) tskp->fhas_fcall = TRUE;
7249 
7250  /* check all sub statements for illegal delay controls */
7251  /* also sets name_assigned_to if name somewhere on assign lhs */
7252  __task_has_delay = FALSE;
7253  __task_has_tskcall = FALSE;
7254  __name_assigned_to = FALSE;
7255  __locfnamsyp = tskp->tskpins->tpsy;
7256  __nbsti = -1;
7257  __checking_only = FALSE;
7258  __chk_nodel_lstofsts(tskp->tskst);
7259  __checking_only = TRUE;
7260  if (!__name_assigned_to)
7261   __gfwarn(647, tskp->tsksyp->syfnam_ind, tskp->tsksyp->sylin_cnt,
7262    "no assignment to function name %s in body", tskp->tsksyp->synam);
7263  /* must leave name assigned to off, unless checking func. def body */
7264  else __name_assigned_to = FALSE;
7265  if (__pv_err_cnt != saverr_cnt) tskp->tsksyp->sydecl = FALSE;
7266  __cur_tsk = NULL;
7267 }
7268 
7269 /*
7270  * check a function def arguments
7271  * all ports inputs and 1 required
7272  */
chk_fdef_args(struct task_t * tskp)7273 static void chk_fdef_args(struct task_t *tskp)
7274 {
7275  register struct task_pin_t *tpp;
7276  int32 ai;
7277  struct sy_t *syp;
7278  struct net_t *np;
7279  char s1[RECLEN];
7280 
7281  /* function definition return value missing */
7282  if ((tpp = tskp->tskpins) == NULL)
7283   __misc_gfterr(__FILE__, __LINE__, tskp->tsksyp->syfnam_ind,
7284    tskp->tsksyp->sylin_cnt);
7285  if (tpp->tpsy->sytyp != SYM_N) __arg_terr(__FILE__, __LINE__);
7286  /* assign err replaces unused err, this rhs of func. return value assign */
7287  np = tpp->tpsy->el.enp;
7288  /* notice not set n_onprocrhs since only needed for wires */
7289  if (np->nrngrep == NX_CT) np->nu.ct->n_onrhs = TRUE;
7290 
7291  if ((tpp = tpp->tpnxt) == NULL)
7292   {
7293    __gferr(867, tskp->tsksyp->syfnam_ind, tskp->tsksyp->sylin_cnt,
7294     "function %s definition requires at least one input argument",
7295     tskp->tsksyp->synam);
7296    return;
7297   }
7298  for (ai = 1; tpp != NULL; tpp = tpp->tpnxt, ai++)
7299   {
7300    if (tpp->trtyp != IO_IN)
7301     {
7302      syp = tpp->tpsy;
7303      __gferr(868, syp->syfnam_ind, syp->sylin_cnt,
7304       "function %s argument %s illegal - must be input",
7305       __to_ptnam(s1, tpp->trtyp), syp->synam);
7306     }
7307    if (tpp->tpsy->sytyp != SYM_N) __arg_terr(__FILE__, __LINE__);
7308    np = tpp->tpsy->el.enp;
7309    if (np->nrngrep == NX_CT) np->nu.ct->n_onlhs = TRUE;
7310    /* SJM 01/14/1999 - arrays illegal formal function arguments */
7311    if (np->n_isarr)
7312     {
7313      syp = tpp->tpsy;
7314      __gferr(869, syp->syfnam_ind, syp->sylin_cnt,
7315       "function %s definition entire array formal argument %s (pos. %d) illegal - must be simple variable",
7316       tskp->tsksyp->synam, syp->synam, ai);
7317     }
7318   }
7319 }
7320 
7321 /*
7322  * check func. def. and task statement list
7323  * if func. def. and delay error, else just set flag for optimization
7324  */
__chk_nodel_lstofsts(struct st_t * fhdstp)7325 extern void __chk_nodel_lstofsts(struct st_t *fhdstp)
7326 {
7327  register struct st_t *stp;
7328 
7329  /* then check for illegal in func def. statements */
7330  for (stp = fhdstp; stp != NULL; stp = stp->stnxt) chk_nodel_stmt(stp);
7331 }
7332 
7333 /*
7334  * check task body statement list for time movement constructs
7335  * for functions emits errors, for rest sets flags
7336  * for every named block sets time movement task bits for optimization
7337  *
7338  * think could allow distant disables and causes and still could optimize
7339  * but for now using function rules
7340  * assumes normal statement checking already finished
7341  * notice always called after statement checking so disables fixed up
7342  */
chk_nodel_stmt(struct st_t * stp)7343 static void chk_nodel_stmt(struct st_t *stp)
7344 {
7345  char s1[RECLEN];
7346 
7347  switch ((byte) stp->stmttyp) {
7348   case S_NULL: case S_STNONE: break;
7349   /* legal statements */
7350   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA:
7351    /* notice for rhs delay control - wrong delay control caught at dctrl */
7352    if (!__checking_only || !__name_assigned_to)
7353     {
7354      if (lhsexpr_hassym(stp->st.spra.lhsx, __locfnamsyp))
7355       __name_assigned_to = TRUE;
7356     }
7357    break;
7358   /* these do not count as assignment to name */
7359   case S_QCONTA: case S_QCONTDEA:
7360    break;
7361   case S_IF:
7362    __chk_nodel_lstofsts(stp->st.sif.thenst);
7363    if (stp->st.sif.elsest != NULL) __chk_nodel_lstofsts(stp->st.sif.elsest);
7364    break;
7365   case S_CASE:
7366    {
7367     register struct csitem_t *csip;
7368     struct csitem_t *dflt_csip;
7369 
7370     /* first always default or place holder for default in no st */
7371     dflt_csip = stp->st.scs.csitems;
7372     for (csip = dflt_csip->csinxt; csip != NULL; csip = csip->csinxt)
7373      {
7374       __chk_nodel_lstofsts(csip->csist);
7375      }
7376     if (dflt_csip->csist != NULL) __chk_nodel_lstofsts(dflt_csip->csist);
7377    }
7378    break;
7379   case S_FOREVER:
7380   case S_WHILE:
7381    __chk_nodel_lstofsts(stp->st.swh.lpst);
7382    break;
7383   case S_REPEAT:
7384    __chk_nodel_lstofsts(stp->st.srpt.repst);
7385    break;
7386   case S_FOR:
7387    {
7388     struct for_t *frs;
7389 
7390     frs = stp->st.sfor;
7391     chk_nodel_stmt(frs->forassgn);
7392     chk_nodel_stmt(frs->forinc);
7393     __chk_nodel_lstofsts(frs->forbody);
7394    }
7395    break;
7396   /* illegal statements */
7397   case S_TSKCALL:
7398    {
7399     struct expr_t *tkxp;
7400 
7401     tkxp = stp->st.stkc.tsksyx;
7402     /* $stop system tasks requires iact schedule */
7403     if (strcmp(tkxp->lu.sy->synam, "$stop") == 0) __iact_must_sched = TRUE;
7404 
7405     if ((tkxp->optyp == ID || tkxp->optyp == GLBREF)
7406      && *(tkxp->lu.sy->synam) != '$')
7407      {
7408       if (__checking_only) __task_has_tskcall = TRUE;
7409       else
7410        {
7411         __gferr(870, stp->stfnam_ind, stp->stlin_cnt,
7412          "user task %s enable illegal in function body", __to_idnam(tkxp));
7413        }
7414      }
7415    }
7416    break;
7417   /* for these check sub statement even though must have delay */
7418   case S_DELCTRL:
7419    if (stp->st.sdc->actionst != NULL)
7420     __chk_nodel_lstofsts(stp->st.sdc->actionst);
7421    goto bad_fdstmt;
7422   case S_WAIT:
7423    __chk_nodel_lstofsts(stp->st.swait.lpst);
7424    goto bad_fdstmt;
7425   case S_UNFJ:
7426    {
7427     int32 fji;
7428     struct st_t *fjstp;
7429     int32 sav_has_tskcall, has_timemove;
7430 
7431     has_timemove = FALSE;
7432     sav_has_tskcall = __task_has_tskcall;
7433     __task_has_delay = TRUE;
7434     __task_has_tskcall = FALSE;
7435     for (fji = 0;; fji++)
7436      {
7437       if ((fjstp = stp->st.fj.fjstps[fji]) == NULL) break;
7438       __chk_nodel_lstofsts(fjstp);
7439       if (__task_has_delay || __task_has_tskcall) has_timemove = TRUE;
7440      }
7441     if (!has_timemove)
7442      {
7443       __gfwarn(606, stp->stfnam_ind, stp->stlin_cnt,
7444         "unnamed fork-join components probably have no time movement");
7445      }
7446     if (!__task_has_tskcall) __task_has_tskcall = sav_has_tskcall;
7447     /* always has time fork-join always has time move since needs threads */
7448    }
7449    goto bad_fdstmt;
7450   /* non blocking procedural assign implies time movement so can not */
7451   /* be in function that is execed outside of time */
7452   case S_NBPROCA:
7453   /* these are simple delay statements */
7454   case S_CAUSE:
7455 bad_fdstmt:
7456    if (__checking_only) __task_has_delay = TRUE;
7457    else
7458     {
7459      __gferr(870, stp->stfnam_ind, stp->stlin_cnt,
7460       "%s illegal in function body", __to_sttyp(s1, stp->stmttyp));
7461     }
7462    break;
7463   /* possibly illegal statements */
7464   case S_NAMBLK:
7465    /* legal except for fork */
7466    {
7467     struct task_t *nbtskp;
7468     int32 sav_has_delay, sav_has_tskcall;
7469 
7470     sav_has_delay = __task_has_delay;
7471     sav_has_tskcall = __task_has_tskcall;
7472     __task_has_delay = FALSE;
7473     __task_has_tskcall = FALSE;
7474     nbtskp = stp->st.snbtsk;
7475     __push_nbstk(stp);
7476     if (nbtskp->tsktyp == FORK)
7477      {
7478       int32 fji;
7479       int32 has_timemove;
7480       struct st_t *stp2;
7481       struct st_t *fjstp;
7482 
7483       stp2 = nbtskp->tskst;
7484       has_timemove = FALSE;
7485       /* named fork-join is task with 1 UNFJ statement */
7486       for (fji = 0;; fji++)
7487        {
7488         if ((fjstp = stp2->st.fj.fjstps[fji]) == NULL) break;
7489         __chk_nodel_lstofsts(fjstp);
7490         if (__task_has_delay || __task_has_tskcall) has_timemove = TRUE;
7491        }
7492       if (!has_timemove)
7493        {
7494         __gfwarn(606, stp->stfnam_ind, stp->stlin_cnt,
7495          "named fork-join components probably have no time movement");
7496        }
7497       if (!__task_has_tskcall) __task_has_tskcall = sav_has_tskcall;
7498       goto bad_fdstmt;
7499      }
7500     __chk_nodel_lstofsts(nbtskp->tskst);
7501     if (!__task_has_delay) __task_has_delay = sav_has_delay;
7502     if (__task_has_tskcall) nbtskp->thas_tskcall = TRUE;
7503     else __task_has_tskcall = sav_has_tskcall;
7504     __pop_nbstk();
7505    }
7506    break;
7507   case S_UNBLK:
7508    /* must check statements below */
7509    {
7510     register struct st_t *stp2;
7511 
7512     for (stp2 = stp->st.sbsts; stp2 != NULL; stp2 = stp2->stnxt)
7513      chk_nodel_stmt(stp2);
7514    }
7515    break;
7516   case S_DSABLE:
7517    /* this may or may not be a delay */
7518    chk_nodel_dsable(stp);
7519    break;
7520   default: __case_terr(__FILE__, __LINE__);
7521  }
7522 }
7523 
7524 /*
7525  * check a function definition (body) disable
7526  * think possibly here, can still optimize and avoid thread for tasks even
7527  * if they disable other tasks - but for now forcing thread.
7528  */
chk_nodel_dsable(struct st_t * stp)7529 static void chk_nodel_dsable(struct st_t *stp)
7530 {
7531  struct expr_t *dsxp;
7532  struct sy_t *syp;
7533  int32 dummy;
7534 
7535  /* task disable illegal - named block ok if above in func. body */
7536  dsxp = stp->st.sdsable.dsablx;
7537  /* assume above */
7538  syp = dsxp->lu.sy;
7539  if (syp->sytyp == SYM_TSK)
7540   {
7541    if (__checking_only)
7542     {
7543      /* if disabling current task still above */
7544      if (syp->el.etskp != __cur_tsk) goto set_has_del;
7545      return;
7546     }
7547    __gferr(873, stp->stfnam_ind, stp->stlin_cnt,
7548     "task %s disable illegal in function body", __to_idnam(dsxp));
7549    return;
7550   }
7551  /* cannot disable anything outside of function also - qualified name */
7552  /* ok if within function */
7553  /* cannot disable anything not upward for function */
7554  if (dsxp->optyp == GLBREF)
7555   {
7556    if (__checking_only) goto set_has_del;
7557    __gferr(874, stp->stfnam_ind, stp->stlin_cnt,
7558     "disable of cross module reference %s illegal in function",
7559     __to_idnam(dsxp));
7560    return;
7561   }
7562  /* if called from func., ok to disable function name */
7563  if (syp->sytyp == SYM_F)
7564   {
7565    if (syp->el.etskp != __cur_tsk)
7566     {
7567      if (__checking_only) goto set_has_del;
7568 
7569      __gferr(866, stp->stfnam_ind, stp->stlin_cnt,
7570       "disable of function %s illegal inside other function %s",
7571       __to_idnam(dsxp), __cur_tsk->tsksyp->synam);
7572     }
7573    return;
7574   }
7575  /* OK to disable function from within body */
7576  if (__nbsti >= 0 && __is_upward_dsable_syp(syp,
7577   __nbstk[__nbsti]->st.snbtsk->tsksymtab, &dummy)) return;
7578  if (__checking_only) goto set_has_del;
7579 
7580  __gferr(875, stp->stfnam_ind, stp->stlin_cnt,
7581   "disable of non enclosing named block %s inside function %s illegal",
7582   __msgexpr_tostr(__xs, dsxp), __locfnamsyp->synam);
7583  return;
7584 
7585 set_has_del:
7586  __task_has_delay = TRUE;
7587 }
7588 
7589 /*
7590  * return T if lhs expression contains lhs symbol
7591  */
lhsexpr_hassym(struct expr_t * ndp,struct sy_t * syp)7592 static int32 lhsexpr_hassym(struct expr_t *ndp, struct sy_t *syp)
7593 {
7594  register struct expr_t *ndp2;
7595 
7596  switch ((byte) ndp->optyp) {
7597    case ID:
7598     if (ndp->lu.sy == syp) return(TRUE);
7599     break;
7600    case GLBREF: case NUMBER: case REALNUM: break;
7601    case LSB: case PARTSEL:
7602     if (ndp->lu.x->lu.sy == syp) return(TRUE);
7603     break;
7604    case LCB:
7605     /* know only 1 level of lhs concatenates (at least by here) */
7606     for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
7607      {
7608       /* widths get set after checking */
7609       if (ndp2->lu.x->lu.sy == syp) return(TRUE);
7610      }
7611     break;
7612    default: __case_terr(__FILE__, __LINE__);
7613   }
7614  return(FALSE);
7615 }
7616 
7617 /*
7618  * RANGE MANIPULATION ROUTINES
7619  */
7620 
7621 /*
7622  * get width of net - cannot be called unless n_isavec is TRUE
7623  * used when know vector width needed even if array
7624  *
7625  * notice always know range is no inst. specific - if defparam in
7626  * in range assigned to must really split.
7627  */
__get_netwide(struct net_t * np)7628 extern int32 __get_netwide(struct net_t *np)
7629 {
7630  register int32 i1, i2;
7631  int32 wid;
7632 
7633  if (!np->n_isavec) return(1);
7634 
7635  i1 = i2 = 0;
7636  if (np->nrngrep == NX_CT)
7637   {
7638    i1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
7639    i2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
7640 
7641    if (i1 == -1 || i2 == -2) __arg_terr(__FILE__, __LINE__);
7642    wid = (i1 >= i2) ? (i1 - i2 + 1) : (i2 - i1 + 1);
7643    return(wid);
7644   }
7645  return(np->nwid);
7646 }
7647 
7648 /*
7649  * get array width (i.e. width of range or number of elements in memory)
7650  */
__get_arrwide(struct net_t * np)7651 extern int32 __get_arrwide(struct net_t *np)
7652 {
7653  register int32 w1, w2;
7654 
7655  w1 = w2 = 0;
7656  switch ((byte) np->nrngrep) {
7657   case NX_CT:
7658    w1 = (int32) __contab[np->nu.ct->ax1->ru.xvi];
7659    w2 = (int32) __contab[np->nu.ct->ax2->ru.xvi];
7660    break;
7661   case NX_ARR:
7662    w1 = np->nu.rngarr->ai1;
7663    w2 = np->nu.rngarr->ai2;
7664    break;
7665   default: __case_terr(__FILE__, __LINE__);
7666  }
7667  return((w1 >= w2) ? (w1 - w2 + 1) : (w2 - w1 + 1));
7668 }
7669 
7670 /*
7671  * get vector range extremes independent of representation
7672  * (for both compile and run times)
7673  * this can only be called for known vector not scalar
7674  *
7675  * returns false if cannot determine range (unfolded still)
7676  * this will return vector width of array
7677  * must use bit to determine if vector or not
7678  */
__getwir_range(struct net_t * np,int32 * xr1,int32 * xr2)7679 extern void __getwir_range(struct net_t *np, int32 *xr1, int32 *xr2)
7680 {
7681  register int32 r1, r2;
7682 
7683  r1 = r2 = 0;
7684  switch ((byte) np->nrngrep) {
7685   case NX_CT:
7686    r1 = (int32) __contab[np->nu.ct->nx1->ru.xvi];
7687    r2 = (int32) __contab[np->nu.ct->nx2->ru.xvi];
7688    break;
7689   case NX_ARR: r1 = np->nu.rngarr->ni1; r2 = np->nu.rngarr->ni2; break;
7690   case NX_DWIR: r1 = np->nu.rngdwir->ni1; r2 = np->nu.rngdwir->ni2; break;
7691   case NX_WIR: r1 = np->nu.rngwir->ni1; r2 = np->nu.rngwir->ni2; break;
7692   default: __case_terr(__FILE__, __LINE__);
7693  }
7694  *xr1 = r1;
7695  *xr2 = r2;
7696 }
7697 
7698 /*
7699  * run time get array range extremes independent of representation
7700  * must use bit to determine if array or not
7701  *
7702  * returns false if cannot determine range (unfolded still)
7703  * this will return array width of array
7704  */
__getarr_range(struct net_t * np,int32 * mr1,int32 * mr2,int32 * arrwid)7705 extern void __getarr_range(struct net_t *np, int32 *mr1, int32 *mr2, int32 *arrwid)
7706 {
7707  register int32 r1, r2;
7708 
7709  r1 = r2 = 0;
7710  /* notice fall thru on things with no array range */
7711  switch ((byte) np->nrngrep) {
7712   case NX_CT:
7713    if (np->n_isarr)
7714     {
7715      r1 = (int32) __contab[np->nu.ct->ax1->ru.xvi];
7716      r2 = (int32) __contab[np->nu.ct->ax2->ru.xvi];
7717     }
7718    break;
7719   case NX_ARR: r1 = np->nu.rngarr->ai1; r2 = np->nu.rngarr->ai2; break;
7720   default: __case_terr(__FILE__, __LINE__);
7721  }
7722  *arrwid = (r1 > r2) ? r1 - r2 + 1 : r2 - r1 + 1;
7723  *mr1 = r1;
7724  *mr2 = r2;
7725 }
7726 
7727 /*
7728  * routine to map normalized h:0 form index back to input value
7729  * know indi in range and wire type determines if array or wire select
7730  */
__unnormalize_ndx(struct net_t * np,int32 indi)7731 extern int32 __unnormalize_ndx(struct net_t *np, int32 indi)
7732 {
7733  int32 r1, r2, obwid;
7734 
7735  if (np->n_isarr) __getarr_range(np, &r1, &r2, &obwid);
7736  else if (np->n_isavec) __getwir_range(np, &r1, &r2);
7737  else return(indi);
7738  if (r1 >= r2) return(r2 + indi); else return(r2 - indi);
7739 }
7740 
7741 /*
7742  * map normalized h:0 constant index to value in source world
7743  * already processed to word32 and know in range
7744  *
7745  * just like C implied truncating assign to 32 bit value
7746  * constants are already normalized during compilation
7747  */
__unmap_ndx(int32 biti,int32 ri1,int32 ri2)7748 extern int32 __unmap_ndx(int32 biti, int32 ri1, int32 ri2)
7749 {
7750  if (ri1 >= ri2) { if (ri1 != 0) biti -= ri2; }
7751  else { if (ri2 != 0) biti = ri2 - biti; }
7752  return(biti);
7753 }
7754 
7755 /*
7756  * VARIABLE INITIALIZE ASSIGNMENT CHECKING ROUTINES
7757  */
7758 
7759 /*
7760  * check a module's var init rhs exprs
7761  */
chk_varinits(void)7762 static void chk_varinits(void)
7763 {
7764  register struct varinitlst_t *initp;
7765 
7766  initp = __inst_mod->mvarinits;
7767  for (; initp != NULL; initp = initp->varinitnxt)
7768   {
7769    __sfnam_ind = initp->init_syp->syfnam_ind;
7770    __slin_cnt = initp->init_syp->sylin_cnt;
7771 
7772    if (!__chk_paramexpr(initp->init_xp, initp->init_syp->el.enp->nwid))
7773     {
7774      __sgferr(3431,
7775       "variable assign to %s initializing expression %s illegal - numbers and parameters only",
7776       initp->init_syp->synam, __msgexpr_tostr(__xs, initp->init_xp));
7777 
7778      /* need to still add value of x to prevent further errors */
7779      __free2_xtree(initp->init_xp);
7780      /* SJM 09/30/04 - LOOKATME - maybe needs to be right width x's */
7781      initp->init_xp->szu.xclen = 1;
7782      __set_numval(initp->init_xp, ALL1W, ALL1W, 1);
7783     }
7784   }
7785 }
7786 
7787 /*
7788  * STATEMENT CHECKING ROUTINES
7789  */
7790 
7791 
7792 /*
7793  * routines to check fix up statements
7794  */
chk_stmts(void)7795 static void chk_stmts(void)
7796 {
7797  register struct ialst_t *ialp;
7798 
7799  for (ialp = __inst_mod->ialst; ialp != NULL; ialp = ialp->ialnxt)
7800   {
7801    __cur_tsk = NULL;
7802    __chk_lstofsts(ialp->iastp);
7803    /* also check no del statement lists to set various task/block bits */
7804    __task_has_delay = FALSE;
7805    __task_has_tskcall = FALSE;
7806    __nbsti = -1;
7807    __chk_nodel_lstofsts(ialp->iastp);
7808   }
7809 }
7810 
7811 /*
7812  * check a statement list
7813  */
__chk_lstofsts(struct st_t * hdstp)7814 extern void __chk_lstofsts(struct st_t *hdstp)
7815 {
7816  register struct st_t *stp;
7817 
7818  /* notice legal empty statement list just does nothing here */
7819  for (stp = hdstp; stp != NULL; stp = stp->stnxt) chk_1stmt(stp);
7820 }
7821 
7822 /*
7823  * check 1 statement
7824  */
chk_1stmt(struct st_t * stp)7825 static void chk_1stmt(struct st_t *stp)
7826 {
7827  int32 save_lno, save_fni, cwid, is_regform;
7828 
7829  /* save callers values */
7830  save_fni = __sfnam_ind;
7831  save_lno = __slin_cnt;
7832  __sfnam_ind = stp->stfnam_ind;
7833  __slin_cnt = stp->stlin_cnt;
7834 
7835  switch ((byte) stp->stmttyp) {
7836   case S_NULL: case S_STNONE: break;
7837   /* if delay prefix action part of delay control */
7838   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA: case S_NBPROCA:
7839    __chk_lhsexpr(stp->st.spra.lhsx, LHS_PROC);
7840    if (stp->st.spra.lhsx->optyp == LCB && stp->st.spra.lhsx->szu.xclen == 1)
7841     __sgfwarn(542, "procedural assign lvalue 1 bit concatenate unusual");
7842    cwid = stp->st.spra.lhsx->szu.xclen;
7843    __chk_rhsexpr(stp->st.spra.rhsx, cwid);
7844 
7845    /* SJM 10/08/04 - for Ver 2001 because WBITS can be 64 - must widen */
7846    /* unsized constant (unsiznum bit in expr rec on) to lhs width */
7847    if (stp->st.spra.rhsx->optyp == NUMBER && stp->st.spra.rhsx->unsiznum
7848     && stp->st.spra.rhsx->szu.xclen < stp->st.spra.lhsx->szu.xclen)
7849     {
7850      stp->st.spra.rhsx = __widen_unsiz_rhs_assign(stp->st.spra.rhsx,
7851       stp->st.spra.lhsx->szu.xclen);
7852     }
7853    break;
7854   case S_IF:
7855    __chk_rhsexpr(stp->st.sif.condx, 0);
7856    __chk_lstofsts(stp->st.sif.thenst);
7857    if (stp->st.sif.elsest != NULL) __chk_lstofsts(stp->st.sif.elsest);
7858    break;
7859   case S_CASE:
7860    chk_case(stp);
7861    break;
7862   case S_WAIT:
7863    /* notice this is level sensitive condition cannot be event expr */
7864    /* DBG remove -- */
7865    if (stp->st.swait.lpx == NULL) __misc_terr(__FILE__, __LINE__);
7866    /* --- */
7867    __chk_rhsexpr(stp->st.swait.lpx, 0);
7868    if (__isleaf(stp->st.swait.lpx) && stp->st.swait.lpx->optyp != ID
7869     && stp->st.swait.lpx->optyp != GLBREF)
7870     __sgfinform(413, "wait expression constant - use loop");
7871 
7872    __chk_lstofsts(stp->st.swait.lpst);
7873    break;
7874   case S_FOREVER:
7875    __chk_lstofsts(stp->st.swh.lpst);
7876    break;
7877   case S_REPEAT:
7878    if (stp->st.srpt.repx != NULL)
7879     {
7880      __chk_rhsexpr(stp->st.srpt.repx, 0);
7881      if (stp->st.srpt.repx->szu.xclen > WBITS)
7882       __sgfwarn(543,
7883        "truncation of repeat count from %d to 32 bits - high bits ignored",
7884        stp->st.srpt.repx->szu.xclen);
7885     }
7886    else __sgferr(803, "required repeat statement repeat count missing");
7887    __chk_lstofsts(stp->st.srpt.repst);
7888    break;
7889   case S_WHILE:
7890    if (stp->st.swh.lpx != NULL)
7891     {
7892      __chk_rhsexpr(stp->st.swh.lpx, 0);
7893      /* SJM 04/05/02 - this warning is wrong - while not truncated - REMOVED */
7894      /* ---
7895      if (stp->st.swh.lpx->szu.xclen > WBITS)
7896       __sgfwarn(544,
7897        "truncation of while expression from %d to 32 bits - high bits ignored",
7898        stp->st.swh.lpx->szu.xclen);
7899      --- */
7900     }
7901    else __sgferr(804, "while statement required while expression missing");
7902    __chk_lstofsts(stp->st.swh.lpst);
7903    break;
7904   case S_FOR:
7905    {
7906     struct for_t *frs;
7907 
7908     /* notice for statement must use temporaries of right width */
7909     frs = stp->st.sfor;
7910     chk_1stmt(frs->forassgn);
7911     if (frs->fortermx != NULL) __chk_rhsexpr(frs->fortermx, 0);
7912     chk_1stmt(frs->forinc);
7913     __chk_lstofsts(frs->forbody);
7914    }
7915    break;
7916   case S_DELCTRL:
7917    chk_dctrl(stp->st.sdc);
7918    break;
7919   case S_NAMBLK:
7920    __chk_lstofsts(stp->st.snbtsk->tskst);
7921    break;
7922   case S_UNBLK:
7923    __chk_lstofsts(stp->st.sbsts);
7924    break;
7925   case S_UNFJ:
7926    {
7927     register int32 fji;
7928     struct st_t *fjstp;
7929 
7930     /* 1 sub stmt only, for unnamed begin-end will be unnamed block */
7931     for (fji = 0;; fji++)
7932      {
7933       if ((fjstp = stp->st.fj.fjstps[fji]) == NULL) break;
7934       /* SJM 09/24/01 - this can be 2 stmts for for (for assgn then for) */
7935       __chk_lstofsts(fjstp);
7936      }
7937    }
7938    break;
7939   case S_TSKCALL:
7940    __chk_tskenable(stp);
7941    break;
7942   case S_QCONTA:
7943    /* quasi-continuous assign is either proc. assign or force */
7944    chk_qclvalue(stp->st.sqca->qclhsx, stp->st.sqca->qcatyp, &is_regform);
7945    __set_lhswidth(stp->st.sqca->qclhsx);
7946    cwid = stp->st.sqca->qclhsx->szu.xclen;
7947    __chk_rhsexpr(stp->st.sqca->qcrhsx, cwid);
7948    stp->st.sqca->regform = is_regform;
7949 
7950    /* SJM 10/08/04 - for Ver 2001 because WBITS can be 64 - must widen */
7951    /* unsized constant (unsiznum bit in expr rec on) to lhs width */
7952    if (stp->st.sqca->qcrhsx->optyp == NUMBER
7953     && stp->st.sqca->qcrhsx->unsiznum
7954     && stp->st.sqca->qcrhsx->szu.xclen < stp->st.sqca->qclhsx->szu.xclen)
7955     {
7956      stp->st.sqca->qcrhsx = __widen_unsiz_rhs_assign(stp->st.sqca->qcrhsx,
7957       stp->st.sqca->qclhsx->szu.xclen);
7958     }
7959 
7960    /* SJM 07/16/03 - illegal if rhs expr. contains lhs being forced lvalue */
7961    chk_circular_qc_stmt(stp);
7962    break;
7963   case S_QCONTDEA:
7964    /* quasi-continuous deassign is either proc. deassign or release */
7965    chk_qclvalue(stp->st.sqcdea.qcdalhs, stp->st.sqcdea.qcdatyp, &is_regform);
7966    __set_lhswidth(stp->st.sqcdea.qcdalhs);
7967    stp->st.sqcdea.regform = is_regform;
7968    break;
7969   case S_DSABLE:
7970    chk_disable(stp);
7971    break;
7972   case S_CAUSE:
7973    {
7974     struct expr_t *ndp;
7975     struct sy_t *syp;
7976     struct net_t *np;
7977 
7978     ndp = stp->st.scausx;
7979     if (ndp->optyp != GLBREF && ndp->optyp != ID)
7980      {
7981       __sgferr(806, "cause argument %s must be simple event name",
7982        __msgexpr_tostr(__xs, ndp));
7983       break;
7984      }
7985     syp = ndp->lu.sy;
7986     if (syp->sytyp == SYM_N) np = syp->el.enp; else np = NULL;
7987     if (syp->sytyp != SYM_N || np->ntyp != N_EVENT)
7988      {
7989       if (np == NULL) __to_sytyp(__xs, syp->sytyp);
7990       else __to_wtnam(__xs, np);
7991       __sgferr(807,
7992        "cause right hand side symbol \"%s\" type %s is not an event",
7993        __to_idnam(ndp), __xs);
7994      }
7995     /* cause is lhs assign for event */
7996     if (np->nrngrep == NX_CT) np->nu.ct->n_onlhs = TRUE;
7997    }
7998    break;
7999    default: __case_terr(__FILE__, __LINE__);
8000   }
8001  /* restore callers values */
8002  __sfnam_ind = save_fni;
8003  __slin_cnt = save_lno;
8004 }
8005 
8006 /*
8007  * routine to widen unsized number to lhs context
8008  *
8009  * know only called for literal numbers - maybe literal from folding
8010  * and think folded bit will be on for all but fcalls but not using
8011  *
8012  * this is special widen with x/z extend in addition to sign extend
8013  * but if word32, does not extend the high 1
8014  *
8015  * needed from Ver 2001 change because WBITS can now be 64 so for
8016  * any of the assigns (proc, cont, func/task input and force/assign)
8017  * need to use lhs context to widen unsized number to that size
8018  * with sign and x/z extend
8019  */
__widen_unsiz_rhs_assign(struct expr_t * rhsx,int32 lhswid)8020 extern struct expr_t *__widen_unsiz_rhs_assign(struct expr_t *rhsx,
8021  int32 lhswid)
8022 {
8023  int32 owlen, bi;
8024  word32 *owp;
8025  struct xstk_t *xsp;
8026 
8027  owlen = wlen_(rhsx->szu.xclen);
8028  push_xstk_(xsp, rhsx->szu.xclen);
8029  owp = &(__contab[rhsx->ru.xvi]);
8030  memcpy(xsp->ap, owp, 2*owlen*WRDBYTES);
8031 
8032  /* notice not lhs signed because signed does not corss = */
8033  if (rhsx->has_sign) __sgn_xtnd_widen(xsp, lhswid);
8034  else
8035   {
8036    /* if x/z - b part high bit on, then widen both a and b parts */
8037    bi = get_bofs_(rhsx->szu.xclen - 1);
8038    if ((xsp->bp[owlen - 1] & (1 << bi)) != 0)
8039     {
8040      /* notice since x/z bit on - can treat as sign extend widen since */
8041      /* reduces to x/z widen case */
8042      __sgn_xtnd_widen(xsp, lhswid);
8043     }
8044   }
8045  rhsx = bld_num_expr(xsp);
8046  __pop_xstk();
8047  return(rhsx);
8048 }
8049 
8050 /*
8051  * check a case statement
8052  *
8053  * SJM 05/10/04 - new algorithm turns off sign bit for widening if needed
8054  * for * every expression if select expr word32, if select expr signed
8055  * then compares are signed if match signed else unsigned
8056  */
chk_case(struct st_t * stp)8057 static void chk_case(struct st_t *stp)
8058 {
8059  register struct csitem_t *csip;
8060  register struct exprlst_t *xplp;
8061  int32 xwid, maxselwid, nd_realcnv, nd_unsgn_widen;
8062  struct csitem_t *dflt_csip;
8063 
8064  dflt_csip = stp->st.scs.csitems;
8065  /* first find maximum selection expression width */
8066  csip = dflt_csip->csinxt;
8067  for (maxselwid = 0; csip != NULL; csip = csip->csinxt)
8068   {
8069    /* check each expression in possible list */
8070    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8071     {
8072      xwid = __get_rhswidth(xplp->xp);
8073      if (xwid > maxselwid) maxselwid = xwid;
8074     }
8075   }
8076  /* including selector itself */
8077  xwid = __get_rhswidth(stp->st.scs.csx);
8078 
8079  if (xwid > maxselwid) maxselwid = xwid;
8080  stp->st.scs.maxselwid = (word32) maxselwid;
8081 
8082  /* now check expression using max. width context */
8083  for (csip = dflt_csip->csinxt; csip != NULL; csip = csip->csinxt)
8084   {
8085    /* check each expression in possible list */
8086    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8087     {
8088      __chk_rhsexpr(xplp->xp, maxselwid);
8089     }
8090    /* this must be a statement (at least null) */
8091    __chk_lstofsts(csip->csist);
8092   }
8093  __chk_rhsexpr(stp->st.scs.csx, maxselwid);
8094 
8095  if (dflt_csip->csist != NULL) __chk_lstofsts(dflt_csip->csist);
8096 
8097  /* SJM 12/12/03 - because real bit only turned on when rhs expr chk called */
8098  /* must set the real bits after do all other checking */
8099  /* one pass sets the flag if any expr real (select or case item) */
8100  csip = dflt_csip->csinxt;
8101  nd_unsgn_widen = FALSE;
8102  for (nd_realcnv = FALSE; csip != NULL; csip = csip->csinxt)
8103   {
8104    /* check each expression in possible list */
8105    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8106     {
8107      if (xplp->xp->is_real) nd_realcnv = TRUE;
8108      if (!xplp->xp->has_sign) nd_unsgn_widen = TRUE;
8109     }
8110   }
8111  if (stp->st.scs.csx->is_real) nd_realcnv = TRUE;
8112  if (stp->st.scs.csx->has_sign) nd_unsgn_widen = TRUE;
8113 
8114  if (!nd_realcnv && !nd_unsgn_widen) return;
8115 
8116  for (csip = dflt_csip->csinxt; csip != NULL; csip = csip->csinxt)
8117   {
8118    /* check each expression in possible list */
8119    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8120     {
8121      if (nd_realcnv)
8122       {
8123        if (!xplp->xp->is_real) xplp->xp->cnvt_to_real = TRUE;
8124       }
8125      if (nd_unsgn_widen)
8126       {
8127        if (xplp->xp->has_sign) xplp->xp->unsgn_widen = TRUE;
8128       }
8129     }
8130   }
8131  if (nd_realcnv)
8132   {
8133    if (!stp->st.scs.csx->is_real) stp->st.scs.csx->cnvt_to_real = TRUE;
8134   }
8135  if (nd_unsgn_widen)
8136   {
8137    if (stp->st.scs.csx->has_sign) stp->st.scs.csx->unsgn_widen = TRUE;
8138   }
8139 }
8140 
8141 /*
8142  * check a delay control statement
8143  */
chk_dctrl(struct delctrl_t * dctp)8144 static void chk_dctrl(struct delctrl_t *dctp)
8145 {
8146  int32 sav_ecnt;
8147  struct paramlst_t *dhdr;
8148 
8149  /* even if error keeep checking - also know list has exactly 1 element */
8150  if (dctp->dctyp == DC_EVENT || dctp->dctyp == DC_RHSEVENT)
8151   {
8152    /* SJM 06/01/04 - if implicit list form "@(*)" no expr to check */
8153    if (!dctp->implicit_evxlst)
8154     {
8155      __chk_evxpr(dctp->dc_du.pdels->plxndp);
8156     }
8157   }
8158  /* pound form normal rhs expression checked here */
8159  /* notice delay controls even if numbers scaled at execution time */
8160  /* always only and at least 1 value */
8161  else
8162   {
8163    dhdr = __copy_dellst(dctp->dc_du.pdels);
8164    __chk_delparams(dhdr, "procedural delay control", FALSE);
8165    __free_dellst(dhdr);
8166   }
8167 
8168  if (dctp->repcntx != NULL)
8169   {
8170    __chk_rhsexpr(dctp->repcntx, 0);
8171 
8172    if (dctp->repcntx->szu.xclen > WBITS)
8173     {
8174      __sgfwarn(543,
8175       "truncation of right hand side event control repeat count from %d to 32 bits - high bits ignored",
8176       dctp->repcntx->szu.xclen);
8177     }
8178   }
8179 
8180  sav_ecnt = __pv_err_cnt;
8181  /* for RHS delay control know is assign, else can be spliced up list */
8182  /* algorithm here is bottom up because this may process implicit @* forms */
8183  if (dctp->actionst != NULL) __chk_lstofsts(dctp->actionst);
8184 
8185  /* final step (must be done after statement checking) build the */
8186  /* all rhs form evxpr list */
8187  if (dctp->implicit_evxlst)
8188   {
8189    /* if errors in stmts can't build this list - make it empty */
8190    if (sav_ecnt > __pv_err_cnt)
8191     {
8192      __sgfwarn(3134, "implicit @(*) event control action statement has syntax errors - can't build implicit change list");
8193      __bld_unc_expr();
8194      dctp->dc_du.pdels->plxndp = __root_ndp;
8195      return;
8196     }
8197    if (dctp->actionst == NULL)
8198     {
8199      __sgfwarn(3135, "implicit @(*) event control no action statement - no implicit change list");
8200      __bld_unc_expr();
8201      dctp->dc_du.pdels->plxndp = __root_ndp;
8202      return;
8203     }
8204 
8205    /* if nothing in list - expr become op empty and no triggers */
8206    __impl_evlst_hd = __impl_evlst_tail = NULL;
8207    bld_stlst_evxlst(dctp->actionst);
8208    if (__impl_evlst_hd != NULL)
8209     {
8210      dctp->dc_du.pdels->plxndp = bld_evlst_comma_expr();
8211      __impl_evlst_hd = __impl_evlst_tail = NULL;
8212 
8213      /* SJM 08/03/04 - can't call check here because building normalized */
8214      /* to h:0 expressions but check uses actual src read decl ranges */
8215     }
8216   }
8217 }
8218 
8219 /*
8220  * bld the list of change ev xpr lists - check for duplicates
8221  */
bld_stlst_evxlst(struct st_t * hdstp)8222 static void bld_stlst_evxlst(struct st_t *hdstp)
8223 {
8224  register struct st_t *stp;
8225 
8226  /* notice legal empty statement list just does nothing here */
8227  for (stp = hdstp; stp != NULL; stp = stp->stnxt)
8228   {
8229    bld_stmt_evxlst(stp);
8230   }
8231 }
8232 
8233 /*
8234  * build the evxprlist for the action stmt for one @(*) implicit ev ctrl
8235  *
8236  * this must be run after the action stmt is checked for syntax errors
8237  * this must be run before pass 3 v prp because of for loops
8238  */
bld_stmt_evxlst(struct st_t * stp)8239 static void bld_stmt_evxlst(struct st_t *stp)
8240 {
8241  switch ((byte) stp->stmttyp) {
8242   case S_NULL: case S_STNONE: break;
8243   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA: case S_NBPROCA:
8244    /* know if lhs IS form bit or array select - will be split */
8245    bld_lhs_impl_evxlst(stp->st.spra.lhsx);
8246    bld_rhs_impl_evxlst(stp->st.spra.rhsx);
8247    break;
8248   case S_IF:
8249    bld_rhs_impl_evxlst(stp->st.sif.condx);
8250    bld_stlst_evxlst(stp->st.sif.thenst);
8251    if (stp->st.sif.elsest != NULL) bld_stmt_evxlst(stp->st.sif.elsest);
8252    break;
8253   case S_CASE:
8254    /* case is special case because selection and case item expressions */
8255    /* need to be added to list */
8256    bld_case_evxlst(stp);
8257    break;
8258   case S_WAIT:
8259    bld_stlst_evxlst(stp->st.swait.lpst);
8260    break;
8261   case S_FOREVER:
8262    bld_stlst_evxlst(stp->st.swh.lpst);
8263    break;
8264   case S_REPEAT:
8265    if (stp->st.srpt.repx != NULL)
8266     {
8267      bld_rhs_impl_evxlst(stp->st.srpt.repx);
8268     }
8269    bld_stlst_evxlst(stp->st.srpt.repst);
8270    break;
8271   case S_WHILE:
8272    if (stp->st.swh.lpx != NULL)
8273     {
8274      bld_rhs_impl_evxlst(stp->st.swh.lpx);
8275     }
8276    bld_stlst_evxlst(stp->st.swh.lpst);
8277    break;
8278   case S_FOR:
8279    {
8280     struct for_t *frs;
8281 
8282     /* notice for statement must use temporaries of right width */
8283     frs = stp->st.sfor;
8284     bld_stmt_evxlst(frs->forassgn);
8285     if (frs->fortermx != NULL) bld_rhs_impl_evxlst(frs->fortermx);
8286     bld_stmt_evxlst(frs->forinc);
8287     bld_stlst_evxlst(frs->forbody);
8288    }
8289    break;
8290   case S_DELCTRL:
8291    /* notice if implicit @(*) form event ctrl - implicit expr list */
8292    /* already built - but this needs to also add to any containing */
8293    /* list is union of all contained implicit dctrl lists */
8294    if (stp->st.sdc->actionst != NULL)
8295     {
8296      bld_stlst_evxlst(stp->st.sdc->actionst);
8297     }
8298    break;
8299   case S_NAMBLK:
8300    bld_stlst_evxlst(stp->st.snbtsk->tskst);
8301    break;
8302   case S_UNBLK:
8303    bld_stlst_evxlst(stp->st.sbsts);
8304    break;
8305   case S_UNFJ:
8306    {
8307     register int32 fji;
8308     struct st_t *fjstp;
8309 
8310     /* 1 sub stmt only, for unnamed begin-end will be unnamed block */
8311     for (fji = 0;; fji++)
8312      {
8313       if ((fjstp = stp->st.fj.fjstps[fji]) == NULL) break;
8314       /* SJM 09/24/01 - this can be 2 stmts for for (for assgn then for) */
8315       bld_stlst_evxlst(fjstp);
8316      }
8317    }
8318    break;
8319   case S_TSKCALL:
8320    /* task enable out ports are lhs exprs (but sel ndx needs to go in list) */
8321    /* does nothing for system tasks */
8322    bld_tskenable_evxlst(stp);
8323    break;
8324   case S_QCONTA: case S_QCONTDEA:
8325    /* SJM 06/01/04 - LOOKATME - think quasi-cont stmts can't cause triggers */
8326    /* because rhs changes outside of proc time */
8327    break;
8328   case S_DSABLE: case S_CAUSE:
8329    /* SJM 06/01/04 - LOOKATME - think cause is lhs expr here */
8330    break;
8331    default: __case_terr(__FILE__, __LINE__);
8332   }
8333 }
8334 
8335 /*
8336  * build case stmt evx lst - tricky because both select and case item
8337  * expr must be added
8338  */
bld_case_evxlst(struct st_t * stp)8339 static void bld_case_evxlst(struct st_t *stp)
8340 {
8341  register struct csitem_t *csip;
8342  register struct exprlst_t *xplp;
8343  struct csitem_t *dflt_csip;
8344 
8345  /* first build expr list element for case select */
8346  bld_rhs_impl_evxlst(stp->st.scs.csx);
8347 
8348  dflt_csip = stp->st.scs.csitems;
8349  csip = dflt_csip->csinxt;
8350  for (;csip != NULL; csip = csip->csinxt)
8351   {
8352    /* then expr list element for each case item expr */
8353    /* usually will be constants so none will be added */
8354    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8355     {
8356      bld_rhs_impl_evxlst(xplp->xp);
8357     }
8358   }
8359 
8360  /* now check expression using max. width context */
8361  for (csip = dflt_csip->csinxt; csip != NULL; csip = csip->csinxt)
8362   {
8363    /* check each expression in possible list */
8364    for (xplp = csip->csixlst; xplp != NULL; xplp = xplp->xpnxt)
8365     {
8366      bld_rhs_impl_evxlst(xplp->xp);
8367     }
8368    bld_stlst_evxlst(csip->csist);
8369    /* this must be a statement (at least null) */
8370   }
8371  if (dflt_csip->csist != NULL) bld_stlst_evxlst(dflt_csip->csist);
8372 }
8373 
8374 /*
8375  * build task enable stmt evx lst - output ports are lhs exprs here
8376  */
bld_tskenable_evxlst(struct st_t * stp)8377 static void bld_tskenable_evxlst(struct st_t *stp)
8378 {
8379  struct expr_t *xp;
8380  struct tskcall_t *tkcp;
8381  struct sy_t *syp;
8382  struct task_t *tskp;
8383  struct task_pin_t *tpp;
8384 
8385  tkcp = &(stp->st.stkc);
8386  syp = tkcp->tsksyx->lu.sy;
8387  /* SJM 06/01/04 - think system task rhs should not go in sensitivity list */
8388  if (syp->sytyp == SYM_STSK) return;
8389 
8390  tskp = tkcp->tsksyx->lu.sy->el.etskp;
8391  tpp = tskp->tskpins;
8392  for (xp = tkcp->targs; xp != NULL; xp = xp->ru.x, tpp = tpp->tpnxt)
8393   {
8394    /* output port connections are lvalues but must trigger on any indices */
8395    if (tpp->trtyp == IO_OUT) bld_lhs_impl_evxlst(xp->lu.x);
8396    else bld_rhs_impl_evxlst(xp->lu.x);
8397   }
8398 }
8399 
8400 /*
8401  * build rhs impl event expr list - all vars, bsel and psels go in list
8402  *
8403  * SJM 06/01/04 ### ??? FIXME - right to assume not including XMRs
8404  */
bld_rhs_impl_evxlst(struct expr_t * rhsx)8405 static void bld_rhs_impl_evxlst(struct expr_t *rhsx)
8406 {
8407  struct expr_t *evxp;
8408  struct exprlst_t *xplp;
8409  struct expr_t *ndp2;
8410 
8411  switch ((byte) rhsx->optyp) {
8412   case ID:
8413    /* DBG remove -- */
8414    if (rhsx->lu.sy->el.enp->n_isaparam) __misc_terr(__FILE__, __LINE__);
8415    /* --- */
8416    goto add_expr;
8417   case LSB: case PARTSEL:
8418 add_expr:
8419    evxp = __copy_expr(rhsx);
8420    if (!xp_in_evxlst(evxp))
8421     {
8422      xplp = (struct exprlst_t *) __my_malloc(sizeof(struct exprlst_t));
8423      xplp->xp = evxp;
8424      xplp->xpnxt = NULL;
8425      if (__impl_evlst_hd == NULL) __impl_evlst_hd = __impl_evlst_tail = xplp;
8426      else { __impl_evlst_tail->xpnxt = xplp; __impl_evlst_tail = xplp; }
8427     }
8428    break;
8429   case GLBREF:
8430    /* assuming XMR not in sensitivity list */
8431    break;
8432   case NUMBER: case ISNUMBER: case OPEMPTY:
8433   case REALNUM: case ISREALNUM:
8434    break;
8435   case QUEST:
8436    bld_rhs_impl_evxlst(rhsx->lu.x);
8437    bld_rhs_impl_evxlst(rhsx->ru.x->ru.x);
8438    bld_rhs_impl_evxlst(rhsx->ru.x->lu.x);
8439    break;
8440   case FCALL:
8441    /* this is func call side */
8442    for (ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
8443     {
8444      bld_rhs_impl_evxlst(ndp2->lu.x);
8445     }
8446    break;
8447   case LCB:
8448    /* know by here concatenates only one level */
8449    for (ndp2 = rhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
8450     {
8451      bld_rhs_impl_evxlst(ndp2->lu.x);
8452     }
8453    break;
8454   default:
8455    /* handle unary or binary operators */
8456    /* DBG remove -- */
8457    if (rhsx->lu.x == NULL) __misc_terr(__FILE__, __LINE__);
8458    /* --- */
8459    bld_rhs_impl_evxlst(rhsx->lu.x);
8460    if (rhsx->ru.x != NULL) bld_rhs_impl_evxlst(rhsx->ru.x);
8461  }
8462 }
8463 
8464 /*
8465  * build lhs impl event expr list
8466  *
8467  * only variable bit select are rhs expr that need to go in list
8468  * must handle concats - otherwise only needs to look at bsel/arrsel
8469  *
8470  * know all expr checking and folding completed before here
8471  */
bld_lhs_impl_evxlst(struct expr_t * lhsx)8472 static void bld_lhs_impl_evxlst(struct expr_t *lhsx)
8473 {
8474  register struct expr_t *ndp2;
8475 
8476  switch ((byte) lhsx->optyp) {
8477   case ID: case GLBREF: case OPEMPTY: break;
8478   case LSB:
8479    /* only need to add variable selects of bit select or array select */
8480    if (lhsx->ru.x->optyp == NUMBER || lhsx->ru.x->optyp == ISNUMBER)
8481     break;
8482    /* DBG remove -- */
8483    if (__is_const_expr(lhsx->ru.x)) __misc_terr(__FILE__, __LINE__);
8484    /* --- */
8485    bld_rhs_impl_evxlst(lhsx->ru.x);
8486    break;
8487   case PARTSEL:
8488    /* know ranges are constant */
8489    break;
8490   case LCB:
8491    /* know lhs concatenates never nested */
8492    for (ndp2 = lhsx->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
8493     {
8494      bld_lhs_impl_evxlst(ndp2->lu.x);
8495     }
8496    break;
8497   default: __case_terr(__FILE__, __LINE__);
8498  }
8499 }
8500 
8501 /*
8502  * return T if expr already in the ev xpr list
8503  */
xp_in_evxlst(struct expr_t * evxp)8504 static int32 xp_in_evxlst(struct expr_t *evxp)
8505 {
8506  register struct exprlst_t *xplp;
8507 
8508  for (xplp = __impl_evlst_hd; xplp != NULL; xplp = xplp->xpnxt)
8509   {
8510    /* SJM 06/01/04 - ### ??? LOOKATME - is this expr compare right */
8511    if (__cmp_xpr(evxp, xplp->xp)) return(TRUE);
8512   }
8513  return(FALSE);
8514 }
8515 
8516 /*
8517  * build implicit ev list comma expr from expr list
8518  *
8519  * notice needs to left associate and edges never appear
8520  */
bld_evlst_comma_expr(void)8521 static struct expr_t *bld_evlst_comma_expr(void)
8522 {
8523  register struct exprlst_t *xplp;
8524  struct expr_t *rootndp, *ndp;
8525  struct exprlst_t *xplp2;
8526  int32 first_time;
8527 
8528  first_time = TRUE;
8529  ndp = NULL;
8530  rootndp = NULL;
8531  for (xplp = __impl_evlst_hd; xplp != NULL; xplp = xplp->xpnxt)
8532   {
8533    if (first_time)
8534     {
8535      rootndp = xplp->xp;
8536      first_time = FALSE;
8537      continue;
8538     }
8539    ndp = __alloc_newxnd();
8540    ndp->optyp = OPEVCOMMAOR;
8541    ndp->lu.x = rootndp;
8542    ndp->ru.x = xplp->xp;
8543    rootndp = ndp;
8544   }
8545  /* DBG remove -- */
8546  if (__debug_flg) __dbg_msg(__msgexpr_tostr(__xs, rootndp));
8547  /* -- */
8548  /* free the expr list but not the contained exprs */
8549  for (xplp = __impl_evlst_hd; xplp != NULL;)
8550   {
8551    xplp2 = xplp->xpnxt;
8552    __my_free((char *) xplp, sizeof(struct exprlst_t));
8553    xplp = xplp2;
8554   }
8555  return(rootndp);
8556 }
8557 
8558 /*
8559  * STMT CHECKING ROUTINES FOR QC STMTS
8560  */
8561 
8562 /*
8563  * check a quasi continous assign/deassign reg. or force wire or reg
8564  * most checks special qc reg concatenate form
8565  *
8566  * assuming here there are 2 disjoint32 forms - force [normal decl. lhs] or
8567  * force [assign style register form] - concatentates cannot mix the 2
8568  */
chk_qclvalue(struct expr_t * ndp,word32 qctyp,int32 * is_rgform)8569 static void chk_qclvalue(struct expr_t *ndp, word32 qctyp,
8570  int32 *is_rgform)
8571 {
8572  register struct expr_t *ndp2;
8573  int32 cnt;
8574  char s1[RECLEN];
8575 
8576  *is_rgform = TRUE;
8577  /* one level concatenates for either reg or wire forms ok */
8578  /* for legal concatenate can not mix reg and wire elements */
8579  if (ndp->optyp == LCB)
8580   {
8581    for (cnt = 1, ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x,
8582     cnt++)
8583     {
8584      /* if this is normal declarative (wire only) lhs - must be force */
8585      if (!__xhas_reg(ndp2->lu.x))
8586       {
8587        if (qctyp != FORCE && qctyp != RELEASE)
8588         {
8589          __sgferr(808,
8590            "%s concatenate lvalue (pos. %d) contains wires - use force/release",
8591           __to_qctyp(s1, qctyp), cnt);
8592          return;
8593         }
8594        if (cnt == 1) *is_rgform = FALSE;
8595        else if (*is_rgform)
8596         {
8597          __sgferr(1150,
8598           "%s concatenate lvalue (pos %d) wire conflicts with reg form",
8599           __to_qctyp(s1, qctyp), cnt);
8600          return;
8601         }
8602        continue;
8603       }
8604      /* must be reg form */
8605      if (!nd_qcreg(ndp2->lu.x))
8606       {
8607        __sgferr(810,
8608         "%s concatenate lvalue (pos %d) not a scalared wire or simple reg",
8609         __to_qctyp(s1, qctyp), cnt);
8610        return;
8611       }
8612      if (!*is_rgform)
8613       {
8614        __sgferr(1150,
8615         "%s concatenate lvalue (pos %d) reg conflicts with wire form",
8616         __to_qctyp(s1, qctyp), cnt);
8617        return;
8618       }
8619     }
8620   }
8621  else
8622   {
8623    /* if this is normal declarative (wire only) lhs - must be force */
8624    if (!__xhas_reg(ndp))
8625     {
8626      if (qctyp != FORCE && qctyp != RELEASE)
8627       {
8628        __sgferr(808, "%s lvalue contains wires - use force/release",
8629         __to_qctyp(s1, qctyp));
8630        return;
8631       }
8632      *is_rgform = FALSE;
8633     }
8634    else
8635     {
8636      if (!nd_qcreg(ndp))
8637       {
8638        __sgferr(810, "%s lvalue not a scalared wire or simple reg",
8639         __to_qctyp(s1, qctyp));
8640        return;
8641       }
8642     }
8643   }
8644  /* final step is checking lhs expression */
8645  /* know for procedural required simple format already checked for */
8646  if (*is_rgform) __chk_lhsexpr(ndp, LHS_PROC);
8647  else __chk_lhsexpr(ndp, LHS_DECL);
8648 
8649  /* set used in qc force assign nets - set even if no code gen */
8650  set_qc_frcassgn_net(ndp);
8651 }
8652 
8653 /*
8654  * set used in QC stmt bit for all nets on LHS
8655  * always called but does nothing for interactive fixup (pass 2)
8656  */
set_qc_frcassgn_net(struct expr_t * ndp)8657 static void set_qc_frcassgn_net(struct expr_t *ndp)
8658 {
8659  struct net_t *np;
8660 
8661  if (__isleaf(ndp))
8662   {
8663    if (ndp->optyp == ID || ndp->optyp == GLBREF)
8664     {
8665      np = ndp->lu.sy->el.enp;
8666      if (np->nrngrep != NX_CT) return;
8667 
8668      np->nu.ct->frc_assgn_in_src = TRUE;
8669      /* setting mod flag for task to - i.e. no task qc assign/force flag */
8670      /* SJM 12/23/02 - only needs to be set during elaboration - if */
8671      /* added from PLI not needed */
8672      __inst_mod->mhas_frcassgn = TRUE;
8673     }
8674    return;
8675   }
8676  if (ndp->lu.x != NULL) set_qc_frcassgn_net(ndp->lu.x);
8677  if (ndp->ru.x != NULL) set_qc_frcassgn_net(ndp->ru.x);
8678 }
8679 
8680 /*
8681  * return T if expr. is a register
8682  * nd reg for id's - this is where node type is unknown
8683  * this reg cannot be a real
8684  */
nd_qcreg(struct expr_t * ndp)8685 static int32 nd_qcreg(struct expr_t *ndp)
8686 {
8687  struct net_t *np;
8688 
8689  if ((ndp->optyp != ID && ndp->optyp != GLBREF) || ndp->lu.sy->sytyp != SYM_N)
8690   return(FALSE);
8691  np = ndp->lu.sy->el.enp;
8692  if (np->n_isaparam) return(FALSE);
8693  if (np->ntyp >= NONWIRE_ST && np->ntyp != N_EVENT) return(TRUE);
8694  return(FALSE);
8695 }
8696 
8697 /*
8698  * must check qc assign/force (not deassign/release) for cirular use
8699  * of lhs component on rhs
8700  * error if lhs net used on rhs of assign/force
8701  *
8702  * SJM 07/16/03 new check added since code core dumps with stack overflow
8703  * otherwise
8704  * LOOKATME - currently pessimistic - different XMR inst or bit still error
8705  */
chk_circular_qc_stmt(struct st_t * stp)8706 static void chk_circular_qc_stmt(struct st_t *stp)
8707 {
8708  register struct expr_t *lhsx, *rhsx;
8709  int32 qctyp;
8710  struct expr_t *catndp, *catelx, *lhsx2;
8711  struct net_t *np;
8712  char s1[RECLEN];
8713 
8714  lhsx = stp->st.sqca->qclhsx;
8715  rhsx = stp->st.sqca->qcrhsx;
8716  qctyp =   stp->st.sqca->qcatyp;
8717  if (lhsx->optyp == LCB)
8718   {
8719    for (catndp = lhsx->ru.x; catndp != NULL; catndp = catndp->ru.x)
8720     {
8721      catelx = __get_lvalue_idndp(catndp->lu.x);
8722      /* DBG remove -- */
8723      if (catelx->optyp != ID && catelx->optyp != GLBREF)
8724       __misc_terr(__FILE__, __LINE__);
8725      /* -- */
8726      np = catelx->lu.sy->el.enp;
8727 
8728      if (rhs_expr_has_net(rhsx, np))
8729       {
8730        if (qctyp != FORCE && qctyp != RELEASE)
8731         {
8732          __sgferr(3409,
8733            "net %s in concatenate on both left and right hand sides of QC %s - illegal infinite loop",
8734            np->nsym->synam, __to_qctyp(s1, qctyp));
8735          return;
8736         }
8737       }
8738     }
8739    return;
8740   }
8741  lhsx2 = __get_lvalue_idndp(lhsx);
8742  /* DBG remove -- */
8743  if (lhsx2->optyp != ID && lhsx2->optyp != GLBREF)
8744   __misc_terr(__FILE__, __LINE__);
8745  /* -- */
8746  np = lhsx2->lu.sy->el.enp;
8747  if (rhs_expr_has_net(rhsx, np))
8748   {
8749    __sgferr(3409,
8750     "net %s on both left and right hand sides of QC %s - illegal infinite loop",
8751     np->nsym->synam, __to_qctyp(s1, qctyp));
8752   }
8753 }
8754 
8755 /*
8756  * get lvalue (lhs expr that is decomposed form concat) expr
8757  * for ID/XMR return expr else return left offspring
8758  */
__get_lvalue_idndp(struct expr_t * lhsx)8759 extern struct expr_t *__get_lvalue_idndp(struct expr_t *lhsx)
8760 {
8761  if (lhsx->optyp == GLBREF || lhsx->optyp == ID) return(lhsx);
8762  if (lhsx->optyp == LSB || lhsx->optyp == PARTSEL) return(lhsx->lu.x);
8763  __misc_terr(__FILE__, __LINE__);
8764  return(NULL);
8765 }
8766 
8767 /*
8768  * routine to return T if net contained in rhs expr
8769  */
rhs_expr_has_net(struct expr_t * rhsx,struct net_t * np)8770 static int32 rhs_expr_has_net(struct expr_t *rhsx, struct net_t *np)
8771 {
8772  if (__isleaf(rhsx))
8773   {
8774    if (rhsx->optyp == ID || rhsx->optyp == GLBREF)
8775     {
8776      if (rhsx->lu.sy->el.enp == np) return(TRUE);
8777     }
8778    return(FALSE);
8779   }
8780  if (rhsx->lu.x != NULL)
8781   { if (rhs_expr_has_net(rhsx->lu.x, np)) return(TRUE); }
8782  if (rhsx->ru.x != NULL)
8783   { if (rhs_expr_has_net(rhsx->ru.x, np)) return(TRUE); }
8784  return(FALSE);
8785 }
8786 
8787 /*
8788  * check a disable statement
8789  * tricky because if non global may need to replace with labl/task sym.
8790  */
chk_disable(struct st_t * stp)8791 static void chk_disable(struct st_t *stp)
8792 {
8793  struct expr_t *dsxp;
8794  struct sy_t *syp, *syp2;
8795  struct symtab_t *sytp;
8796  struct sy_t *upsyp;
8797  struct gref_t *grp;
8798 
8799  dsxp = stp->st.sdsable.dsablx;
8800  /* case 1: global cannot replace if cannot be disabled */
8801  if (dsxp->optyp == GLBREF) syp = dsxp->lu.sy;
8802  else if (dsxp->optyp == ID)
8803   {
8804    /* case 2: ID - make sure can be disabled and look upward */
8805    syp = dsxp->lu.sy;
8806    /* if not declared, or not disable try to find above */
8807    if (!syp->sydecl) goto use_syp;
8808 
8809    if (syp->sytyp != SYM_TSK && syp->sytyp != SYM_F
8810     && syp->sytyp != SYM_LB)
8811     {
8812      /* if ID disable and no current task, error */
8813      if (__cur_tsk == NULL) goto use_syp;
8814 
8815      /* work upward to task/func or named block that can be disabled */
8816      /* know parent of task is module and of module is nil */
8817      /* but only look starting one up since syp already set */
8818      sytp = __cur_tsk->tsksymtab->sytpar;
8819      for (; sytp != NULL; sytp = sytp->sytpar)
8820       {
8821        if ((syp2 = __get_sym(syp->synam, sytp)) != NULL)
8822         {
8823          /* if can be disabled, must change ID expr. symbol */
8824          /* but statement still points to same expr. */
8825          if (syp2->sytyp == SYM_TSK || syp2->sytyp != SYM_F
8826           || syp2->sytyp != SYM_LB)
8827           { syp = syp2; dsxp->lu.sy = syp; goto use_syp; }
8828         }
8829       }
8830      /* fall thru and use known wrong syp since no alternative */
8831     }
8832   }
8833  else { syp = NULL; __misc_sgfterr(__FILE__, __LINE__); }
8834 
8835  /* disable object not simple name */
8836 use_syp:
8837  if (!syp->sydecl) return;
8838  /* if ID and function know ok, if different func. error catch in nodel chk */
8839  if (dsxp->optyp == ID && syp->sytyp == SYM_F && __cur_tsk != NULL
8840   && __cur_tsk->tsktyp == FUNCTION) return;
8841 
8842  /* if error will still be global ID - else from now on normal symbol */
8843  if (syp->sytyp != SYM_TSK && syp->sytyp != SYM_LB)
8844   {
8845    __sgferr(968, "object \"%s\" type %s cannot be disabled",
8846     __to_idnam(dsxp), __to_sytyp(__xs, syp->sytyp));
8847   }
8848  /* know if local, good since accessible local means not in function */
8849  /* or checked in special inside function checking code */
8850  if (dsxp->optyp == GLBREF)
8851   {
8852    grp = dsxp->ru.grp;
8853    /* see if symbol table that target is in */
8854    /* think gref target symbol table should be set */
8855    if (grp->grsytp == NULL) __misc_sgfterr(__FILE__, __LINE__);
8856 
8857    for (sytp = grp->grsytp; sytp != NULL; sytp = sytp->sytpar)
8858     {
8859      upsyp = sytp->sypofsyt;
8860      if (upsyp->sytyp == SYM_TSK && upsyp->el.etskp->tsktyp == FUNCTION)
8861       {
8862        __sgferr(805,
8863         "disable target \"%s\" type %s cannot be inside function",
8864         __to_idnam(dsxp), __to_sytyp(__xs, upsyp->sytyp));
8865        return;
8866       }
8867     }
8868   }
8869 }
8870