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