1 /* Copyright (c) 1991-2007 Pragmatic C Software Corp. */
2 
3 /*
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2 of the License, or (at your
7    option) any later version.
8 
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17 
18    We are selling our new Verilog compiler that compiles to X86 Linux
19    assembly language.  It is at least two times faster for accurate gate
20    level designs and much faster for procedural designs.  The new
21    commercial compiled Verilog product is called CVC.  For more information
22    on CVC visit our website at www.pragmatic-c.com/cvc.htm or contact
23    Andrew at avanvick@pragmatic-c.com
24 
25  */
26 
27 
28 /*
29  * module that fixes and checks net list after all source read
30  * all defparam and global processing in v_grf
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 
38 #include <sys/types.h>
39 
40 #if defined(__SVR4) || defined(__hpux) || defined(__CYGWIN32__) || defined(__FreeBSD__)
41 #include <dirent.h>
42 #else
43 #include <sys/dir.h>
44 #endif
45 
46 #ifdef __DBMALLOC__
47 #include "../malloc.h"
48 #endif
49 
50 #include "v.h"
51 #include "cvmacros.h"
52 
53 /* local prototypes */
54 static void resolve_undef_mods(void);
55 static void process_lib(void);
56 static void resolve_from_ydir(struct vylib_t *);
57 static struct undef_t *add_undef_el(struct sy_t *, struct undef_t **,
58  struct undef_t **);
59 static void bld_ylb_dirfiles(struct vylib_t *);
60 static int32 srch_yfiles(char *, struct mydir_t *, word32);
61 static int32 fn_cmp(const void *, const void *);
62 static void rd_vlibfil(struct undef_t *);
63 static void rescan_process_lib(void);
64 static void rescan_resolve_from_ydir(struct vylib_t *, struct undef_t *);
65 static void free_tnblks(void);
66 static void sep_mdgates(void);
67 static int32 count_minum_and_mgnum(int32 *, struct mod_t *);
68 static void cellrep_to_gate(struct cell_t *, struct gate_t *);
69 static void add_mod_attrs_toinst(struct inst_t *);
70 static int32 pndparams_explicit(struct namparam_t *, int32 *);
71 static struct paramlst_t *bld_gate_paramlst(struct namparam_t *);
72 static void bld_giarr(struct mod_t *, int32, struct cell_t *, int32);
73 static void init_giarr(struct giarr_t *);
74 static int32 cnt_gateprts(struct cell_t *);
75 static void cellrep_to_inst(struct cell_t *, struct inst_t *);
76 static void init_inst(struct inst_t *);
77 static struct expr_t **inst_nparms_to_xtab(struct namparam_t *,
78  struct inst_t *);
79 static struct expr_t **match_namparam_exprtab(struct namparam_t *,
80  struct inst_t *);
81 static int32 chk1_pndparam(char *, struct inst_t *, struct namparam_t *,
82  int32, int32);
83 static int32 prmtab_cmp(const void *, const void *);
84 static struct expr_t **match_implprm_exprtab(struct namparam_t *,
85  struct inst_t *);
86 static void bld_miarr(struct mod_t *, int32, struct cell_t *, int32);
87 static int32 fix_modcell_nl(void);
88 static int32 count_static_instances(struct mod_t *);
89 static int32 chk_dag(void);
90 static void fix_port_conns(void);
91 static void setchk_modports(void);
92 static int32 chk_prtref(struct expr_t *, struct mod_pin_t *, int32);
93 static int32 chk_prtntyp(struct mod_pin_t *, struct net_t *);
94 static void conn_mod_insts(void);
95 static void conn_impl_mports(struct inst_t *, struct cell_pin_t *,
96  struct mod_t *, struct expr_t **, struct srcloc_t *);
97 static void conn_expl_mports(struct inst_t *, struct cell_pin_t *,
98  struct mod_t *, struct expr_t **, struct srcloc_t *);
99 static int32 chk_mdports_named(struct inst_t *, struct mod_t *, struct expr_t **);
100 static void bld_srted_mdpins(struct mod_t *);
101 static int32 smp_cmp(const void *, const void *);
102 static int32 bld_srted_ipins(struct inst_t *, register struct cell_pin_t *,
103  int32, struct cell_pin_t **);
104 static int32 cpn_cmp(const void *, const void *);
105 static void free_cpblks(void);
106 static void free_cppblks(void);
107 static void count_flat_insts(void);
108 static void count2_flat_insts(struct mod_t *);
109 static void chg_params_to_tab(void);
110 static int32 cnt_prms(struct net_t *);
111 static void free_param_listform(struct net_t *);
112 static void do_giarr_splitting(void);
113 static void mark_gia_rng_params(struct mod_t *);
114 static int32 in_giarng_markparam(struct giarr_t *, struct expr_t *);
115 static int32 down_hasgiarngdet_param(struct mod_t *);
116 static void bld_top_virtinsts(void);
117 static int32 topip_cmp(const void *, const void *);
118 static void save_all_param_vals(void);
119 static void free_all_param_vals(void);
120 static void set_giarr_ranges(void);
121 static void eval1_arr_of_gates_rng(struct giarr_t *, struct mod_t *,
122  struct itree_t *, int32);
123 static int32 gi_ndxexpr_chk(struct expr_t *, int32, int32, char *);
124 static int32 gi_ndxval_chk(struct xstk_t *, int32, int32, char *);
125 static void eval1_arr_of_insts_rng(struct giarr_t *, struct mod_t *,
126  struct itree_t *, int32);
127 static void set_pnd_gi_rnges(void);
128 static void set2_pnd_gi_rnges(struct mod_t *, struct itree_t *);
129 static void set_gia_expr_pndparms(struct expr_t *, struct itree_t *);
130 static void set1_giarr_pndparm(struct net_t *, struct itree_t *);
131 static void unsave_gia_expr_pndparms(struct expr_t *, struct itree_t *);
132 static void rebld_mod_giarrs(void);
133 static int32 gia_sym_cmp(const void *, const void *);
134 static void add_new_gsym(struct gate_t *, int32);
135 static void add_new_isym(struct inst_t *, int32);
136 static void chk_defparams(void);
137 static int32 lhs_chk1dfparam(struct dfparam_t *);
138 static int32 gref_has_giarr_ndxes(struct gref_t *);
139 static void set_1defparam_iis(struct dfparam_t *, struct gref_t *);
140 static void resolve_xmrs(void);
141 static int32 resolve_local_path(struct gref_t *, struct expr_t *);
142 static int32 chk_xmr_tail_wire(struct gref_t *, struct sy_t *, int32);
143 static int32 fill_dfp_gsymhead(struct gref_t *, struct expr_t *);
144 static int32 fill_gsymhead(struct gref_t *, struct expr_t *);
145 static int32 chk_all_uprels_same(struct gref_t *, struct sy_t *, char *,
146  struct expr_t *);
147 static struct sy_t *fnd_uprel_inst(char *, struct itree_t *);
148 static int32 fnd_uprel_mod(struct sy_t *, struct itree_t *);
149 static struct mod_t *fnd_uprel_tskfunc(struct sy_t **, char *,
150  struct itree_t *);
151 static struct sy_t *fnd_tskfunc_inscope(char *, struct symtab_t *);
152 static int32 fill_grestsyms(struct gref_t *, struct expr_t *);
153 static struct sy_t *find_inmod_sym(struct gref_t *, struct expr_t *,
154  struct sy_t *, struct symtab_t **);
155 static int32 chk_glb_inst_sels(struct gref_t *);
156 static void free_gone_glbs(void);
157 static void mark_poundparam_splitinsts(void);
158 static int32 indir_widthdet_markparam(struct expr_t *);
159 static void do_poundparam_splitting(void);
160 static void split_upd_mod(struct mod_t *, struct inst_t *, int32);
161 static void copy_mod(struct mod_t *, char *);
162 static void copy_modsymtabs(void);
163 static void copy_lowsymtab(register struct symtab_t *, struct symtab_t *);
164 static struct symtab_t *copy_1symtab(struct symtab_t *);
165 static struct sy_t **copy_stsyms(struct sy_t **, word32);
166 static void copy_modports(void);
167 static void copy_wires(struct symtab_t *);
168 static struct net_t *copy_params(struct net_t *, int32, int32);
169 static void copy_defparams(void);
170 static void copy_insts(void);
171 static struct attr_t *copy_attrs(struct attr_t *);
172 static struct varinitlst_t *copy_varinits(struct varinitlst_t *);
173 static void copy_1inst(struct inst_t *, struct inst_t *, int32);
174 static struct expr_t **copy_pndxtab(struct inst_t *);
175 static void copy_iports(struct inst_t *, struct inst_t *);
176 static void copy_miarr(void);
177 static void copy_gates(void);
178 static void copy_1gate(struct gate_t *, struct gate_t *, int32);
179 static void copy_mgarr(void);
180 static void copy_contas(void);
181 static void copy_mdtasks(void);
182 static struct task_pin_t *copy_tskargs(struct task_t *);
183 static struct st_t *copy_stmt(struct st_t *);
184 static struct st_t *copy_lstofsts(register struct st_t *);
185 static struct ialst_t *copy_ialst(register struct ialst_t *);
186 static struct csitem_t *copy_csitemlst(register struct csitem_t *);
187 static struct exprlst_t *copy_xprlst(struct exprlst_t *);
188 static void copy_mgrefs(void);
189 static void copy_1gref_flds(struct gref_t *, struct gref_t *);
190 static void copy_specify(void);
191 static void copy_spcpths(struct spfy_t *, struct spfy_t *);
192 static void copy_timchks(struct spfy_t *, struct spfy_t *);
193 static struct tchk_t *copy1_tchk(struct tchk_t *);
194 static void bld2_flat_itree(struct itree_t *);
195 static int32 dmp_down_itree(struct itree_t *, int32, int32);
196 static void do_dmp(struct itree_t *, int32);
197 static void free2_flat_itree(struct itree_t *);
198 static void bld_moditps(void);
199 static void bld2_itnum_to_itp(struct itree_t *);
200 
201 
202 /* extern prototypes (maybe defined in this module) */
203 extern char *__my_malloc(int32);
204 extern char *__my_realloc(char *, int32, int32);
205 extern char *__pv_stralloc(char *);
206 extern struct ncomp_t *__alloc_arrncomp(void);
207 extern char *__prt_vtok(void);
208 extern struct xstk_t *__eval2_xpr(struct expr_t *);
209 extern int32 __isleaf(struct expr_t *);
210 extern int32 __wide_vval_is0(register word32 *, int32);
211 extern struct expr_t *__alloc_newxnd(void);
212 extern struct exprlst_t *__alloc_xprlst(void);
213 extern char *__to_ptnam(char *, word32);
214 extern char *__to_wtnam(char *, struct net_t *);
215 extern char *__to_sytyp(char *, word32);
216 extern char *__msgexpr_tostr(char *, struct expr_t *);
217 extern struct expr_t *__copy_expr(struct expr_t *);
218 extern void __bld_flat_itree(void);
219 extern void __free_flat_itree(void);
220 /* DBG */
221 extern void __dmp_itree(struct itree_t *);
222 /* --- */
223 extern struct sy_t *__zget_sym(char *, struct sy_t **, word32);
224 extern struct sy_t *__add_modsym(char *);
225 extern struct sy_t *__get_sym(char *, struct symtab_t *);
226 extern struct symtab_t *__alloc_symtab(int32);
227 extern struct paramlst_t *__alloc_pval(void);
228 extern struct delctrl_t *__alloc_dctrl(void);
229 extern struct csitem_t *__alloc_csitem(void);
230 extern struct paramlst_t *__copy_dellst(struct paramlst_t *);
231 extern char *__bld_lineloc(char *, word32, int32);
232 extern void __process_defparams(void);
233 extern void __set_poundparams(void);
234 extern void __process_timescales(void);
235 extern void __recalc_param_vals(void);
236 extern void __chk_1mdecls(void);
237 extern void __mark_st_wires(void);
238 extern void __setchk_mpwidths(void);
239 extern void __chk_shorted_bids(void);
240 extern void __reconn_gia_pins(void);
241 extern void __reset_modport_strens(void);
242 extern void __prt_top_mods(void);
243 extern void __chk_mod(void);
244 extern void __free_icptab(void);
245 extern void __chkfix_spfy(void);
246 extern void __free_specify(struct mod_t *);
247 extern void __free_tchks(struct tchk_t *);
248 extern void __emit_param_informs(void);
249 extern void __grow_infils(int32);
250 extern void __my_free(char *, int32);
251 extern void __get_vtok(void);
252 extern void __process_cdir(void);
253 extern int32 __vskipto_modend(int32);
254 extern int32 __vskipto2_modend(int32, int32);
255 extern int32 __rd_moddef(struct symtab_t *, int32);
256 extern int32 __rd_udpdef(struct symtab_t *);
257 extern void __my_rewind(FILE *);
258 extern void __my_fclose(FILE *);
259 extern FILE *__tilde_fopen(char *, char *);
260 extern void __free_xtree(struct expr_t *);
261 extern void __free2_xtree(struct expr_t *);
262 extern void __bld_unc_expr(void);
263 extern void __in_xpr_markparam(struct expr_t *);
264 extern int32 __chk_paramexpr(struct expr_t *, int32);
265 extern void __set_numval(struct expr_t *, word32, word32, int32);
266 extern void __free_1dfparam(struct dfparam_t *);
267 extern struct gref_t *__alloc_grtab(struct gref_t *, int32);
268 extern void __resolve_glbnam(struct gref_t *);
269 extern int32 __ip_indsrch(char *);
270 extern void __free_1glb_flds(struct gref_t *);
271 extern void __bld_mlevel_lists(void);
272 extern void __mark_widdet_params(struct mod_t *);
273 extern void __do_mdsplit(struct mod_t *);
274 extern void __init_itree_node(struct itree_t *);
275 extern int32 __chk_giarr_ndx_expr(struct expr_t *);
276 extern int32 __get_giarr_wide(struct giarr_t *);
277 extern void __dmp_dsgn_minst(char *);
278 extern void __dmp_1minst(struct inst_t *);
279 extern int32 __expr_has_glb(struct expr_t *);
280 extern char *__regab_tostr(char *, word32 *, word32 *, int32, int32, int32);
281 extern void __free_namedparams(struct namparam_t *);
282 extern int32 __chkndx_expr(struct expr_t *, char *);
283 extern void __cnvt_param_stkval(struct xstk_t *, struct expr_t *,
284  struct net_t *, char *);
285 extern void __assgn_nonis_param(struct net_t *, struct expr_t *,
286  struct xstk_t *);
287 extern char *__msg2_blditree(char *, struct itree_t *);
288 extern int32 __get_arrwide(struct net_t *);
289 extern void __push_wrkitstk(struct mod_t *, int32);
290 extern void __pop_wrkitstk(void);
291 extern struct mod_t *__get_mast_mdp(struct mod_t *);
292 extern void __set_drvr_bits(void);
293 extern void __chk_chg_port_dir(int32);
294 extern int32 __open_lbfil(int32);
295 
296 extern void __cv_msg(char *, ...);
297 extern void __crit_msg(char *, ...);
298 extern void __pv_ferr(int32, char *, ...);
299 extern void __pv_err(int32, char *, ...);
300 extern void __pv_warn(int32, char *,...);
301 extern void __gfwarn(int32, word32, int32, char *, ...);
302 extern void __sgfwarn(int32, char *, ...);
303 extern void __pv_fwarn(int32, char *, ...);
304 extern void __gfinform(int32, word32, int32, char *, ...);
305 extern void __gferr(int32, word32, int32, char *, ...);
306 extern void __sgferr(int32, char *, ...);
307 extern void __finform(int32, char *, ...);
308 extern void __dbg_msg(char *, ...);
309 extern void __sgfinform(int32, char *, ...);
310 extern void __pv_terr(int32, char *, ...);
311 extern void __gfterr(int32, word32, int32, char *, ...);
312 extern void __arg_terr(char *, int32);
313 extern void __case_terr(char *, int32);
314 extern void __misc_terr(char *, int32);
315 extern void __misc_gfterr(char *, int32, word32, int32);
316 
317 /*
318  * DESIGN WIDE SYNTAX/SEMANTICS CHECKING ROUTINES
319  */
320 
321 /*
322  * fixup the net list after all modules read
323  * this is second pass on internal data structure
324  * returns T to get cannot continue message
325  */
__fixup_nl(void)326 extern int32 __fixup_nl(void)
327 {
328  register struct mod_t *mdp;
329 
330  /* find and resolve unsatisfied module/udp refs - process lib. in here */
331  /* SJM 05/19/04 - following new P1364 LRM, config can't be in src */
332  if (__map_files_hd == NULL && __undef_mods != 0)
333   {
334    resolve_undef_mods();
335    if (__undef_mods != 0)
336     {
337      __crit_msg(
338       "  %d modules or udps unresolved after library processing - cannot continue.\n",
339       __undef_mods);
340      return(FALSE);
341     }
342   }
343 
344  /* at this point all module and task symbol tables frozen so can free */
345  /* the tree nodes (can be large) and change formats */
346  free_tnblks();
347  chg_params_to_tab();
348 
349  /* separate into gates and module instances */
350  /* also converts cell term expr. list to array of exprs (never explicit) */
351  sep_mdgates();
352 
353  /* build static instance information */
354  if (!fix_modcell_nl()) return(TRUE);
355 
356  /* check module ports and connect inst ports (for iarrs conns unexpanded) */
357  fix_port_conns();
358 
359  /* AIV 06/01/04 FIXME ### ??? bug if config used and free these blocks */
360  /* now finished with cell pins and cells */
361  if (__map_files_hd != NULL)
362   {
363    free_cpblks();
364    /* this also frees cell pins (optional explicit port name) */
365    free_cppblks();
366   }
367 
368  count_flat_insts();
369 
370  /* need well formed static instance tree to continue */
371  if (__pv_err_cnt != 0) return(TRUE);
372 
373  /* build the levelized module table - rebuilt later again after splitting */
374  __bld_mlevel_lists();
375 
376  /* do split - needed because pound param used in array of gate/inst ranges */
377  if (__design_gi_arrays && __num_inst_pndparams != 0) do_giarr_splitting();
378 
379  /* build top of itree table now so can search tops when build dfpii */
380  bld_top_virtinsts();
381 
382  /* after here, all g/i array ranges known */
383  /* current value of pound params used then value thrown away because */
384  /* defparam setting and splitting may change again */
385  if (__design_gi_arrays)
386   {
387    /* save all module (not task/func) parameter values */
388    save_all_param_vals();
389 
390    set_giarr_ranges();
391    /* rebuild array and gate tables in module with g/i arrays */
392    rebld_mod_giarrs();
393 
394    /* final step free saved param value records */
395    free_all_param_vals();
396   }
397 
398  /* check all defparams lhs and move globals to defparam struct */
399  chk_defparams();
400 
401  /* do all splitting for all pound params */
402  /* must set pound params after all splitting since need itree inst num. */
403  if (__num_inst_pndparams != 0)
404   {
405    mark_poundparam_splitinsts();
406    do_poundparam_splitting();
407   }
408 
409  /* build the as if flattened instance tree and assign instance numbers */
410  __bld_flat_itree();
411 
412  /* -- v_fx2.c routines start here -- */
413 
414  /* handle defparam setting and associated splitting and param expr array */
415  /* building - finally reassigns itree place numbers */
416  /* after here all parameters have a numeric value (but maybe IS form) */
417  /* therefore can fold and evaluate constant expressions */
418 
419  /* notice if have defparams must process pound params at same time */
420  /* else do just pound params separately */
421  if (__num_dfps != 0) __process_defparams();
422  else if (__num_inst_pndparams != 0) __set_poundparams();
423 
424  /* final itree instance numbers now assigned, build mod by num to inst tab */
425  bld_moditps();
426 
427  /* resolve all global variables */
428  /* this reuses much of freed defparam storage if needed */
429  resolve_xmrs();
430 
431  /* must stop here if errors since will not have value for xmrs */
432  if (__pv_err_cnt != 0) return(TRUE);
433 
434  /* fixup - 2nd pass done - connectivity now known and no errors */
435 
436  /* set timescale info before module checking that converts delays to ticks */
437  __process_timescales();
438 
439  /* re-calculate parameter values, for params with other rhs params */
440  /* may have been changed by pount or defparam setting */
441  /* SJM 02/28/02 - need so parameter values use post pound/def val */
442  __recalc_param_vals();
443 
444  /* now all parameter values known */
445  /* must check decl. and eval. wire params before setting port widths */
446  /* must always have at least dummy itree context set for these */
447  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
448   {
449    __push_wrkitstk(mdp, 0);
450 
451    /* LOOKATME maybe could change to scheme where one mod net table */
452    /* contains all mod nets and regs decled in all tasks since one set */
453    /* per task - SJM 02/29/00 - yes moved chk taskvars to chk 1 mdecls */
454    __chk_1mdecls();
455 
456    __pop_wrkitstk();
457   }
458 
459  /* SJM 05/23/01 - can't guess port types until ranges known as exprs */
460  /* set net per bit drvrs class (type) and change port dir if option on, */
461  /* else warns */
462  /* must do this after xmr's resolved and know ranges so can access xmr net */
463  __set_drvr_bits();
464  __chk_chg_port_dir(__chg_portdir);
465 
466  /* at this point all wire widths known */
467 
468  /* if no arrays of gate or instances in design, can set strengths now */
469  if (!__design_gi_arrays) __mark_st_wires();
470 
471  /* mod port widths set here, widths now known - inst. width set in chk mod */
472  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
473   {
474    __push_wrkitstk(mdp, 0);
475    __setchk_mpwidths();
476    __chk_shorted_bids();
477 
478    /* must make sure module level symbols are all marked as top level */
479    mdp->msym->spltsy = NULL;
480    __pop_wrkitstk();
481   }
482 
483  if (__design_gi_arrays)
484   {
485    __reconn_gia_pins();
486    /* mark wire that have strength storage format */
487    __mark_st_wires();
488    /* now set strength in port expr. bits if lhs with strength variable */
489    /* only check exprs (because need size) at this point are ports */
490    __reset_modport_strens();
491   }
492 
493  /* if decl. errors cannot continue - do not know port widths */
494  /* and probably have missing expr. node fields */
495  if (__pv_err_cnt != 0) return(TRUE);
496 
497  if (!__quiet_msgs) __prt_top_mods();
498 
499  /* check mainly element usage semantics */
500  /* expression node widths and constant optimizations here */
501  /* statement checking here */
502  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
503   {
504    __push_wrkitstk(mdp, 0);
505    __chk_mod();
506    __pop_wrkitstk();
507   }
508 
509  /* free iploctab (line no. per contained mod port) shared among split */
510  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
511   {
512    __push_wrkitstk(mdp, 0);
513    __free_icptab();
514    __pop_wrkitstk();
515   }
516 
517  /* -- specify fixup (pass 2) routines in v fx3 but also expr checking */
518 
519  /* check and fix up expressions from specify section */
520  /* also emit all unused parameter (both types warnings */
521  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
522   {
523    __push_wrkitstk(mdp, 0);
524    if (mdp->mspfy != NULL)
525     {
526      __chkfix_spfy();
527      if (__no_specify)
528       { __free_specify(mdp); mdp->mspfy = NULL; }
529      else if (mdp->mspfy->tchks != NULL && __no_tchks)
530       {
531        __free_tchks(mdp->mspfy->tchks);
532        mdp->mspfy->tchks = NULL;
533       }
534     }
535    __emit_param_informs();
536    __pop_wrkitstk();
537   }
538  return(TRUE);
539 }
540 
541 /*
542  * routine to print top level modules - on one line
543  * always printed unless -q on
544  */
__prt_top_mods(void)545 extern void __prt_top_mods(void)
546 {
547  register int32 tpii;
548  struct inst_t *ip;
549 
550  __cv_msg("Highest level modules:\n");
551  for (tpii = 0; tpii < __numtopm; tpii++)
552   {
553    ip = __top_itab[tpii];
554    __cv_msg("%s\n", ip->imsym->synam);
555   }
556 }
557 
558 /*
559  * MODULE DECLARATION CHECKING AND LIBRARY RESOLUTION ROUTINES
560  */
561 
562 /*
563  * resolve all undefined modules and udps
564  */
resolve_undef_mods(void)565 static void resolve_undef_mods(void)
566 {
567  register struct undef_t *undefp;
568  struct sy_t *syp;
569 
570  /* try to satisfy unresolved modules/udps from -y, -v or - lib. */
571  /* check for remaining unresolveds, cannot continue if any */
572  if (__vyhdr != NULL)
573   {
574    if (__lib_rescan) rescan_process_lib();
575    else process_lib();
576   }
577  if (__undef_mods > 0)
578   {
579    /* notice this must be printed no matter what */
580    __crit_msg("Unresolved modules or udps:\n");
581    for (undefp = __undefhd; undefp != NULL; undefp = undefp->undefnxt)
582     {
583      syp = undefp->msyp;
584      if(syp->sydecl || !syp->syundefmod) __misc_terr(__FILE__, __LINE__);
585      __crit_msg("  %s\n", syp->synam);
586     }
587    __crit_msg("\n");
588   }
589  /* if libverbose messages need to separate */
590  else if (__lib_verbose) __cv_msg("\n");
591 }
592 
593 /*
594  * process library to attempt to resolve all unresolved libraries
595  * only called if unresolved modules/udps remain
596  */
process_lib(void)597 static void process_lib(void)
598 {
599  register struct undef_t *undefp;
600  register struct vylib_t *vyp;
601  int32 num_passes, sav_last_lbf;
602  struct sy_t *syp;
603 
604  /* go thru libs in order */
605  for (num_passes = 1;; num_passes++)
606   {
607    if (num_passes > 1) __rescanning_lib = TRUE;
608 
609    __cur_passres = 0;
610    if (__lib_verbose)
611     {
612      /* notice only unresolved after 1st pass are interesting */
613      if (num_passes > 1)
614       {
615        __cv_msg("\n  Library scan pass %d with the following %d undefined:\n",
616         num_passes, __undef_mods);
617        for (undefp = __undefhd; undefp != NULL; undefp = undefp->undefnxt)
618         {
619          syp = undefp->msyp;
620          __cv_msg("    %s (first reference %s)\n", syp->synam,
621           __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt));
622         }
623       }
624      else __cv_msg("\n  Begin library scan pass %d (%d undefined).\n",
625       num_passes, __undef_mods);
626     }
627 
628    for (vyp = __vyhdr; vyp != NULL; vyp = vyp->vynxt)
629     {
630      /* AIV 11/11/03 - if -y dir is empty changed to 'e' so do nothing */
631      /* this handles multiple passes empty directories */
632      if (vyp->vytyp == 'e') continue;
633 
634      if (vyp->vytyp == 'y')
635       {
636        if (vyp->yfiles == NULL) bld_ylb_dirfiles(vyp);
637 
638        /* AIV 11/11/03 - if -y dir is empty made 'e' and must do nothing */
639        if (vyp->vytyp == 'e') continue;
640 
641        resolve_from_ydir(vyp);
642        if (__undef_mods <= 0) return;
643        continue;
644       }
645 
646      /* add or reuse -v library file to in_fils */
647      if (vyp->vyfnam_ind == 0)
648       {
649        /* this dies if >64k */
650        if (++__last_lbf >= __siz_in_fils) __grow_infils(__last_lbf);
651        vyp->vyfnam_ind = __last_lbf;
652        __in_fils[__last_lbf] = __pv_stralloc(vyp->vyu.vyfnam);
653       }
654 
655      sav_last_lbf = __last_lbf;
656      __last_lbf = vyp->vyfnam_ind;
657      /* know this will leave undef_mods with correct value */
658      if (__open_lbfil(FALSE)) rd_vlibfil(NULL);
659      __last_lbf = sav_last_lbf;
660      if (__undef_mods <= 0) return;
661     }
662    if (__cur_passres == 0)
663     {
664      __pv_err(706,
665       "%d modules or primitives unresolved after pass %d with no progress",
666       __undef_mods, num_passes);
667      return;
668     }
669   }
670 }
671 
672 /*
673  * resolve unresolved references from a library directory
674  * tricky because resolve as go along effecting __undefhd list
675  *
676  * algorithm is:
677  * 1) go through all unresolved and find all files that match any suffix
678  *    and add to list
679  * 2) then read and scan all files for any (not just names that produced
680  *    file by adding +lbext+ suffix) unresolved - quits in case all resolved
681  */
resolve_from_ydir(struct vylib_t * vyp)682 static void resolve_from_ydir(struct vylib_t *vyp)
683 {
684  register int32 lbxi;
685  register struct undef_t *undefp;
686  int32 dfi, sav_last_lbf, got_err;
687  struct undef_t *tmphd, *tmptail, *tmpundefp, *undefp2;
688  char fnam[IDLEN], stem[IDLEN];
689 
690  tmphd = tmptail = NULL;
691  /* build stem that gives current path to directory */
692  sprintf(stem, "%s/", vyp->vyu.vydirpth);
693  /* case 1: no lbext - module name must exactly match file name */
694  if (__last_lbx == -1)
695   {
696    for (undefp = __undefhd; undefp != NULL; undefp = undefp->undefnxt)
697     {
698      if ((dfi = srch_yfiles(undefp->msyp->synam, vyp->yfiles, vyp->vyfnam_ind))
699       == -1 ) continue;
700      /* add to tmp list since parsing changes __undefhd list */
701      tmpundefp = add_undef_el(undefp->msyp, &tmphd, &tmptail);
702      tmpundefp->dfi = dfi;
703      vyp->yfiles[dfi].ylbxi = 0;
704     }
705   }
706  else
707   {
708    /* case 2: must add lbext to module name and see if matches */
709    /* build temporary list of all */
710    for (undefp = __undefhd; undefp != NULL; undefp = undefp->undefnxt)
711     {
712      for (lbxi = 0; lbxi <= __last_lbx; lbxi++)
713       {
714        sprintf(fnam, "%s%s", undefp->msyp->synam, __lbexts[lbxi]);
715        if ((dfi = srch_yfiles(fnam, vyp->yfiles, vyp->vyfnam_ind)) == -1)
716         continue;
717 
718        /* add to tmp list since parsing changes __undefhd list */
719        tmpundefp = add_undef_el(undefp->msyp, &tmphd, &tmptail);
720        tmpundefp->dfi = dfi;
721        vyp->yfiles[dfi].ylbxi = lbxi;
722        /* when found, from precedence rules must stop looking */
723        break;
724       }
725     }
726   }
727  /* go through temp list reading file */
728  for (undefp = tmphd; undefp != NULL; undefp = undefp->undefnxt)
729   {
730    dfi = undefp->dfi;
731    if (vyp->yfiles[dfi].ydirfnam_ind == 0)
732     {
733      /* this dies if >64k */
734      if (++__last_lbf >= __siz_in_fils) __grow_infils(__last_lbf);
735      vyp->yfiles[dfi].ydirfnam_ind = __last_lbf;
736      if (__last_lbx == -1) sprintf(fnam, "%s%s", stem, undefp->msyp->synam);
737      else
738       {
739        lbxi = vyp->yfiles[dfi].ylbxi;
740        sprintf(fnam, "%s%s%s", stem, undefp->msyp->synam, __lbexts[lbxi]);
741       }
742      __in_fils[__last_lbf] = __pv_stralloc(fnam);
743     }
744    /* notice each lib. file increments this by 1 */
745    sav_last_lbf = __last_lbf;
746    __last_lbf = vyp->yfiles[dfi].ydirfnam_ind;
747    got_err = FALSE;
748 
749    if (__open_lbfil(FALSE)) rd_vlibfil(NULL); else got_err = TRUE;
750    __last_lbf = sav_last_lbf;
751    if (got_err) continue;
752    /* if scanned because of a module and still unresolved after scanning */
753    /* need warning - i.e. it is legal to not resolve in name matching */
754    /* module but unrecommended */
755    if (!undefp->msyp->sydecl)
756     {
757      __pv_warn(510,
758       "module %s still unresolved after processing library directory file %s",
759       undefp->msyp->synam, __in_fils[vyp->yfiles[dfi].ydirfnam_ind]);
760     }
761    else break;
762   }
763  /* final step is to free temp undef list */
764  for (undefp = tmphd; undefp != NULL;)
765   {
766    undefp2 = undefp->undefnxt;
767    __my_free((char *) undefp, sizeof(struct undef_t));
768    undefp = undefp2;
769   }
770 }
771 
772 /*
773  * add to tail of undef list that is only singly linked
774  */
add_undef_el(struct sy_t * syp,struct undef_t ** hd,struct undef_t ** tail)775 static struct undef_t *add_undef_el(struct sy_t *syp,
776  struct undef_t **hd, struct undef_t **tail)
777 {
778  struct undef_t *undefp;
779 
780  undefp = (struct undef_t *) __my_malloc(sizeof(struct undef_t));
781  undefp->msyp = syp;
782  undefp->dfi = -1;
783  undefp->modnam = NULL;
784  undefp->undefprev = undefp->undefnxt = NULL;
785  if (*tail == NULL) *hd = *tail = undefp;
786  else { (*tail)->undefnxt = undefp; *tail = undefp; }
787  return(undefp);
788 }
789 
790 /*
791  * preprocess 1 -y library directory - build entry for each file
792  * this builds sorted yfiles array
793  *
794  * notice done only once and saved
795  */
bld_ylb_dirfiles(struct vylib_t * vyp)796 static void bld_ylb_dirfiles(struct vylib_t *vyp)
797 {
798  register int32 last_fi;
799  register int32 numdfils, siz_mydir, bytlen, obytlen;
800  DIR *dirp;
801 #if defined(__SVR4) || defined(__hpux) || defined(__CYGWIN32__) || defined(__FreeBSD__)
802  struct dirent *dp;
803 #else
804  /* all BSD cases and special case interface for non unices */
805  struct direct *dp;
806 #endif
807  struct mydir_t *mdtab;
808 
809  if ((dirp = opendir(vyp->vyu.vyfnam)) == NULL)
810   {
811    __pv_warn(511, "-y directory name %s not found - ignored",
812     vyp->vyu.vydirpth);
813    return;
814   }
815  siz_mydir = 256;
816  bytlen = siz_mydir*sizeof(struct mydir_t);
817  mdtab = (struct mydir_t *) __my_malloc(bytlen);
818  for (last_fi = -1;;)
819   {
820    /* should check error number here for other than end of file */
821    if ((dp = readdir(dirp)) == NULL) break;
822    if (*dp->d_name == '.' && (strcmp(dp->d_name, ".") == 0
823     || strcmp(dp->d_name, "..") == 0)) continue;
824 
825    if (++last_fi >= siz_mydir)
826     {
827      obytlen = bytlen;
828      siz_mydir = 2*siz_mydir;
829      bytlen = siz_mydir*sizeof(struct mydir_t);
830      /* know initial section copied */
831      mdtab = (struct mydir_t *) __my_realloc((char *) mdtab, obytlen, bytlen);
832     }
833    mdtab[last_fi].ydirfnam_ind = 0;
834    mdtab[last_fi].ylbxi = 0;
835    mdtab[last_fi].dirfnam = __pv_stralloc(dp->d_name);
836   }
837  closedir(dirp);
838  numdfils = last_fi + 1;
839 
840  /* AIV 11/11/03 could be an empty directory for -y, free, return */
841  if (numdfils == 0)
842   {
843    __my_free((char *) mdtab, bytlen);
844    __pv_warn(3114, "-y directory %s empty - ignored", vyp->vyu.vydirpth);
845    /* set vy type to 'e' to prevent any further attmpts to rebuild */
846    vyp->vytyp = 'e';
847    return;
848   }
849 
850  /* final step, shrink my directory table back to exact size */
851  if (numdfils != siz_mydir)
852   {
853    obytlen = bytlen;
854    bytlen = numdfils*sizeof(struct mydir_t);
855    mdtab = (struct mydir_t *) __my_realloc((char *) mdtab, obytlen, bytlen);
856   }
857  qsort((char *) mdtab, (word32) numdfils, sizeof(struct mydir_t), fn_cmp);
858  vyp->vyfnam_ind = numdfils;
859  vyp->yfiles = mdtab;
860  __num_ys++;
861 }
862 
863 /*
864  * find index in sorted -y directory yfiles table
865  */
srch_yfiles(char * nam,struct mydir_t * mdtab,word32 numdfiles)866 static int32 srch_yfiles(char *nam, struct mydir_t *mdtab,
867  word32 numdfiles)
868 {
869  int32 l, h;
870  register int32 m, cv;
871 
872  if (numdfiles == 0) return(-1);
873  l = 0; h = numdfiles - 1;
874  for (;;)
875   {
876    m = (l + h)/2;
877    if ((cv = strcmp(mdtab[m].dirfnam, nam)) == 0) return(m);
878    if (cv < 0) l = m + 1; else h = m - 1;
879    if (h < l) break;
880   }
881  return(-1);
882 }
883 
884 /*
885  * module port name comparison routine
886  */
fn_cmp(const void * dp1,const void * dp2)887 static int32 fn_cmp(const void *dp1, const void *dp2)
888 {
889  return(strcmp(((struct mydir_t *) dp1)->dirfnam,
890   ((struct mydir_t *) dp2)->dirfnam));
891 }
892 
893 /*
894  * process a -v or in -y directory file - must try to resolve all modules
895  * know file open and no token read and normal source input env. set
896  * caller must open and close file
897  *
898  *
899  * if lib rescan only resolve one passed undefp and stop when resolved
900  *
901  * LOOKATME _ better here to save byte location from ftell and seek to byte
902  * for defined before used definitions but for now cannot do because do
903  * not have mechanism for saving and restoring compiler directive state?
904  */
rd_vlibfil(struct undef_t * res_undefp)905 static void rd_vlibfil(struct undef_t *res_undefp)
906 {
907  int32 nd_repeat, len, rewind_pass;
908  struct undef_t *hd, *tail, *undefp, *undefp2;
909  struct sy_t *syp;
910  char *chp, savtoken[IDLEN];
911 
912  rewind_pass = 0;
913 again:
914  rewind_pass++;
915  hd = tail = NULL;
916  __get_vtok();
917  if (__toktyp == TEOF)
918   { __pv_fwarn(609, "library file contains no tokens"); return; }
919 
920  for (;;)
921   {
922    /* may be a compiler directive */
923    if (__toktyp >= CDIR_TOKEN_START && __toktyp <= CDIR_TOKEN_END)
924     {
925      __process_cdir();
926      goto nxt_tok;
927     }
928    switch ((byte) __toktyp) {
929     case MACROMODULE:
930      __get_vtok();
931      __finform(423,
932       "macromodules in library not expanded - %s translated as module",
933       __token);
934      goto chk_name;
935     case MODULE:
936      __get_vtok();
937 chk_name:
938      if (__toktyp != ID)
939       {
940        __pv_ferr(707, "in library file, module name expected - %s read",
941         __prt_vtok());
942        /* since error, just try to resynchronize */
943        __vskipto_modend(ENDMODULE);
944        goto nxt_tok;
945       }
946 
947      /* if rescan specific one to resolve skip all but that one */
948      if ((syp = __get_sym(__token, __modsyms)) == NULL || syp->sydecl
949       || (res_undefp != NULL && syp != res_undefp->msyp))
950       {
951        /* must save module name - skip overwrites */
952        strcpy(savtoken, __token);
953        if (!__vskipto_modend(ENDMODULE))
954         {
955          __pv_ferr(767,
956          "syntax error in skipped (defined or not referenced) library module %s",
957           __token);
958          goto nxt_tok;
959         }
960 try_add_unref:
961        /* if symbol never referenced up to here may be define before use */
962        /* so need to add to list in case reference nearer end */
963        /* for rescan mode, this inhibits any rescanning */
964        if (syp == NULL && !__lib_rescan)
965         {
966          undefp = add_undef_el((struct sy_t *) NULL, &hd, &tail);
967          chp = __pv_stralloc(savtoken);
968          undefp->modnam = chp;
969         }
970        goto nxt_tok;
971       }
972 
973      /* notice name token read - also undef_mods not changed */
974      if (__lib_verbose)
975       __cv_msg("  Compiling library module (%s).\n", __token);
976      /* know error here will cause skipping to file level thing */
977      if (!__rd_moddef(NULL, FALSE)) goto nxt_tok;
978      /* when reading source this was set only if in cell define region */
979      /* now turn on (maybe again) if all library modules are cells */
980      /* dummy itstk empty here but if good module read mark as cell */
981      if (__lib_are_cells && __last_libmdp != NULL)
982       {
983        __last_libmdp->m_iscell = TRUE;
984        __design_has_cells = TRUE;
985       }
986      __last_libmdp = NULL;
987      /* know to get here 1 more resolved */
988      __cur_passres++;
989      if (__undef_mods <= 0 || __lib_rescan) return;
990      break;
991 
992     case PRIMITIVE:
993      __get_vtok();
994      if (__toktyp != ID)
995       {
996        __pv_ferr(708, "library file udp primitive name expected - %s read",
997 	__prt_vtok());
998        /* since err, just try to skip to end primitive */
999        __vskipto_modend(ENDPRIMITIVE);
1000        goto nxt_tok;
1001       }
1002      /* if rescan specific one to resolve skip all but that one */
1003      if ((syp = __get_sym(__token, __modsyms)) == NULL || syp->sydecl
1004       || (res_undefp != NULL && syp != res_undefp->msyp))
1005       {
1006        /* must save module name - skip overwrites */
1007        strcpy(savtoken, __token);
1008        if (!__vskipto_modend(ENDPRIMITIVE))
1009         {
1010          __pv_ferr(702,
1011 	  "syntax error in skipped (defined or not referenced) library primitive %s",
1012           __token);
1013          goto nxt_tok;
1014         }
1015        goto try_add_unref;
1016       }
1017      /* notice name token read */
1018      if (__lib_verbose)
1019       __cv_msg("  Compiling library udp primitive (%s).\n", __token);
1020      if (!__rd_udpdef(NULL)) goto nxt_tok;
1021      /* if all modules resolved, nothing more to do */
1022      __cur_passres++;
1023      if (__undef_mods <= 0 || __lib_rescan) return;
1024      break;
1025     default:
1026      __pv_ferr(709,
1027      "library file module, primitive or directive expected - %s read",
1028       __prt_vtok());
1029      /* here just ignores extra semicolons */
1030      if (__toktyp != SEMI) __vskipto2_modend(ENDMODULE, ENDPRIMITIVE);
1031    }
1032 nxt_tok:
1033    /* why checking this twice */
1034    if (__toktyp == TEOF)
1035     {
1036 chk_ifdef:
1037      if (__in_ifdef_level != 0)
1038       {
1039        __pv_err(924, "last `ifdef unterminated in libary file %s",
1040         __cur_fnam);
1041       }
1042      break;
1043     }
1044    __get_vtok();
1045    if (__toktyp == TEOF) goto chk_ifdef;
1046  }
1047  /* need to determine if any of the skipped modules or udp's now undefined */
1048  nd_repeat = FALSE;
1049  for (undefp = hd; undefp != NULL; undefp = undefp->undefnxt)
1050   {
1051    /* SJM 06/03/02 - change so undef list no longer shares undefprev */
1052    chp = (char *) undefp->modnam;
1053    /* DBG remove --- */
1054    if (chp == NULL) __misc_terr(__FILE__, __LINE__);
1055    /* --- */
1056 
1057    if ((syp = __get_sym(chp, __modsyms)) != NULL && !syp->sydecl)
1058     {
1059      nd_repeat = TRUE;
1060      if (!__lib_verbose) break;
1061      __cv_msg(
1062       "  Rereading %s library element %s defined before use (pass %d).\n",
1063       __cur_fnam, syp->synam, rewind_pass);
1064     }
1065   }
1066 
1067  /* go through freeing list */
1068  for (undefp = hd; undefp != NULL;)
1069   {
1070    undefp2 = undefp->undefnxt;
1071    /* LOOKATME - think will always be set here */
1072    if (undefp->modnam != NULL)
1073     {
1074      chp = undefp->modnam;
1075      len = strlen(chp);
1076      __my_free(chp, len + 1);
1077     }
1078    __my_free((char *) undefp, sizeof(struct undef_t));
1079    undefp = undefp2;
1080   }
1081  if (nd_repeat)
1082   {
1083    __my_rewind(__in_s);
1084    /* in case hit eof with push back make sure reads 1st token */
1085    __lasttoktyp = UNDEF;
1086    __lin_cnt = 1;
1087    __file_just_op = TRUE;
1088    goto again;
1089   }
1090 }
1091 
1092 /*
1093  * try to open the next library file and repl. top of stack with its info
1094  * file must be openable and have contents
1095  * return F on no success
1096  * in fils of last lbf must be filled with file name
1097  * since know last_lbf > last_inf - on EOF get_vtok will resturn to caller
1098  */
__open_lbfil(int32 is_dir)1099 extern int32 __open_lbfil(int32 is_dir)
1100 {
1101  /* if not first time, close previous file */
1102  if (__visp->vi_s != NULL) { __my_fclose(__visp->vi_s); __visp->vi_s = NULL; }
1103  /* know called with last_lbf index of file to process */
1104  __cur_fnam = __in_fils[__last_lbf];
1105  if ((__in_s = __tilde_fopen(__cur_fnam, "r")) == NULL)
1106   {
1107    if (is_dir) strcpy(__xs, " directory"); else strcpy(__xs, "");
1108    __pv_err(710, "cannot open Verilog library%s file %s - skipped", __xs,
1109     __cur_fnam);
1110    return(FALSE);
1111   }
1112  if (feof(__in_s))
1113   {
1114    __pv_warn(512, "Verilog library file %s empty", __cur_fnam);
1115    return(FALSE);
1116   }
1117  /* whenever open new file must discard pushed back */
1118  __lasttoktyp = UNDEF;
1119  __visp->vi_s = __in_s;
1120  __visp->vifnam_ind = __last_lbf;
1121  __cur_fnam_ind = __last_lbf;
1122  __cur_fnam = __in_fils[__cur_fnam_ind];
1123  __lin_cnt = 1;
1124  __file_just_op = TRUE;
1125  if (__lib_verbose)
1126   {
1127    if (is_dir)
1128     __cv_msg("  Opening library directory file \"%s\".\n", __cur_fnam);
1129    else __cv_msg("  Scanning library file \"%s\".\n", __cur_fnam);
1130   }
1131  return(TRUE);
1132 }
1133 
1134 /*
1135  * RESCAN LIBRARY RESOLUTION ROUTINES
1136  */
1137 
1138 /*
1139  * process library to attempt to resolve all unresolved libraries
1140  * only called if unresolved modules/udps remain
1141  *
1142  * BEWARE - must not free memory of linked out resolved undefp for
1143  * 2 reasons: 1) need it for error msgs, 2) need next field to move in list
1144  */
rescan_process_lib(void)1145 static void rescan_process_lib(void)
1146 {
1147  register struct undef_t *undefp;
1148  register struct vylib_t *vyp;
1149  struct undef_t *sav_undefhd;
1150  struct sy_t *syp;
1151  int32 sav_last_lbf, passi;
1152 
1153  if (__lib_verbose)
1154   {
1155    __cv_msg("\n  Begin rescan mode library resolution (%d undefined).\n",
1156     __undef_mods);
1157   }
1158 
1159  /* goto through unresolved resolving one per pass */
1160  /* resolution of one may add other to end, but next field will */
1161  /* be right for new */
1162  passi = 1;
1163  for (undefp = __undefhd; undefp != NULL; passi++)
1164   {
1165    /* AIV 10/10/03 - undefhd may be removed and then new undefhd added as */
1166    /* unresolved so must save and replace if changed */
1167    sav_undefhd = __undefhd;
1168 
1169    if (passi > 1) __rescanning_lib = TRUE;
1170 
1171    if (__lib_verbose)
1172     {
1173      syp = undefp->msyp;
1174      __cv_msg("\n  Resolving %s (first reference %s)(pass %d)\n",
1175       syp->synam, __bld_lineloc(__xs, syp->syfnam_ind, syp->sylin_cnt), passi);
1176     }
1177    __cur_passres = 0;
1178    for (vyp = __vyhdr; vyp != NULL; vyp = vyp->vynxt)
1179     {
1180      /* AIV 11/11/03 - if -y dir is empty changed to 'e' so do nothing */
1181      /* this handles empty directories for rescanning */
1182      if (vyp->vytyp == 'e') continue;
1183 
1184      if (vyp->vytyp == 'y')
1185       {
1186        if (vyp->yfiles == NULL) bld_ylb_dirfiles(vyp);
1187 
1188        /* AIV 11/11/03 - if -y dir is empty made 'e' and must do nothing */
1189        if (vyp->vytyp == 'e') continue;
1190 
1191        rescan_resolve_from_ydir(vyp, undefp);
1192        if (__cur_passres == 0) continue;
1193 
1194        /* DBG remove -- */
1195        if (__cur_passres != 1) __misc_terr(__FILE__, __LINE__);
1196        /* --- */
1197        goto resolve_nxt;
1198       }
1199 
1200      /* add or reuse -v library file to in_fils */
1201      if (vyp->vyfnam_ind == 0)
1202       {
1203        /* this dies if >64k */
1204        if (++__last_lbf >= __siz_in_fils) __grow_infils(__last_lbf);
1205        vyp->vyfnam_ind = __last_lbf;
1206        __in_fils[__last_lbf] = __pv_stralloc(vyp->vyu.vyfnam);
1207       }
1208 
1209      sav_last_lbf = __last_lbf;
1210      __last_lbf = vyp->vyfnam_ind;
1211      /* know this will leave undef_mods with correct value */
1212      if (__open_lbfil(FALSE)) rd_vlibfil(undefp);
1213      __last_lbf = sav_last_lbf;
1214      if (__cur_passres == 0) continue;
1215      /* DBG remove -- */
1216      if (__cur_passres != 1) __misc_terr(__FILE__, __LINE__);
1217      /* --- */
1218      goto resolve_nxt;
1219     }
1220    __pv_err(706,
1221     "lib rescan module %s unresolved after all libaries searched - skipping to next",
1222       undefp->msyp->synam);
1223 
1224 resolve_nxt:;
1225    /* AIV 10/07/03 - if new head it is "next" else move one down list */
1226    if (sav_undefhd != __undefhd) undefp = __undefhd;
1227    else undefp = undefp->undefnxt;
1228   }
1229 }
1230 
1231 /*
1232  * rescan resolve one current unresolved references from a library dir
1233  * simpler than non rescan cases because at most one resolved
1234  *
1235  * algorithm is:
1236  * 1) go through one current unresolved and find all files that match suffix
1237  *    and add to list
1238  * 2) then read and scan all files for the one unresolved now working on
1239  */
rescan_resolve_from_ydir(struct vylib_t * vyp,struct undef_t * undefp)1240 static void rescan_resolve_from_ydir(struct vylib_t *vyp,
1241  struct undef_t *undefp)
1242 {
1243  register int32 lbxi;
1244  int32 dfi, sav_last_lbf, got_err;
1245  struct undef_t *tmpundefp, *undefp2, *tmphd, *tmptail;
1246  char fnam[IDLEN], stem[IDLEN];
1247 
1248  /* build stem that gives current path to directory */
1249  sprintf(stem, "%s/", vyp->vyu.vydirpth);
1250  /* case 1: no lbext - module name must exactly match file name */
1251  tmphd = tmptail = NULL;
1252  if (__last_lbx == -1)
1253   {
1254    if ((dfi = srch_yfiles(undefp->msyp->synam, vyp->yfiles, vyp->vyfnam_ind))
1255     != -1)
1256     {
1257      /* add to tmp list since parsing changes __undefhd list */
1258      tmpundefp = add_undef_el(undefp->msyp, &tmphd, &tmptail);
1259      tmpundefp->dfi = dfi;
1260      vyp->yfiles[dfi].ylbxi = 0;
1261     }
1262   }
1263  else
1264   {
1265    /* case 2: must add lbext to module name and see if matches */
1266    /* build temporary list of all */
1267    for (lbxi = 0; lbxi <= __last_lbx; lbxi++)
1268     {
1269      sprintf(fnam, "%s%s", undefp->msyp->synam, __lbexts[lbxi]);
1270      if ((dfi = srch_yfiles(fnam, vyp->yfiles, vyp->vyfnam_ind)) == -1)
1271       continue;
1272 
1273      /* add to tmp list since parsing changes __undefhd list */
1274      tmpundefp = add_undef_el(undefp->msyp, &tmphd, &tmptail);
1275      tmpundefp->dfi = dfi;
1276      vyp->yfiles[dfi].ylbxi = lbxi;
1277      /* when found, from precedence rules must stop looking */
1278      break;
1279     }
1280   }
1281  /* go through temp (will always be exactly one long) list reading file */
1282  /* DBG remove -- */
1283  if (tmphd != NULL && tmphd->undefnxt != NULL)
1284   __misc_terr(__FILE__, __LINE__);
1285  /* --- */
1286  for (undefp = tmphd; undefp != NULL; undefp = undefp->undefnxt)
1287   {
1288    dfi = undefp->dfi;
1289    if (vyp->yfiles[dfi].ydirfnam_ind == 0)
1290     {
1291      /* this dies if >64k */
1292      if (++__last_lbf >= __siz_in_fils) __grow_infils(__last_lbf);
1293      vyp->yfiles[dfi].ydirfnam_ind = __last_lbf;
1294      if (__last_lbx == -1) sprintf(fnam, "%s%s", stem, undefp->msyp->synam);
1295      else
1296       {
1297        lbxi = vyp->yfiles[dfi].ylbxi;
1298        sprintf(fnam, "%s%s%s", stem, undefp->msyp->synam, __lbexts[lbxi]);
1299       }
1300      __in_fils[__last_lbf] = __pv_stralloc(fnam);
1301     }
1302    /* notice each lib. file increments this by 1 */
1303    sav_last_lbf = __last_lbf;
1304    __last_lbf = vyp->yfiles[dfi].ydirfnam_ind;
1305    got_err = FALSE;
1306 
1307    if (__open_lbfil(FALSE)) rd_vlibfil(undefp); else got_err = TRUE;
1308    __last_lbf = sav_last_lbf;
1309    if (got_err) continue;
1310    /* if scanned because of a module and still unresolved after scanning */
1311    /* need warning - i.e. it is legal to not resolve in name matching */
1312    /* module but unrecommended */
1313    if (!undefp->msyp->sydecl)
1314     {
1315      __pv_warn(510,
1316       "module %s still unresolved after processing library directory file %s",
1317       undefp->msyp->synam, __in_fils[vyp->yfiles[dfi].ydirfnam_ind]);
1318     }
1319    else break;
1320   }
1321  /* final step is to free temp undef list */
1322  for (undefp = tmphd; undefp != NULL;)
1323   {
1324    undefp2 = undefp->undefnxt;
1325    __my_free((char *) undefp, sizeof(struct undef_t));
1326    undefp = undefp2;
1327   }
1328 }
1329 
1330 /*
1331  * PRELIMINARY FIXUP ROUTINES USUALLY FORMAT CHANGES
1332  */
1333 
1334 /*
1335  * routine to free all allocated tnode blks from unfrozen part of symtabs
1336  */
free_tnblks(void)1337 static void free_tnblks(void)
1338 {
1339  register struct tnblk_t *tnbp, *tnbp2;
1340 
1341  /* free all cell pin blks since ncomp form now gone */
1342  for (tnbp = __hdr_tnblks; tnbp != NULL;)
1343   {
1344    tnbp2 = tnbp->tnblknxt;
1345    __my_free((char *) tnbp->tnblks, BIG_ALLOC_SIZE);
1346    __my_free((char *) tnbp, sizeof(struct tnblk_t));
1347    tnbp = tnbp2;
1348   }
1349  __hdr_tnblks = NULL;
1350 }
1351 
1352 /*
1353  * change all module and task parameter lists to table from list
1354  *
1355  * also sets mprmnum and tprmnum so know size of tables
1356  * after completion, param nu2 field nnxt field no longed needed
1357  */
chg_params_to_tab(void)1358 static void chg_params_to_tab(void)
1359 {
1360  register int32 pi;
1361  register struct net_t *pnp, *pnp2;
1362  register struct mod_t *mdp;
1363  int32 pnum;
1364  struct net_t *nptab;
1365  struct task_t *tskp;
1366  struct spfy_t *spfyp;
1367 
1368  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1369   {
1370    __push_wrkitstk(mdp, 0);
1371 
1372    /* first module params */
1373    pnum = cnt_prms(mdp->mprms);
1374    if (pnum != 0)
1375     {
1376      nptab = (struct net_t *) __my_malloc(pnum*sizeof(struct net_t));
1377      pi = 0;
1378      for (pnp = mdp->mprms; pnp != NULL; pnp = pnp->nu2.nnxt, pi++)
1379       {
1380        pnp2 = &(nptab[pi]);
1381        *pnp2 = *pnp;
1382        /* symbol points back to net - because copied to table change ptr */
1383        pnp2->nsym->el.enp = pnp2;
1384        /* ptr filds in pnp unique so will just get moved to new */
1385        /* except must nil out new table pnp2 nu2 because needed for saving */
1386        pnp2->nu2.wp = NULL;
1387       }
1388      mdp->mprmnum = pnum;
1389      free_param_listform(mdp->mprms);
1390      mdp->mprms = nptab;
1391     }
1392 
1393    /* first module LOCAL params */
1394    pnum = cnt_prms(mdp->mlocprms);
1395    if (pnum != 0)
1396     {
1397      nptab = (struct net_t *) __my_malloc(pnum*sizeof(struct net_t));
1398      pi = 0;
1399      for (pnp = mdp->mlocprms; pnp != NULL; pnp = pnp->nu2.nnxt, pi++)
1400       {
1401        pnp2 = &(nptab[pi]);
1402        *pnp2 = *pnp;
1403        pnp2->nsym->el.enp = pnp2;
1404        pnp2->nu2.wp = NULL;
1405       }
1406      mdp->mlocprmnum = pnum;
1407      free_param_listform(mdp->mlocprms);
1408      mdp->mlocprms = nptab;
1409     }
1410 
1411    /* next parameters in each task */
1412    for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
1413     {
1414      if ((pnum = cnt_prms(tskp->tsk_prms)) != 0)
1415       {
1416        nptab = (struct net_t *) __my_malloc(pnum*sizeof(struct net_t));
1417        pi = 0;
1418        for (pnp = tskp->tsk_prms; pnp != NULL; pnp = pnp->nu2.nnxt, pi++)
1419         {
1420          pnp2 = &(nptab[pi]);
1421          *pnp2 = *pnp;
1422          /* symbol points back to net - because copied to table change ptr */
1423          pnp2->nsym->el.enp = pnp2;
1424          /* ptr filds in pnp uniue so will just get moved to new */
1425          /* except must nil out new table pnp2 nu2 because needed for saving */
1426          pnp2->nu2.wp = NULL;
1427         }
1428        tskp->tprmnum = pnum;
1429        free_param_listform(tskp->tsk_prms);
1430        tskp->tsk_prms = nptab;
1431       }
1432      /* do the task LOCAL parameters as well */
1433      if ((pnum = cnt_prms(tskp->tsk_locprms)) != 0)
1434       {
1435        nptab = (struct net_t *) __my_malloc(pnum*sizeof(struct net_t));
1436        pi = 0;
1437        for (pnp = tskp->tsk_locprms; pnp != NULL; pnp = pnp->nu2.nnxt, pi++)
1438         {
1439          pnp2 = &(nptab[pi]);
1440          *pnp2 = *pnp;
1441          /* symbol points back to net - because copied to table change ptr */
1442          pnp2->nsym->el.enp = pnp2;
1443          /* ptr filds in pnp uniue so will just get moved to new */
1444          /* except must nil out new table pnp2 nu2 because needed for saving */
1445          pnp2->nu2.wp = NULL;
1446         }
1447        tskp->tlocprmnum = pnum;
1448        free_param_listform(tskp->tsk_locprms);
1449        tskp->tsk_locprms = nptab;
1450       }
1451     }
1452    /* finally specparams */
1453    if ((spfyp = mdp->mspfy) == NULL) goto nxt_mod;
1454    if ((pnum = cnt_prms(spfyp->msprms)) == 0) goto nxt_mod;
1455 
1456    nptab = (struct net_t *) __my_malloc(pnum*sizeof(struct net_t));
1457    pi = 0;
1458    for (pnp = spfyp->msprms; pnp != NULL; pnp = pnp->nu2.nnxt, pi++)
1459     {
1460      pnp2 = &(nptab[pi]);
1461      *pnp2 = *pnp;
1462      /* symbol points back to net - because copied to table change ptr */
1463      pnp2->nsym->el.enp = pnp2;
1464      /* ptr filds in pnp unique so will just get moved to new */
1465      /* except must nil out new table pnp2 nu2 because needed for saving */
1466      pnp2->nu2.wp = NULL;
1467     }
1468    spfyp->sprmnum = pnum;
1469    free_param_listform(spfyp->msprms);
1470    spfyp->msprms = nptab;
1471 nxt_mod:
1472    __pop_wrkitstk();
1473   }
1474 
1475 }
1476 
1477 /*
1478  * count params in list form
1479  */
cnt_prms(struct net_t * np)1480 static int32 cnt_prms(struct net_t *np)
1481 {
1482  register struct net_t *parm_np;
1483  int32 pnum;
1484 
1485  for (pnum = 0, parm_np = np; parm_np != NULL; parm_np = parm_np->nu2.nnxt)
1486   { pnum++; }
1487  return(pnum);
1488 }
1489 
1490 /*
1491  * free parameter list form
1492  *
1493  * no freeing of ncomp or expressions pointed to from inside since moved
1494  * to table form element
1495  */
free_param_listform(struct net_t * parm_np)1496 static void free_param_listform(struct net_t *parm_np)
1497 {
1498  register struct net_t *pnp, *pnp2;
1499 
1500  for (pnp = parm_np; pnp != NULL;)
1501   {
1502    pnp2 = pnp->nu2.nnxt;
1503    __my_free((char *) pnp, sizeof(struct net_t));
1504    pnp = pnp2;
1505   }
1506 }
1507 
1508 /*
1509  * ROUTINES TO SEPARATE CELLS INTO GATES AND INSTANCES
1510  */
1511 
1512 /*
1513  * separate module gate and insts into separate lists
1514  * contas already separated by here
1515  * relocate, free cell_t, and build array form port lists
1516  *
1517  * also checks for unnamed module instances and number cells with type range
1518  * could save some space by make insts and gates array of thing rather
1519  * than array of ptrs to things
1520  */
sep_mdgates(void)1521 static void sep_mdgates(void)
1522 {
1523  register struct cell_t *cp;
1524  int32 modinum, modgnum, ii, gi, nbytes;
1525  struct mod_t *mdp;
1526  struct inst_t *iptab;
1527  struct gate_t *gptab;
1528 
1529  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1530   {
1531    __push_wrkitstk(mdp, 0);
1532 
1533    /* first allocate array of pointers to instances */
1534    modinum = count_minum_and_mgnum(&modgnum, mdp);
1535    if (modinum != 0)
1536     {
1537      nbytes = modinum*sizeof(struct inst_t);
1538      iptab = (struct inst_t *) __my_malloc(nbytes);
1539     }
1540    else iptab = NULL;
1541    if (modgnum != 0)
1542     {
1543      nbytes = modgnum*sizeof(struct gate_t);
1544      gptab = (struct gate_t *) __my_malloc(nbytes);
1545     }
1546    else gptab = NULL;
1547 
1548    ii = gi = -1;
1549    for (cp = mdp->mcells; cp != NULL; cp = cp->cnxt)
1550     {
1551      /* if not declared error above can still get here */
1552      /* but undeclared udp symbol with always be actually undcl mod */
1553      /* case 1: udp */
1554      if (cp->cmsym->sytyp == SYM_UDP)
1555       {
1556        cellrep_to_gate(cp, &(gptab[++gi]));
1557        if (cp->cx1 != NULL) bld_giarr(mdp, gi, cp, modgnum);
1558        continue;
1559       }
1560      /* case 2: built in primitive */
1561      if (cp->cmsym->sytyp == SYM_PRIM)
1562       {
1563        /* notice pullup becomes gate but can have only 1 (or more) ports */
1564        cellrep_to_gate(cp, &(gptab[++gi]));
1565        if (cp->cx1 != NULL) bld_giarr(mdp, gi, cp, modgnum);
1566        continue;
1567       }
1568      /* case 3: instance */
1569      if (!cp->c_named)
1570       {
1571        __gferr(731, cp->csym->syfnam_ind, cp->csym->sylin_cnt,
1572         "required module instance name missing (type is %s)",
1573         cp->cmsym->synam);
1574        cp->c_named = FALSE;
1575       }
1576      if (cp->cmsym != NULL && cp->cmsym->sydecl)
1577       {
1578        cellrep_to_inst(cp, &(iptab[++ii]));
1579        if (cp->cx1 != NULL) bld_miarr(mdp, ii, cp, modinum);
1580       }
1581     }
1582    mdp->minum = modinum;
1583    mdp->minsts = iptab;
1584    mdp->mgnum = modgnum;
1585    mdp->mgates = gptab;
1586    mdp->mcells = NULL;
1587 
1588    __pop_wrkitstk();
1589   }
1590 }
1591 
1592 /*
1593  * count number of instances in module
1594  * need array that is parallel to itree array for instances so must
1595  * count in order to allocate before building array
1596  */
count_minum_and_mgnum(int32 * gnum,struct mod_t * mdp)1597 static int32 count_minum_and_mgnum(int32 *gnum, struct mod_t *mdp)
1598 {
1599  register struct cell_t *cp;
1600  int32 inum;
1601  struct sy_t *syp;
1602 
1603  for (inum = *gnum = 0, cp = mdp->mcells; cp != NULL; cp = cp->cnxt)
1604   {
1605    syp = cp->cmsym;
1606    if (syp == NULL || !syp->sydecl) continue;
1607 
1608    if (syp->sytyp == SYM_UDP || syp->sytyp == SYM_PRIM) (*gnum)++;
1609    else inum++;
1610   }
1611  return(inum);
1612 }
1613 
1614 /*
1615  * convert a syntax analysis format general cell struct to a sim gate struct
1616  * cell pin list changed to expression list later
1617  */
cellrep_to_gate(struct cell_t * cp,struct gate_t * gp)1618 static void cellrep_to_gate(struct cell_t *cp, struct gate_t *gp)
1619 {
1620  register int32 pi;
1621  register struct cell_pin_t *cpp;
1622  int32 pnum, nbytes, all_named;
1623  char s1[RECLEN];
1624 
1625  /* how is a port connect lost */
1626  if ((pnum = cnt_gateprts(cp)) == 0L)
1627   {
1628    __gferr(732, cp->csym->syfnam_ind, cp->csym->sylin_cnt,
1629     "%s %s illegal - at least one gate required", __to_sytyp(__xs,
1630     cp->cmsym->sytyp), cp->cmsym->synam);
1631   }
1632  /* must fit in 16 bits */
1633  if (pnum >= 0x3fffL)
1634   {
1635    __gferr(732, cp->csym->syfnam_ind, cp->csym->sylin_cnt,
1636     "%s %s has too many terminals (%d)", __to_sytyp(__xs, cp->cmsym->sytyp),
1637     cp->cmsym->synam, 0x3fffL);
1638    pnum = 0x3fffL;
1639   }
1640 
1641  /* notice symbol type is still SYM_I here */
1642  gp->gsym = cp->csym;
1643  gp->gsym->el.egp = gp;
1644  gp->gmsym = cp->cmsym;
1645  gp->gpnum = pnum;
1646  gp->g_hasst = (cp->c_hasst) ? TRUE : FALSE;
1647  gp->g_stval = cp->c_stval;
1648  gp->g_delrep = DT_CMPLST;
1649  gp->g_gone = FALSE;
1650  gp->g_pdst = FALSE;
1651  if (gp->gmsym->sytyp == SYM_UDP)
1652   { gp->g_class = GC_UDP; gp->gsym->sytyp = SYM_PRIM; }
1653  else
1654   {
1655    gp->g_class = gp->gmsym->el.eprimp->gclass;
1656    gp->gsym->sytyp = SYM_PRIM;
1657   }
1658 
1659  gp->schd_tevs = NULL;
1660  /* since before cells numbered non zero means unnamed */
1661  if (!cp->c_named) gp->g_unam = TRUE; else gp->g_unam = FALSE;
1662 
1663  gp->g_du.pdels = NULL;
1664  if (cp->c_nparms != NULL)
1665   {
1666    /* explicit parameter name form illegal for udps or gates */
1667    /* T returned if some named */
1668    if (pndparams_explicit(cp->c_nparms, &all_named))
1669     {
1670      if (all_named) strcpy(s1, "all"); else strcpy(s1, "some");
1671      __gferr(809, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
1672       "%s explicit .[parameter name]([expr]) # delay forms illegal for %s %s",
1673       s1, __to_sytyp(__xs, gp->gmsym->sytyp), gp->gmsym->synam);
1674      __free_namedparams(cp->c_nparms);
1675      gp->g_du.pdels = NULL;
1676     }
1677    else
1678     {
1679      gp->g_du.pdels = bld_gate_paramlst(cp->c_nparms);
1680      __free_namedparams(cp->c_nparms);
1681      cp->c_nparms = NULL;
1682     }
1683   }
1684  gp->gstate.wp = NULL;
1685 
1686  /* just move ptr since not shared */
1687  gp->gattrs = cp->cattrs;
1688 
1689  nbytes = pnum*sizeof(struct expr_t *);
1690  /* SJM 05/05/03 - from previous syntax errors where can't recover */
1691  /* this may be nil, but since errors still works */
1692  if (pnum > 0) gp->gpins = (struct expr_t **) __my_malloc(nbytes);
1693  else gp->gpins = NULL;
1694  gp->gchg_func = NULL;
1695  for (cpp = cp->cpins, pi = 0; cpp != NULL; pi++, cpp = cpp->cpnxt)
1696   {
1697    /* this should always be at least 'bx by here */
1698    if (cpp->pnam != NULL)
1699     {
1700      __gferr(733, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
1701       "explicit port connection illegal for %s %s",
1702       __to_sytyp(__xs, gp->gmsym->sytyp), gp->gmsym->synam);
1703      /* all freeing later */
1704     }
1705    /* this copies expr. (not freed) from cpins so when entire */
1706    /* cpin blocks freed later, no interlinking */
1707    if (pi < pnum) gp->gpins[pi] = cpp->cpxnd;
1708   }
1709 }
1710 
1711 /*
1712  * return T if param name list has any explicit named forms
1713  * if returns T, also sets flag if all are explicit form
1714  */
pndparams_explicit(struct namparam_t * npmphdr,int32 * all_named)1715 static int32 pndparams_explicit(struct namparam_t *npmphdr, int32 *all_named)
1716 {
1717  register struct namparam_t *npmp;
1718  int32 has_named, all2_named;
1719 
1720  *all_named = FALSE;
1721  has_named = FALSE;
1722  all2_named = TRUE;
1723  for (npmp = npmphdr; npmp != NULL; npmp = npmp->nprmnxt)
1724   {
1725    if (npmp->pnam != NULL) has_named = TRUE;
1726    else all2_named = FALSE;
1727   }
1728  if (has_named) *all_named = all2_named;
1729  return(has_named);
1730 }
1731 
1732 /*
1733  * build a delay parameter list from a named parameter list for gates
1734  *
1735  * know all unnamed comma separated form list or will not be called
1736  * also know delay list with at least one element present or not called
1737  */
bld_gate_paramlst(struct namparam_t * npmphdr)1738 static struct paramlst_t *bld_gate_paramlst(struct namparam_t *npmphdr)
1739 {
1740  register struct namparam_t *npmp;
1741  int32 pi;
1742  struct paramlst_t *nplphdr, *nplp, *last_nplp;
1743 
1744  nplphdr = last_nplp = NULL;
1745  for (pi = 0, npmp = npmphdr; npmp != NULL; npmp = npmp->nprmnxt, pi++)
1746   {
1747    if (npmp->pxndp->optyp == OPEMPTY)
1748     {
1749      __pv_ferr(1190,
1750       "empty ,, form primitive pound delay value illegal (pos. %d)", pi + 1);
1751      continue;
1752     }
1753    nplp = __alloc_pval();
1754    nplp->plxndp = npmp->pxndp;
1755    npmp->pxndp = NULL;
1756    if (last_nplp == NULL) nplphdr = nplp; else last_nplp->pmlnxt = nplp;
1757    nplp->pmlnxt = NULL;
1758    last_nplp = nplp;
1759   }
1760  if (nplphdr == NULL)
1761   {
1762    __pv_ferr(1095, "empty primitive #() delay expression illegal");
1763   }
1764  return(nplphdr);
1765 }
1766 
1767 /*
1768  * build parallel array to mgates index element
1769  * only called if array form has range expr
1770  */
bld_giarr(struct mod_t * mdp,int32 gi,struct cell_t * cp,int32 mgnum)1771 static void bld_giarr(struct mod_t *mdp, int32 gi, struct cell_t *cp, int32 mgnum)
1772 {
1773  int32 i;
1774  struct giarr_t *giap;
1775 
1776  if (mdp->mgarr == NULL)
1777   {
1778    mdp->mgarr = (struct giarr_t **) __my_malloc(mgnum*sizeof(struct giarr_t *));
1779    for (i = 0; i < mgnum; i++) mdp->mgarr[i] = NULL;
1780   }
1781  mdp->mgarr[gi] = (struct giarr_t *)__my_malloc(sizeof(struct giarr_t));
1782  giap = mdp->mgarr[gi];
1783  init_giarr(giap);
1784  giap->giax1 = cp->cx1;
1785  giap->giax2 = cp->cx2;
1786  __design_gi_arrays = TRUE;
1787 }
1788 
1789 /*
1790  * initialize a giarr
1791  */
init_giarr(struct giarr_t * giap)1792 static void init_giarr(struct giarr_t *giap)
1793 {
1794  giap->gia_xpnd = FALSE;
1795  giap->gia_rng_has_pnd = FALSE;
1796  giap->giax1 = giap->giax2 = NULL;
1797  giap->gia1 = giap->gia2 = -1;
1798  giap->gia_bi = -1;
1799  giap->giapins = NULL;
1800  giap->gia_base_syp = NULL;
1801 }
1802 
1803 /*
1804  * build parallel array to marrs index element
1805  * only called if module has arrays of insts
1806  */
bld_miarr(struct mod_t * mdp,int32 ii,struct cell_t * cp,int32 minum)1807 static void bld_miarr(struct mod_t *mdp, int32 ii, struct cell_t *cp, int32 minum)
1808 {
1809  int32 i;
1810  struct giarr_t *giap;
1811 
1812  if (mdp->miarr == NULL)
1813   {
1814    mdp->miarr = (struct giarr_t **) __my_malloc(minum*sizeof(struct giarr_t *));
1815    for (i = 0; i < minum; i++) mdp->miarr[i] = NULL;
1816   }
1817  mdp->miarr[ii] = (struct giarr_t *) __my_malloc(sizeof(struct giarr_t));
1818  giap = mdp->miarr[ii];
1819  init_giarr(giap);
1820  giap->giax1 = cp->cx1;
1821  giap->giax2 = cp->cx2;
1822  __design_gi_arrays = TRUE;
1823 }
1824 
1825 /*
1826  * count the number of ports a gate has
1827  */
cnt_gateprts(struct cell_t * cp)1828 static int32 cnt_gateprts(struct cell_t *cp)
1829 {
1830  register struct cell_pin_t *cpp;
1831  int32 pnum;
1832 
1833  for (pnum = 0, cpp = cp->cpins; cpp != NULL; cpp = cpp->cpnxt) pnum++;
1834  return(pnum);
1835 }
1836 
1837 /*
1838  * convert a syntax analysis format general cell struct to a sim gate struct
1839  *
1840  * by here know module declared params converted to table from list
1841  * this also checked passed instance # params constant expressions
1842  */
cellrep_to_inst(struct cell_t * cp,struct inst_t * ip)1843 static void cellrep_to_inst(struct cell_t *cp, struct inst_t *ip)
1844 {
1845  /* if module not defined, nothing to do */
1846  if (cp->c_hasst)
1847   {
1848    __gferr(734, cp->csym->syfnam_ind, cp->csym->sylin_cnt,
1849     "module instance %s type %s strength specification illegal",
1850     cp->csym->synam, cp->cmsym->synam);
1851   }
1852 
1853  init_inst(ip);
1854 
1855  ip->isym = cp->csym;
1856  ip->isym->el.eip = ip;
1857  ip->imsym = cp->cmsym;
1858  ip->pprm_explicit = FALSE;
1859  /* instance numbers assigned later because splitting can change */
1860  /* convert named param list to parallel table of pound param exprs */
1861 
1862  /* must set instance type flags before processing pound params */
1863  ip->i_iscell = (cp->c_iscell) ? TRUE : FALSE;
1864  ip->i_pndsplit = FALSE;
1865 
1866  /* this also checks pound paremeter's since know each params loc. */
1867  if (cp->c_nparms == NULL) ip->ipxprtab = NULL;
1868  else ip->ipxprtab = inst_nparms_to_xtab(cp->c_nparms, ip);
1869 
1870  ip->ip_explicit = (cp->cp_explicit) ? TRUE : FALSE;
1871 
1872  /* count instances with pound params */
1873  if (ip->ipxprtab != NULL) __num_inst_pndparams++;
1874 
1875  /* just move ptr since not shared */
1876  ip->iattrs = cp->cattrs;
1877  /* if has instance attributes combine mod attributes into inst attrs */
1878  if (ip->iattrs != NULL && ip->imsym->el.emdp->mattrs != NULL)
1879   add_mod_attrs_toinst(ip);
1880 
1881  /* for now must leave inst-pin list form */
1882  ip->ipins = (struct expr_t **) cp->cpins;
1883 }
1884 
1885 /*
1886  * routine to initialize inst_t record
1887  *
1888  * SJM 10/16/00 - needed to avoid errors and for top_ip
1889  */
init_inst(struct inst_t * ip)1890 static void init_inst(struct inst_t *ip)
1891 {
1892  ip->ip_explicit = FALSE;
1893  ip->pprm_explicit = FALSE;
1894  ip->i_iscell = FALSE;
1895  ip->i_pndsplit = FALSE;
1896  ip->isym = NULL;
1897  ip->imsym = NULL;
1898  ip->ipxprtab = NULL;
1899  ip->iattrs = NULL;
1900  ip->ipins = NULL;
1901  ip->pb_ipins_tab = NULL;
1902 }
1903 
1904 /*
1905  * merge attributes from mod into inst
1906  *
1907  * only called if both inst and mod have at least one attr
1908  * if same attr name in both use inst value
1909  * if name only in mod add to inst list so can use list to make iterator
1910  */
add_mod_attrs_toinst(struct inst_t * ip)1911 static void add_mod_attrs_toinst(struct inst_t *ip)
1912 {
1913  register struct attr_t *iattrp, *mattrp, *iattr_end;
1914  struct attr_t *new_iattrp, *new_iattrhd, *new_iattrend;
1915  struct mod_t *mdp;
1916 
1917  new_iattrhd = new_iattrend = NULL;
1918  iattr_end = NULL;
1919  for (iattrp = ip->iattrs; iattrp != NULL; iattrp = iattrp->attrnxt)
1920   { iattr_end = iattrp; }
1921  mdp = ip->imsym->el.emdp;
1922 
1923  for (mattrp = mdp->mattrs; mattrp != NULL; mattrp = mattrp->attrnxt)
1924   {
1925    for (iattrp = ip->iattrs; iattrp != NULL; iattrp = iattrp->attrnxt)
1926     {
1927      /* attribute attached to both inst and mod - use inst value */
1928      if (strcmp(mattrp->attrnam, iattrp->attrnam) == 0) goto nxt_mod_attr;
1929     }
1930    /* attr attached to mod but not inst and inst has at least one attr */
1931    /* add mod attr to inst */
1932    new_iattrp = (struct attr_t *) __my_malloc(sizeof(struct attr_t));
1933    *new_iattrp = *mattrp;
1934    new_iattrp->attrnam = __pv_stralloc(mattrp->attrnam);
1935    new_iattrp->attr_xp = __copy_expr(mattrp->attr_xp);
1936    new_iattrp->attrnxt = NULL;
1937    if (new_iattrhd == NULL) new_iattrhd = new_iattrp;
1938    else new_iattrend->attrnxt = new_iattrp;
1939    new_iattrend = new_iattrp;
1940 nxt_mod_attr:;
1941   }
1942  /* possible for all to be duplicated so none to add */
1943  if (iattr_end != NULL && new_iattrhd != NULL)
1944   iattr_end->attrnxt = new_iattrhd;
1945 }
1946 
1947 /*
1948  * build expr table from named param list
1949  *
1950  * know instance has pound param(s) or routine not called
1951  * list needed because must be able to index pound parameters when building
1952  * arrays of instance
1953  *
1954  * this assumes module pound params converted to table from list
1955  * happens just before cell rep to inst for each module
1956  *
1957  * when routine done no longer need nqc_u union (i.e. done with npi)
1958  */
inst_nparms_to_xtab(struct namparam_t * npmphdr,struct inst_t * ip)1959 static struct expr_t **inst_nparms_to_xtab(struct namparam_t *npmphdr,
1960  struct inst_t *ip)
1961 {
1962  int32 all_named;
1963  struct expr_t **npxtab;
1964 
1965  /* new explicitly named form */
1966  if (pndparams_explicit(npmphdr, &all_named))
1967   {
1968    if (!all_named)
1969     {
1970      __gferr(829, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
1971       "mixed implicit and explicit # parameters illegal for instance %s",
1972       ip->isym->synam);
1973      __free_namedparams(npmphdr);
1974      return(NULL);
1975     }
1976    npxtab = match_namparam_exprtab(npmphdr, ip);
1977    if (npxtab != NULL) ip->pprm_explicit = TRUE;
1978   }
1979  else
1980   {
1981    /* old unnamed list - but ,, allowed and becomes nil (no param) */
1982    npxtab = match_implprm_exprtab(npmphdr, ip);
1983   }
1984  __free_namedparams(npmphdr);
1985  return(npxtab);
1986 }
1987 
1988 /*
1989  * routine to build inst param expr table from named param list
1990  *
1991  * by here module definition pound parameters converted to table
1992  * param nu2 field union member npi used here as temp, can reuse after here
1993  */
match_namparam_exprtab(struct namparam_t * npmphdr,struct inst_t * ip)1994 static struct expr_t **match_namparam_exprtab(struct namparam_t *npmphdr,
1995  struct inst_t *ip)
1996 {
1997  register int32 pi;
1998  register struct namparam_t *npmp;
1999  struct mod_t *mdp;
2000  struct net_t *np, **prmtab;
2001  struct expr_t **npxtab;
2002  struct sy_t *syp;
2003  char s1[2*IDLEN];
2004 
2005  sprintf(s1, "instance %s", ip->isym->synam);
2006 
2007  mdp = ip->imsym->el.emdp;
2008  if (mdp->mprmnum == 0)
2009   {
2010    __gferr(865, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2011     "%s has explicit pound parameters but none declared in module %s",
2012     s1, mdp->msym->synam);
2013    return(NULL);
2014   }
2015 
2016  /* build sorted by name param declaration list */
2017  prmtab = (struct net_t **) __my_malloc(mdp->mprmnum*sizeof(struct net_t *));
2018  for (pi = 0; pi < mdp->mprmnum; pi++)
2019   {
2020    prmtab[pi] = &(mdp->mprms[pi]);
2021    /* need original ndx of param (net) in table so can set after sorting */
2022    prmtab[pi]->nu2.npi = pi;
2023   }
2024  qsort((char *) prmtab, (word32) mdp->mprmnum, sizeof(struct net_t *),
2025   prmtab_cmp);
2026  /* allocate inst named param expr ptr table and set to unuused (ni) */
2027  npxtab = (struct expr_t **) __my_malloc(mdp->mprmnum*sizeof(struct expr_t *));
2028  for (pi = 0; pi < mdp->mprmnum; pi++) npxtab[pi] = NULL;
2029 
2030  for (npmp = npmphdr, pi = 0; npmp != NULL; npmp = npmp->nprmnxt, pi++)
2031   {
2032    /* DBG remove --- */
2033    if (npmp->pnam == NULL) __misc_terr(__FILE__, __LINE__);
2034    /* --- */
2035 
2036    syp = __zget_sym(npmp->pnam, mdp->msymtab->stsyms, mdp->msymtab->numsyms);
2037    if (syp == NULL || syp->sytyp != SYM_N)
2038     {
2039 undcl_param:
2040      __gferr(865, npmp->prmfnam_ind, npmp->prmlin_cnt,
2041       "%s explicit pound parameter %s (pos. %d) not a declared parameter",
2042       s1, npmp->pnam, pi);
2043      /* if no declared parameters, always continue here */
2044      continue;
2045     }
2046    np = syp->el.enp;
2047    if (!np->n_isaparam || np->nu.ct->p_specparam) goto undcl_param;
2048 
2049    /* AIV 09/27/06 - net cannot be a local param value cannot be overridden */
2050    if (np->nu.ct->p_locparam)
2051     {
2052      __gferr(3431, npmp->prmfnam_ind, npmp->prmlin_cnt,
2053       "%s explicit pound parameter %s (pos. %d) cannot be a localparam (declared pos. %d)",
2054       s1, npmp->pnam, pi, np->nu2.npi);
2055      continue;
2056     }
2057 
2058    if (npxtab[np->nu2.npi] != NULL)
2059     {
2060      __gferr(935, npmp->prmfnam_ind, npmp->prmlin_cnt,
2061       "%s explicit pound parameter %s (pos. %d) repeated (declared pos. %d)",
2062       s1, npmp->pnam, pi, np->nu2.npi);
2063      continue;
2064     }
2065    /* empty .[pnam]() form legal and becomes nil with warning */
2066    if (npmp->pxndp->optyp == OPEMPTY)
2067     {
2068      __gfwarn(545, npmp->prmfnam_ind, npmp->prmlin_cnt,
2069       "%s explicit pound parameter %s expression empty (pos. %d) - no pound override",
2070       s1, npmp->pnam, pi);
2071      continue;
2072     }
2073    /* on error (returns F), leave location in npx tab nil */
2074    if (chk1_pndparam(s1, ip, npmp, pi, np->nu2.npi))
2075     {
2076      npxtab[np->nu2.npi] = npmp->pxndp;
2077      /* this needed to prevent freeing when namparams freed */
2078      npmp->pxndp = NULL;
2079     }
2080   }
2081  /* if all are errors - i.e. table or none decled still empty return nil */
2082  for (pi = 0; pi < mdp->mprmnum; pi++)
2083   { if (npxtab[pi] != NULL) goto some_good; }
2084  return(NULL);
2085 
2086 some_good:
2087  return(npxtab);
2088 }
2089 
2090 /*
2091  * compare for sort of table of ptrs order module parameter table
2092  */
prmtab_cmp(const void * np1,const void * np2)2093 static int32 prmtab_cmp(const void *np1, const void *np2)
2094 {
2095  return(strcmp((*((struct net_t **) np1))->nsym->synam,
2096  ((*(struct net_t **) np2))->nsym->synam));
2097 }
2098 
2099 /*
2100  * check one pound param to make sure parameter constant expression
2101  *
2102  * if error, return -1 so caller does not add to ipx table
2103  * folding done later
2104  */
chk1_pndparam(char * s1,struct inst_t * ip,struct namparam_t * npmp,int32 pi,int32 npi)2105 static int32 chk1_pndparam(char *s1, struct inst_t *ip, struct namparam_t *npmp,
2106  int32 pi, int32 npi)
2107 {
2108  int32 rv, sav_sfnam_ind, sav_slin_cnt;
2109  struct mod_t *imdp;
2110  struct net_t *parm_np;
2111 
2112  /* SJM 10/01/99 - improve error location for param checking */
2113  /* chk param expr needs sim locations set - set temporary guess here */
2114  sav_sfnam_ind = __sfnam_ind;
2115  sav_slin_cnt = __slin_cnt;
2116  __sfnam_ind = npmp->prmfnam_ind;
2117  __slin_cnt = npmp->prmlin_cnt;
2118 
2119  imdp = ip->imsym->el.emdp;
2120  parm_np = &(imdp->mprms[npi]);
2121 
2122  /* notice must check #(parms) rhs here since can be any parameter*/
2123  /* even one defined later in source according to LRM */
2124  if (!__chk_paramexpr(npmp->pxndp, 0))
2125   {
2126    __sgferr(753,
2127     "%s pound parameter %s (pos. %d) expression %s only parameters and constants - is parameter from other module?",
2128     s1, parm_np->nsym->synam, pi, __msgexpr_tostr(__xs, npmp->pxndp));
2129    rv = FALSE;
2130   }
2131  else rv = TRUE;
2132 
2133  __sfnam_ind = sav_sfnam_ind;
2134  __slin_cnt = sav_slin_cnt;
2135  return(rv);
2136 }
2137 
2138 /*
2139  * routine to build inst param expr table from implicit unnamed # param list
2140  *
2141  * no error possible here
2142  */
match_implprm_exprtab(struct namparam_t * npmphdr,struct inst_t * ip)2143 static struct expr_t **match_implprm_exprtab(struct namparam_t *npmphdr,
2144  struct inst_t *ip)
2145 {
2146  register int32 pi;
2147  register struct namparam_t *npmp;
2148  struct mod_t *mdp;
2149  struct expr_t **npxtab;
2150  char s1[2*IDLEN];
2151 
2152  /* can never see connector parameters here */
2153  sprintf(s1, "instance %s", ip->isym->synam);
2154 
2155  mdp = ip->imsym->el.emdp;
2156  /* FIXME - SJM 06/01/99 - if syntax error and no mod params */
2157  /* was wrongly allocating 0 size array here */
2158  /* notice 1 bit enough since once malloced exits pound param loop */
2159  if (mdp->mprmnum == 0)
2160   {
2161    npxtab = (struct expr_t **) __my_malloc(1*sizeof(struct expr_t *));
2162    npxtab[0] = NULL;
2163   }
2164  else
2165   {
2166    /* allocate inst named param expr ptr table and set to unuused (ni) */
2167    npxtab = (struct expr_t **)
2168     __my_malloc(mdp->mprmnum*sizeof(struct expr_t *));
2169   }
2170  for (pi = 0; pi < mdp->mprmnum; pi++) npxtab[pi] = NULL;
2171 
2172  /* unnamed so must match by position */
2173  for (npmp = npmphdr, pi = 0; npmp != NULL; npmp = npmp->nprmnxt, pi++)
2174   {
2175    /* too few ok, but too many is error */
2176    if (pi >= mdp->mprmnum)
2177     {
2178      /* need to count all in list */
2179      for (; npmp != NULL; npmp = npmp->nprmnxt) pi++;
2180 
2181      __gferr(752, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2182       "%s # parameter list too long (%d) - only %d parameters declared",
2183       s1, pi, mdp->mprmnum);
2184      break;
2185     }
2186    /* because now translating like ports allowing ,, that become nil */
2187    if (npmp->pxndp->optyp == OPEMPTY) continue;
2188    if (chk1_pndparam(s1, ip, npmp, pi, pi))
2189     {
2190      npxtab[pi] = npmp->pxndp;
2191      npmp->pxndp = NULL;
2192     }
2193   }
2194  /* if list short, tail will be correctly nil but need inform */
2195  if (pi < mdp->mprmnum)
2196   {
2197    __gfinform(408, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2198     "%s only first %d of %d pound parameters set", s1, pi + 1, mdp->mprmnum);
2199   }
2200  return(npxtab);
2201 }
2202 
2203 /*
2204  * ROUTINES TO ANALYZE INSTANTIATION CONNECTIVITY STRUCTURE
2205  */
2206 
2207 /*
2208  * rearrange and build module and inst. connections for further processing
2209  * also set dag levels and connect inst. pins to module ports
2210  *
2211  * parameter values still unknown but this builds global strength anal. and
2212  * splitting info
2213  */
fix_modcell_nl(void)2214 static int32 fix_modcell_nl(void)
2215 {
2216  register struct mod_t *mdp;
2217 
2218  /* first need to know static instantiations */
2219  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2220   {
2221    __push_wrkitstk(mdp, 0);
2222 
2223    /* F for self instantiation and cannot continue */
2224    if (!count_static_instances(mdp)) return(TRUE);
2225 
2226    __pop_wrkitstk();
2227   }
2228 
2229  /* set dag levels */
2230  if (!chk_dag()) return(FALSE);
2231  return(TRUE);
2232 }
2233 
2234 /*
2235  * distinguish number of times module statically instantiated
2236  * 0 means top, 1 exactly once, 2 more than once
2237  * value here is static unflattened number of instantiations
2238  */
count_static_instances(struct mod_t * mdp)2239 static int32 count_static_instances(struct mod_t *mdp)
2240 {
2241  register int32 ii;
2242  register struct inst_t *ip;
2243  struct sy_t *syp;
2244  struct mod_t *imdp;
2245 
2246  for (ii = 0; ii < mdp->minum; ii++)
2247   {
2248    ip = &(mdp->minsts[ii]);
2249    syp = ip->imsym;
2250    imdp = syp->el.emdp;
2251    if (mdp == imdp)
2252     __gfterr(312, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2253      "INTERNAL - module instantiates itself");
2254    /* only need counts of 0 (never), 1 (exactly once), 2 (more than once) */
2255    if (imdp->minstnum == 0) imdp->minstnum = 1;
2256    else if (imdp->minstnum == 1) imdp->minstnum = 2;
2257   }
2258  return(TRUE);
2259 }
2260 
2261 /*
2262  * check to see if any instantiation loops and set levelized level
2263  * for multiple instantiations level is level of lowest one
2264  */
chk_dag(void)2265 static int32 chk_dag(void)
2266 {
2267  register int32 ii;
2268  register struct mod_t *mdp;
2269  int32 i, change, allmark;
2270  struct inst_t *ip;
2271  struct mod_t *imdp;
2272 
2273  __dagmaxdist = 0;
2274  /* previously initialized to -1 (unmarked) */
2275  for (allmark = TRUE, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2276   {
2277    if (mdp->minsts == NULL) mdp->mlpcnt = 0;
2278    else allmark = FALSE;
2279   }
2280  if (allmark) return(TRUE);
2281  /* level 0 means no contained instances, mark all level i modules */
2282  for (i = 1; i < MAXCIRDPTH; i++)
2283   {
2284    change = FALSE;
2285    /* assume all marked */
2286    allmark = TRUE;
2287    for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2288     {
2289      /* if marked nothing to do */
2290      if (mdp->mlpcnt != -1) continue;
2291 
2292      for (ii = 0; ii < mdp->minum; ii++)
2293       {
2294        ip = &(mdp->minsts[ii]);
2295        imdp = ip->imsym->el.emdp;
2296        /* cannot mark if unmarked or mark this time == i */
2297        if (imdp->mlpcnt == -1 || imdp->mlpcnt == i)
2298 	{
2299          /* ---
2300 	 if (__debug_flg)
2301           {
2302   	   __dbg_msg("++at level %d cannot mark %s because of %s\n", i,
2303 	     mdp->msym->synam, imdp->msym->synam);
2304           }
2305          ---- */
2306  	 goto cannot_mark;
2307 	}
2308       }
2309      mdp->mlpcnt = i;
2310      /* ---
2311      if (__debug_flg)
2312       __dbg_msg("++at level %d marking %s\n", i, mdp->msym->synam);
2313      --- */
2314      change = TRUE;
2315      continue;
2316 
2317 cannot_mark:
2318      allmark = FALSE;
2319     }
2320    if (allmark) { __dagmaxdist = i; return(TRUE); }
2321    if (!change) break;
2322   }
2323  __pv_err(735,
2324   "design contains indirect (length > 1) self instantiation loop");
2325  return(FALSE);
2326 }
2327 
2328 /*
2329  * ROUTINES TO CONNECT PORTS
2330  */
2331 
2332 /*
2333  * check module ports and make instance connections
2334  * handles implicit and explicit form port matching
2335  */
fix_port_conns(void)2336 static void fix_port_conns(void)
2337 {
2338  register struct mod_t *mdp;
2339 
2340  /* set implicit module port form names and I/O directions */
2341  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2342   {
2343    __push_wrkitstk(mdp, 0);
2344    setchk_modports();
2345    __pop_wrkitstk();
2346   }
2347 
2348  /* connect module ports and change to instance port expr. list */
2349  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2350   {
2351    __push_wrkitstk(mdp, 0);
2352    conn_mod_insts();
2353    __pop_wrkitstk();
2354   }
2355 
2356  /* finally can free any sorted work mod port pointer arrays */
2357  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2358   {
2359    if (mdp->smpins == NULL) continue;
2360    __my_free((char *) mdp->smpins, mdp->mpnum*sizeof(struct srtmp_t));
2361    mdp->smpins = NULL;
2362   }
2363 }
2364 
2365 /*
2366  * set and check module header port connections
2367  * needed because .[port]([expr]), legal, unnamed ports legal, and
2368  * repeated nets legal
2369  *
2370  * since wire width not known yet, structural checking here only, widths
2371  * set and checked later
2372  */
setchk_modports(void)2373 static void setchk_modports(void)
2374 {
2375  register int32 pi;
2376  register struct mod_pin_t *mpp;
2377  int32 pnum, port_gd;
2378 
2379  if ((pnum = __inst_mod->mpnum) == 0) return;
2380  for (pi = 0; pi < pnum; pi++)
2381   {
2382    mpp = &(__inst_mod->mpins[pi]);
2383    __pr_iodir = IO_UNKN;
2384    port_gd = chk_prtref(mpp->mpref, mpp, TRUE);
2385    mpp->mptyp = __pr_iodir;
2386 
2387    /* notice empty and concatenate port lists remain unnamed */
2388    if (port_gd)
2389     {
2390      /* SJM 08/23/00 - now OPEMPTY ports also legal and unnamed */
2391      if (mpp->mpsnam == NULL && mpp->mpref->optyp != LCB
2392       && mpp->mpref->optyp != OPEMPTY)
2393       {
2394        if (mpp->mpref->optyp == ID) mpp->mpsnam = mpp->mpref->lu.sy->synam;
2395        else mpp->mpsnam = mpp->mpref->lu.x->lu.sy->synam;
2396       }
2397     }
2398    else
2399     {
2400      __free_xtree(mpp->mpref);
2401      __bld_unc_expr();
2402      mpp->mpref = __root_ndp;
2403     }
2404   }
2405 }
2406 
2407 /*
2408  * check a module port def. expression to make sure it is a prtref
2409  * return F on error else T
2410  * prtref is lhs value or concatenate (including nested) of port refs.
2411  * also checks and sets I/O direction
2412  * this is called before wire and port ranges known
2413  */
chk_prtref(struct expr_t * ndp,struct mod_pin_t * mpp,int32 is_top)2414 static int32 chk_prtref(struct expr_t *ndp, struct mod_pin_t *mpp,
2415  int32 is_top)
2416 {
2417  struct net_t *np;
2418  struct expr_t *idndp;
2419  char s1[RECLEN], s2[RECLEN];
2420 
2421  switch ((byte) ndp->optyp) {
2422   case GLBREF:
2423 bad_prtglb:
2424    __gferr(736, mpp->mpfnam_ind, mpp->mplin_cnt,
2425     "module header list of ports hierarchical path reference %s illegal",
2426      ndp->ru.grp->gnam);
2427    return(FALSE);
2428   case ID:
2429    /* when ID appears in mod. def. port header, converted to undecl net */
2430    np = ndp->lu.sy->el.enp;
2431    idndp = ndp;
2432 chk_dir:
2433    if (!idndp->lu.sy->sydecl)
2434     {
2435      __gferr(737, mpp->mpfnam_ind, mpp->mplin_cnt,
2436       "I/O port %s required direction declaration missing", np->nsym->synam);
2437      return(FALSE);
2438     }
2439    if (np->iotyp == NON_IO)
2440     {
2441      __gferr(738, mpp->mpfnam_ind, mpp->mplin_cnt,
2442       "module header list of ports %s %s must be I/O port",
2443        __to_wtnam(s1, np), np->nsym->synam);
2444      return(FALSE);
2445     }
2446    if (__pr_iodir == IO_UNKN) __pr_iodir = np->iotyp;
2447    else if (__pr_iodir != np->iotyp)
2448     {
2449      __gferr(739, mpp->mpfnam_ind, mpp->mplin_cnt,
2450      "module header list of ports %s wire %s has conflicting %s port type",
2451       __to_ptnam(s1, np->iotyp), np->nsym->synam, __to_ptnam(s2, __pr_iodir));
2452      return(FALSE);
2453     }
2454    /* count times wire repeated in port list */
2455    if (np->nu.ct->num_prtconns != 2 && is_top) np->nu.ct->num_prtconns += 1;
2456 
2457    /* notice in and inout ports must be wires but out can be reg */
2458    if (!chk_prtntyp(mpp, np)) return(FALSE);
2459    break;
2460   case PARTSEL:
2461    /* since check module port syntax before splitting, mark params that */
2462    /* can effect expr. width here to later possibly cause split not IS form */
2463    __in_xpr_markparam(ndp->ru.x->lu.x);
2464    __in_xpr_markparam(ndp->ru.x->ru.x);
2465    /* FALLTHRU */
2466   case LSB:
2467    if (ndp->lu.x->optyp == GLBREF) goto bad_prtglb;
2468    idndp = ndp->lu.x;
2469    np = idndp->lu.sy->el.enp;
2470    /* inout port expr. may need to go in tran channel so can't be IS form */
2471    if (np->iotyp == IO_BID) __in_xpr_markparam(ndp->ru.x);
2472    goto chk_dir;
2473   case LCB:
2474    if (!is_top)
2475     {
2476      __gferr(740, mpp->mpfnam_ind, mpp->mplin_cnt,
2477       "module header list of ports nested concatenate illegal");
2478      return(FALSE);
2479     }
2480    {
2481     register struct expr_t *ndp2;
2482 
2483     /* ndp2 left can still be nested concatenate by here */
2484     /* but can find rep. number */
2485     for (ndp2 = ndp->ru.x; ndp2 != NULL; ndp2 = ndp2->ru.x)
2486      {
2487       /* check I/O direction from subcomponents one down */
2488       /* also check for incorrect reg one down */
2489       if (!chk_prtref(ndp2->lu.x, mpp, FALSE)) return(FALSE);
2490      }
2491    }
2492    break;
2493   case CATREP:
2494    __gferr(741, mpp->mpfnam_ind, mpp->mplin_cnt,
2495     "module header list of ports port ref. concatenate repeat form illegal");
2496    return(FALSE);
2497   case OPEMPTY:
2498    break;
2499   default:
2500    __gferr(742, mpp->mpfnam_ind, mpp->mplin_cnt,
2501     "%s illegal module header list of ports port reference",
2502     __msgexpr_tostr(__xs, ndp));
2503    return(FALSE);
2504  }
2505  return(TRUE);
2506 }
2507 
2508 /*
2509  * check a port wire to make sure net type legal
2510  */
chk_prtntyp(struct mod_pin_t * mpp,struct net_t * np)2511 static int32 chk_prtntyp(struct mod_pin_t *mpp, struct net_t *np)
2512 {
2513  char s1[RECLEN], s2[RECLEN];
2514 
2515  if (np->iotyp == IO_OUT)
2516   {
2517    if (np->ntyp == N_REAL)
2518     {
2519      __gferr(743, mpp->mpfnam_ind, mpp->mplin_cnt,
2520       "%s port %s type real illegal", __to_ptnam(__xs, np->iotyp),
2521       np->nsym->synam);
2522      return(FALSE);
2523     }
2524   }
2525  else
2526   {
2527    if (np->ntyp >= NONWIRE_ST)
2528     {
2529      __gferr(744, mpp->mpfnam_ind, mpp->mplin_cnt,
2530       "%s port %s of net type %s illegal - must be a wire",
2531        __to_ptnam(s1, np->iotyp), np->nsym->synam, __to_wtnam(s2, np));
2532      return(FALSE);
2533     }
2534   }
2535  return(TRUE);
2536 }
2537 
2538 /*
2539  * check/connect cell pins to defined down one module
2540  * no processing of gates here
2541  */
conn_mod_insts(void)2542 static void conn_mod_insts(void)
2543 {
2544  register int32 ii;
2545  register struct cell_pin_t *cpp;
2546  int32 nbytes;
2547  struct inst_t *ip;
2548  struct sy_t *syp;
2549  struct mod_t *imdp;
2550  struct expr_t **xphdr;
2551  struct srcloc_t *srcloc;
2552 
2553  if (__inst_mod->minum == 0) return;
2554 
2555  /* allocate the || to minsts per contained inst pin src loc table */
2556  nbytes = __inst_mod->minum*sizeof(struct srcloc_t *);
2557  __inst_mod->iploctab = (struct srcloc_t **) __my_malloc(nbytes);
2558 
2559  for (ii = 0; ii < __inst_mod->minum; ii++)
2560   {
2561    ip = &(__inst_mod->minsts[ii]);
2562    syp = ip->imsym;
2563    /* module instance declaration info lost */
2564    if (!syp->sydecl)
2565     __misc_gfterr(__FILE__, __LINE__, ip->isym->syfnam_ind,
2566      ip->isym->sylin_cnt);
2567    imdp = ip->imsym->el.emdp;
2568 
2569    /* instance must contain at least () which will cause 1 unc. pin */
2570    cpp = (struct cell_pin_t *) ip->ipins;
2571    /* DBG remove --- */
2572    /* know there will be at least one pin if no error */
2573    if (cpp == NULL && imdp->mpnum != 0)
2574     {
2575      if (__pv_err_cnt == 0) __misc_terr(__FILE__, __LINE__); else continue;
2576     }
2577    /* --- */
2578 
2579    /* allocate new expression table */
2580    /* special case of module with no ports instantiated as () */
2581    /* it will have one unc. port - legal for 1 port case */
2582    /* but since no module ports this special port must be thrown away */
2583    if (imdp->mpnum == 0)
2584     {
2585      ip->ipins = NULL;
2586      srcloc = NULL;
2587      /* only set to NULL if has 1 unc. port - else will be null */
2588      /* LOOKATME - not freeing case of one unc. port */
2589      if (cpp == NULL || (cpp->cpnxt == NULL && cpp->cpxnd->optyp == OPEMPTY))
2590       goto nxt_cell;
2591 
2592      __gferr(746, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2593       "instance %s module type %s has ports but module does not",
2594        ip->isym->synam, imdp->msym->synam);
2595      goto nxt_cell;
2596     }
2597    nbytes = imdp->mpnum*sizeof(struct expr_t *);
2598    xphdr = (struct expr_t **) __my_malloc(nbytes);
2599    nbytes = imdp->mpnum*sizeof(struct srcloc_t);
2600    srcloc = (struct srcloc_t *) __my_malloc(nbytes);
2601 
2602    /* allocate cell-pin expression table */
2603    /* all implicit connection case */
2604    if (cpp->pnam == NULL) conn_impl_mports(ip, cpp, imdp, xphdr, srcloc);
2605    /* all explicit connection case */
2606    else conn_expl_mports(ip, cpp, imdp, xphdr, srcloc);
2607    ip->ipins = xphdr;
2608 
2609 nxt_cell:
2610 
2611    /* must connect to current mod since need port locs for expr check */
2612    /* since parallel to insts, for insts. with no cell pin list will be nil */
2613    __inst_mod->iploctab[ii] = srcloc;
2614   }
2615 }
2616 
2617 /*
2618  * connect implicit instance ports
2619  * mdp is instance module type
2620  * various checking goes here
2621  * ,, form here already made appropriate unc.
2622  *
2623  * know module port num at least one or not called
2624  */
conn_impl_mports(struct inst_t * ip,struct cell_pin_t * cpp,struct mod_t * mdp,struct expr_t ** xphdr,struct srcloc_t * srclocp)2625 static void conn_impl_mports(struct inst_t *ip, struct cell_pin_t *cpp,
2626  struct mod_t *mdp, struct expr_t **xphdr, struct srcloc_t *srclocp)
2627 {
2628  register int32 pi;
2629  struct cell_pin_t *last_cpp;
2630  int32 pnum, num_unc_ports;
2631 
2632  ip->ip_explicit = FALSE;
2633  pnum = mdp->mpnum;
2634  num_unc_ports = 0;
2635  for (pi = 0; pi < pnum;)
2636   {
2637    if (cpp->pnam != NULL)
2638     {
2639      __gferr(747, cpp->cpfnam_ind, cpp->cplin_cnt,
2640      "%s(%s) explicit port %s (pos. %d) mixed in implicit connection list",
2641       ip->isym->synam, ip->imsym->synam, cpp->pnam, pi + 1);
2642     }
2643    /* SJM 11/13/00 - now also emit warning if ,, unc. form in implicit list */
2644    if (cpp->cpxnd->optyp == OPEMPTY) num_unc_ports++;
2645    xphdr[pi] = cpp->cpxnd;
2646    /* here implicit means port in order def. i and inst i same */
2647    srclocp[pi].sl_fnam_ind = cpp->cpfnam_ind;
2648    srclocp[pi].sl_lin_cnt = cpp->cplin_cnt;
2649    last_cpp = cpp;
2650    if ((cpp = cpp->cpnxt) == NULL && pi < pnum - 1) goto too_few;
2651    pi++;
2652   }
2653  if (cpp != NULL)
2654   {
2655    __gferr(748, cpp->cpfnam_ind, cpp->cplin_cnt,
2656     "%s(%s) implicit connection list more ports than type with %d",
2657     ip->isym->synam, ip->imsym->synam, pnum);
2658   }
2659  if (num_unc_ports > 0)
2660   {
2661    __gfwarn(531, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2662     "%s(%s) implicit connection list fewer ports %d connected than type's %d",
2663     ip->isym->synam, ip->imsym->synam, pnum - num_unc_ports, pnum);
2664   }
2665  return;
2666 
2667 too_few:
2668  pi++;
2669  /* warn because ,,s should be included */
2670   {
2671    __gfwarn(531, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2672     "%s(%s) implicit connection list fewer ports %d in list than type's %d",
2673     ip->isym->synam, ip->imsym->synam, pi, pnum);
2674   }
2675  for (; pi < pnum; pi++)
2676   {
2677    __bld_unc_expr();
2678    xphdr[pi] = __root_ndp;
2679    /* for missing use last or if no conn use isym loc. */
2680    if (last_cpp == NULL)
2681     {
2682      srclocp[pi].sl_fnam_ind = ip->isym->syfnam_ind;
2683      srclocp[pi].sl_lin_cnt = ip->isym->sylin_cnt;
2684     }
2685    else
2686     {
2687      srclocp[pi].sl_fnam_ind = last_cpp->cpfnam_ind;
2688      srclocp[pi].sl_lin_cnt = last_cpp->cplin_cnt;
2689     }
2690   }
2691 }
2692 
2693 /*
2694  * connect explicit instance connection form ports
2695  *
2696  * builds ipins table (of prts to exprs) size is always num mod ports
2697  * even if some unconnected (will be unc. expr)
2698  *
2699  * know module port num at least one or not called
2700  */
conn_expl_mports(struct inst_t * ip,struct cell_pin_t * cpp,struct mod_t * imdp,struct expr_t ** xphdr,struct srcloc_t * srclocp)2701 static void conn_expl_mports(struct inst_t *ip, struct cell_pin_t *cpp,
2702  struct mod_t *imdp, struct expr_t **xphdr, struct srcloc_t *srclocp)
2703 {
2704  register int32 pi, mpi;
2705  register int32 cpnum, pnum;
2706  register int32 cv;
2707  int32 num_unc_ports;
2708  struct cell_pin_t **srtcptab;
2709  struct srtmp_t *srtmptab;
2710  struct cell_pin_t *scpp;
2711  struct srtmp_t *smpp;
2712 
2713  ip->ip_explicit = TRUE;
2714  /* if module has unnamed ports, cannot continue */
2715  if (!chk_mdports_named(ip, imdp, xphdr)) return;
2716 
2717  /* if no sorted port list for this module type, build one */
2718  if (imdp->smpins == NULL) bld_srted_mdpins(imdp);
2719  srtmptab = imdp->smpins;
2720 
2721  /* build the sorted cell pin table for instance */
2722  pnum = imdp->mpnum;
2723  for (scpp = cpp, cpnum = 0; scpp != NULL; scpp = scpp->cpnxt) cpnum++;
2724  srtcptab = (struct cell_pin_t **)
2725   __my_malloc(cpnum*sizeof(struct cell_pin_t *));
2726  if (!bld_srted_ipins(ip, cpp, cpnum, srtcptab)) goto free_pin_tab;
2727 
2728  pi = 0; scpp = srtcptab[0];
2729  mpi = 0; smpp = &(srtmptab[0]);
2730  /* know both lists sorted so move through */
2731  /* if past end of either done - if no match, left as nil, made unc. */
2732  for (; pi < cpnum && mpi < pnum;)
2733   {
2734    /* scpp is cell (inst.) port and smpp is module port */
2735    if ((cv = strcmp(scpp->pnam, smpp->smp->mpsnam)) == 0)
2736     {
2737      xphdr[smpp->mppos] = scpp->cpxnd;
2738      /* index here is type def. order, def. i line no. if for i conn. */
2739      srclocp[smpp->mppos].sl_fnam_ind = scpp->cpfnam_ind;
2740      srclocp[smpp->mppos].sl_lin_cnt = scpp->cplin_cnt;
2741      /* if at end of instance ports, done */
2742      pi++; if (pi < cpnum) scpp = srtcptab[pi];
2743      mpi++; if (mpi < pnum) smpp = &(srtmptab[mpi]);
2744      continue;
2745     }
2746    /* module instance port extra or repeated - fits between type ports */
2747    /* cell port alphabetically less than module port - is non mod port */
2748    /* becasue both sorted - if repeated, moved to next mod port so same */
2749    /* cell port now less than */
2750    if (cv < 0)
2751     {
2752      if (pi > 0 && strcmp(srtcptab[pi - 1]->pnam, scpp->pnam) == 0)
2753       {
2754        __gferr(745, scpp->cpfnam_ind, scpp->cplin_cnt,
2755         "%s(%s) explicit connection port %s repeated",
2756         ip->isym->synam, imdp->msym->synam, scpp->pnam);
2757       }
2758      else __gferr(749, scpp->cpfnam_ind, scpp->cplin_cnt,
2759       "%s(%s) explicit connection port %s is not a module port",
2760       ip->isym->synam, imdp->msym->synam, scpp->pnam);
2761      pi++;
2762      if (pi < cpnum) scpp = srtcptab[pi];
2763      continue;
2764     }
2765    /* cell port alphabetically greater than module port */
2766    /* module type port is extra (unc.) - fits between module inst ports */
2767    mpi++; if (mpi < pnum) smpp = &(srtmptab[mpi]);
2768   }
2769  /* if more cell ports, know are non port - emit error */
2770  for (; pi < cpnum; pi++)
2771   {
2772    scpp = srtcptab[pi];
2773    __gferr(749, scpp->cpfnam_ind, scpp->cplin_cnt,
2774     "%s(%s) explicit connection port %s is not a module port",
2775     ip->isym->synam, imdp->msym->synam, scpp->pnam);
2776   }
2777 free_pin_tab:
2778  __my_free((char *) srtcptab, cpnum*sizeof(struct cell_pin_t *));
2779  srtcptab = NULL;
2780 
2781  /* for all unc. (NULL) expressions convert to real unconnected */
2782  num_unc_ports = 0;
2783  for (pi = 0; pi < pnum; pi++)
2784   {
2785    if (xphdr[pi] == NULL)
2786     {
2787      __bld_unc_expr();
2788      xphdr[pi] = __root_ndp;
2789      /* use instance location for these */
2790      srclocp[pi].sl_fnam_ind = ip->isym->syfnam_ind;
2791      srclocp[pi].sl_lin_cnt = ip->isym->sylin_cnt;
2792      num_unc_ports++;
2793     }
2794   }
2795  if (num_unc_ports > 0)
2796   {
2797    __gfwarn(531, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2798     "%s(%s) explicit connection list fewer ports %d connected than type's %d",
2799     ip->isym->synam, ip->imsym->synam, pnum - num_unc_ports, pnum);
2800   }
2801 }
2802 
2803 /*
2804  * check to make sure for explicit instance form all module ports named
2805  * also initialized instance port expression table to NULL
2806  * only called for explicit conn. instances
2807  */
chk_mdports_named(struct inst_t * ip,struct mod_t * mdp,struct expr_t ** xphdr)2808 static int32 chk_mdports_named(struct inst_t *ip,
2809  struct mod_t *mdp, struct expr_t **xphdr)
2810 {
2811  register int32 pi;
2812  register struct mod_pin_t *mpp;
2813  int32 pnum, __err_seen;
2814 
2815  if ((pnum = mdp->mpnum) == 0) return(FALSE);
2816 
2817  __err_seen = FALSE;
2818  for (pi = 0; pi < pnum; pi++)
2819   {
2820    mpp = &(mdp->mpins[pi]);
2821    if (mpp->mpsnam == NULL)
2822     {
2823      __gferr(750, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2824       "%s(%s) explicit connection form illegal - port %d unnamed",
2825      ip->isym->synam, mdp->msym->synam, pi + 1);
2826      __err_seen = TRUE;
2827     }
2828    xphdr[pi] = NULL;
2829   }
2830  return(!__err_seen);
2831 }
2832 
2833 /*
2834  * build sorted table of module ports - once built saved so not rebuilt
2835  * each time - freed when port connection phase completed
2836  * only called when know all module ports named and at least 1 port
2837  */
bld_srted_mdpins(struct mod_t * mdp)2838 static void bld_srted_mdpins(struct mod_t *mdp)
2839 {
2840  register int32 pi;
2841  register struct srtmp_t *smpp;
2842  register struct mod_pin_t *mpp;
2843  struct srtmp_t *smptab;
2844  int32 pnum;
2845 
2846  pnum = mdp->mpnum;
2847  smptab = (struct srtmp_t *) __my_malloc(pnum*sizeof(struct srtmp_t));
2848  mdp->smpins = smptab;
2849  mpp = &(mdp->mpins[0]);
2850  for (pi = 0, smpp = &(smptab[0]); pi < pnum; pi++, smpp++, mpp++)
2851   {
2852    smpp->smp = mpp;
2853    smpp->mppos = pi;
2854   }
2855  qsort((char *) smptab, (word32) pnum, sizeof(struct srtmp_t), smp_cmp);
2856 }
2857 
2858 /*
2859  * module port name comparison routine
2860  */
smp_cmp(const void * srp1,const void * srp2)2861 static int32 smp_cmp(const void *srp1, const void *srp2)
2862 {
2863  return(strcmp(((struct srtmp_t *) srp1)->smp->mpsnam,
2864  ((struct srtmp_t *) srp2)->smp->mpsnam));
2865 }
2866 
2867 /*
2868  * build sorted table of instance ports
2869  * built for each explicitly connected instance
2870  * free when instance connections made
2871  */
bld_srted_ipins(struct inst_t * ip,register struct cell_pin_t * cpp,int32 pnum,struct cell_pin_t ** scptab)2872 static int32 bld_srted_ipins(struct inst_t *ip,
2873  register struct cell_pin_t *cpp, int32 pnum, struct cell_pin_t **scptab)
2874 {
2875  register int32 pi;
2876  register struct cell_pin_t *cpp2;
2877  char *chp;
2878 
2879  for (pi = 0; pi < pnum; pi++, cpp = cpp->cpnxt)
2880   {
2881    if (cpp->pnam == NULL)
2882     {
2883      __gferr(751, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2884       "%s(%s) explicit connection list but port connection %d is implicit",
2885       ip->isym->synam, ip->imsym->synam, pi + 1);
2886      return(FALSE);
2887     }
2888    scptab[pi] = cpp;
2889   }
2890  qsort((char *) scptab, (word32) pnum, sizeof(struct cell_pin_t *), cpn_cmp);
2891 
2892  /* must check for duplicate of same name since illegal */
2893  /* LOOKATME - think none impossible but doing nothing is right if happens */
2894  if (pnum <= 0) return(TRUE);
2895 
2896  chp = scptab[0]->pnam;
2897  for (pi = 1; pi < pnum; pi++)
2898   {
2899    cpp2 = scptab[pi];
2900    if (strcmp(chp, cpp2->pnam) == 0)
2901     {
2902      __gferr(1038, cpp2->cpfnam_ind, cpp2->cplin_cnt,
2903       "%s(%s) explicit connection list named port %s repeated",
2904       ip->isym->synam, ip->imsym->synam, chp);
2905     }
2906    else chp = scptab[pi]->pnam;
2907   }
2908  return(TRUE);
2909 }
2910 
2911 /*
2912  * module port name comparison routine
2913  */
cpn_cmp(const void * cpp1,const void * cpp2)2914 static int32 cpn_cmp(const void *cpp1, const void *cpp2)
2915 {
2916  return(strcmp((*((struct cell_pin_t **) cpp1))->pnam,
2917   (*(struct cell_pin_t **) cpp2)->pnam));
2918 }
2919 
2920 /*
2921  * routine to free all allocated ncmp blks when no longed used at all
2922  */
free_cpblks(void)2923 static void free_cpblks(void)
2924 {
2925  register struct cpblk_t *cpbp, *cpbp2;
2926 
2927  /* free all cell pin blks since ncomp form now gone */
2928  for (cpbp = __hdr_cpblks; cpbp != NULL;)
2929   {
2930    cpbp2 = cpbp->cpblknxt;
2931    __my_free((char *) cpbp->cpblks, BIG_ALLOC_SIZE);
2932    __my_free((char *) cpbp, sizeof(struct cpblk_t));
2933    cpbp = cpbp2;
2934   }
2935 }
2936 
2937 /*
2938  * routine to free all allocated ncmp blks when no longed used at all
2939  */
free_cppblks(void)2940 static void free_cppblks(void)
2941 {
2942  register struct cppblk_t *cppbp, *cppbp2;
2943  register struct cpnblk_t *cpnbp, *cpnbp2;
2944 
2945  /* free all cell pin blks since ncomp form now gone */
2946  for (cppbp = __hdr_cppblks; cppbp != NULL;)
2947   {
2948    cppbp2 = cppbp->cppblknxt;
2949    __my_free((char *) cppbp->cppblks, BIG_ALLOC_SIZE);
2950    __my_free((char *) cppbp, sizeof(struct cppblk_t));
2951    cppbp = cppbp2;
2952   }
2953  for (cpnbp = __hdr_cpnblks; cpnbp != NULL;)
2954   {
2955    cpnbp2 = cpnbp->cpnblknxt;
2956    __my_free((char *) cpnbp->cpnblks, BIG_ALLOC_SIZE);
2957    __my_free((char *) cpnbp, sizeof(struct cpnblk_t));
2958    cpnbp = cpnbp2;
2959   }
2960 }
2961 
2962 /*
2963  * set the as if flattended instance counts for all modules
2964  * know flat insts initialized to 0 and m insts already counted
2965  * this also links every module inst. upward (parent) instance
2966  *
2967  * count here counts only 1 for each cell array - fixed up later
2968  */
count_flat_insts(void)2969 static void count_flat_insts(void)
2970 {
2971  register int32 ii;
2972  register struct mod_t *mdp;
2973  struct inst_t *ip;
2974  struct mod_t *imdp;
2975 
2976  /* must always reinitialize flat count because maybe called multiple times */
2977  /* i.e. after arrays of instances expanded */
2978  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2979   mdp->flatinum = 0;
2980 
2981  /* inc. count of all instances in each top level module */
2982  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2983   {
2984    /* descend to count only from top level modulss */
2985    if (mdp->minstnum != 0) continue;
2986    mdp->flatinum = 1;
2987 
2988    /* count depth first */
2989    for (ii = 0; ii < mdp->minum; ii++)
2990     {
2991      ip = &(mdp->minsts[ii]);
2992      imdp = ip->imsym->el.emdp;
2993      imdp->flatinum++;
2994 
2995      /* DBG remove ---
2996      if (__debug_flg)
2997       {
2998        __dbg_msg(
2999         "+++ incing count (%d) of inst. %s type %s in top level module %s\n",
3000         imdp->flatinum, ip->isym->synam, imdp->msym->synam,
3001         __inst_mod->msym->synam);
3002       }
3003      ---- */
3004      count2_flat_insts(imdp);
3005     }
3006   }
3007 }
3008 
3009 /*
3010  * traverse 1 down flattened inst. count
3011  */
count2_flat_insts(struct mod_t * mdp)3012 static void count2_flat_insts(struct mod_t *mdp)
3013 {
3014  register int32 ii;
3015  register struct inst_t *ip;
3016  struct mod_t *imdp;
3017 
3018  for (ii = 0; ii < mdp->minum; ii++)
3019   {
3020    ip = &(mdp->minsts[ii]);
3021    imdp = ip->imsym->el.emdp;
3022    imdp->flatinum++;
3023    /* DBG remove ---
3024    if (__debug_flg)
3025     {
3026      __dbg_msg("+++ traverse inc count (%d) inst %s type %s in mod %s\n",
3027       imdp->flatinum, ip->isym->synam, imdp->msym->synam, mdp->msym->synam);
3028     }
3029    --- */
3030    if (imdp->mlpcnt > 0) count2_flat_insts(imdp);
3031   }
3032 }
3033 
3034 /*
3035  * ROUTINES TO SPLIT INSTS, REBUILD AND EXPAND FOR GATE/INST ARRAYS
3036  */
3037 
3038 /*
3039  * split (copy) module types for which pound params used in arrays of
3040  * gates or instances declaration width ranges
3041  */
do_giarr_splitting(void)3042 static void do_giarr_splitting(void)
3043 {
3044  register int32 ii, mlevel;
3045  register struct mod_t *mdp;
3046  struct inst_t *ip;
3047  struct mod_t *imdp;
3048 
3049  /* start will all modules that contain instances only of modules */
3050  /* which themselves contain no instances and work upward */
3051  for (mlevel = 1; mlevel <= __dagmaxdist; mlevel++)
3052   {
3053    /* SJM 03/16/04 - notice processing one up and splitting (if needed) */
3054    /* contained instances - therefore mlevel of md lev hdr list not chged */
3055    /* inside this loop */
3056    for (mdp = __mdlevhdr[mlevel]; mdp != NULL; mdp = mdp->mlevnxt)
3057     {
3058      __push_wrkitstk(mdp, 0);
3059 
3060      /* go through instances in current module */
3061      for (ii = 0; ii < __inst_mod->minum; ii++)
3062       {
3063        ip = &(__inst_mod->minsts[ii]);
3064        if (ip->ipxprtab == NULL) continue;
3065 
3066        /* imdp is module type of instance that has pound params */
3067        imdp = ip->imsym->el.emdp;
3068        __sfnam_ind = ip->isym->syfnam_ind;
3069        __slin_cnt = ip->isym->sylin_cnt;
3070 
3071        /* because static src inst loc. has pnd params, if any gate must */
3072        /* try to set any gate range params */
3073        /* AIV 07/12/04 - old checking and was wrong nad mark gia rng checks */
3074        if (!imdp->mgiarngdone)
3075         {
3076          mark_gia_rng_params(imdp);
3077          imdp->mgiarngdone = TRUE;
3078         }
3079 
3080        /* eliminate if instance not arrayed at this src loc. */
3081        if (__inst_mod->miarr == NULL || __inst_mod->miarr[ii] == NULL)
3082         continue;
3083 
3084        /* mark parameters used in gi array ranges exprs once for each mod */
3085        if (!imdp->mgiarngdone)
3086         { mark_gia_rng_params(imdp); imdp->mgiarngdone = TRUE; }
3087 
3088        if (!down_hasgiarngdet_param(imdp)) continue;
3089 
3090        /* even if no split (one place in source instantiated) need to eval */
3091        /* mark that some modules have width determining pnd params and mark */
3092        /* that this one does */
3093        ip->imsym->el.emdp->mpndprm_ingirng = TRUE;
3094 
3095        /* if only one place in source instantiated, must not split */
3096        /* because would create never instantiated instance */
3097        if (imdp->flatinum == 1 || imdp->flatinum == __inst_mod->flatinum)
3098         continue;
3099 
3100        /* this does not need to update miarr since parallel minsts updated */
3101        split_upd_mod(imdp, ip, mlevel);
3102       }
3103      __pop_wrkitstk();
3104     }
3105   }
3106 }
3107 
3108 /*
3109  * mark all parameters that are used in arrays of gate/inst ranges
3110  * inside module pmdp
3111  *
3112  * splitting later only if these parameters are passed as pound params
3113  * caller will mark module
3114  */
mark_gia_rng_params(struct mod_t * pmdp)3115 static void mark_gia_rng_params(struct mod_t *pmdp)
3116 {
3117  register int32 gi, ii;
3118  struct giarr_t *giap;
3119 
3120  if (pmdp->mgarr != NULL)
3121   {
3122    for (gi = 0; gi < pmdp->mgnum; gi++)
3123     {
3124      if ((giap = pmdp->mgarr[gi]) == NULL) continue;
3125 
3126      if (in_giarng_markparam(giap, giap->giax1))
3127       pmdp->mpndprm_ingirng = TRUE;
3128      if (in_giarng_markparam(giap, giap->giax2))
3129       pmdp->mpndprm_ingirng = TRUE;
3130     }
3131   }
3132 
3133  if (pmdp->miarr != NULL)
3134   {
3135    for (ii = 0; ii < pmdp->minum; ii++)
3136     {
3137      if ((giap = pmdp->miarr[ii]) == NULL) continue;
3138 
3139      if (in_giarng_markparam(giap, giap->giax1))
3140       pmdp->mpndprm_ingirng = TRUE;
3141      if (in_giarng_markparam(giap, giap->giax2))
3142       pmdp->mpndprm_ingirng = TRUE;
3143     }
3144   }
3145 }
3146 
3147 /*
3148  * mark parmeters (nets) in arrays of gate/inst range parameters
3149  *
3150  * only called for expressions in gate/inst range indices
3151  */
in_giarng_markparam(struct giarr_t * giap,struct expr_t * xp)3152 static int32 in_giarng_markparam(struct giarr_t *giap, struct expr_t *xp)
3153 {
3154  int32 rv1, rv2;
3155  struct net_t *np;
3156 
3157  rv1 = rv2 = FALSE;
3158  if (__isleaf(xp))
3159   {
3160    if (xp->optyp == ID && xp->lu.sy->sytyp == SYM_N)
3161     {
3162      np = xp->lu.sy->el.enp;
3163      if (np->n_isaparam)
3164       {
3165        np->nu.ct->n_in_giarr_rng = TRUE;
3166        giap->gia_rng_has_pnd = TRUE;
3167        __design_gia_pndparams = TRUE;
3168        rv1 = TRUE;
3169       }
3170     }
3171    return(rv1);
3172   }
3173  if (xp->lu.x != NULL) rv1 = in_giarng_markparam(giap, xp->lu.x);
3174  if (xp->ru.x != NULL) rv2 = in_giarng_markparam(giap, xp->ru.x);
3175  return(rv1 || rv2);
3176 }
3177 
3178 /*
3179  * return T if any down instance (module type ipmdp) pound parameter
3180  * determines array of gates or instances range
3181  */
down_hasgiarngdet_param(struct mod_t * ipmdp)3182 static int32 down_hasgiarngdet_param(struct mod_t *ipmdp)
3183 {
3184  register int32 pi;
3185  struct net_t *parm_np;
3186 
3187  /* if # param list short ok, do not bother changing missing at end */
3188  /* only check params actually set if short list */
3189  for (pi = 0; pi < ipmdp->mprmnum; pi++)
3190   {
3191    parm_np = &(ipmdp->mprms[pi]);
3192 
3193    if (parm_np->nu.ct->n_in_giarr_rng)
3194     {
3195      if (__debug_flg)
3196       {
3197        __dbg_msg(
3198         "+++ split module %s, # param %s in array of inst/gate range expr.\n",
3199         ipmdp->msym->synam, parm_np->nsym->synam);
3200       }
3201      return(TRUE);
3202     }
3203    /* move to next target module pound param */
3204   }
3205  if (__debug_flg)
3206   __dbg_msg(
3207    "+++ no need to split module %s because of pound param in gate/inst range",
3208    ipmdp->msym->synam);
3209  return(FALSE);
3210 }
3211 
3212 /*
3213  * ROUTINES TO BUILD TOP VIRTUAL INSTANCES
3214  */
3215 
3216 /*
3217  * build the list of instances for uninstantiated top level modules
3218  * this builds inst_t (static inst) for each top level modules
3219  * and makes top itab of index point to it
3220  *
3221  * notice top module may be split, so this new elements can be added later
3222  *
3223  * top_iptab points to created instances since for top module and instance
3224  * have same name - top_iptab and it_roots are parallel arrays, top_ipind
3225  * ins sorted index into both top_iptab and it_roots since they are ||
3226  *
3227  */
bld_top_virtinsts(void)3228 static void bld_top_virtinsts(void)
3229 {
3230  register int32 tpii;
3231  register struct mod_t *mdp;
3232  int32 ii;
3233  struct inst_t *ip;
3234  struct sy_t *syp;
3235  struct itree_t *itp;
3236 
3237  /* count number of top level modules */
3238  __numtopm = 0;
3239  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3240   {
3241    /* descend to count only from top level modules */
3242    if (mdp->minstnum != 0) continue;
3243 
3244    /* top modules will have is cell bit on if configs used */
3245    if (mdp->m_iscell && __map_files_hd == NULL)
3246     {
3247      __gfwarn(597, mdp->msym->syfnam_ind, mdp->msym->sylin_cnt,
3248       "top level module %s in `celldefine region but cannot be a cell",
3249        mdp->msym->synam);
3250      mdp->m_iscell = FALSE;
3251     }
3252    __numtopm++;
3253   }
3254  if (__numtopm == 0) return;
3255  __top_itab = (struct inst_t **)
3256   __my_malloc(__numtopm*sizeof(struct inst_t *));
3257  for (tpii = -1, mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3258   {
3259    if (mdp->minstnum != 0) continue;
3260    /* need 1 itree inst for each top level module because itp->itip */
3261    /* accessed during simulation */
3262    ip = (struct inst_t *) __my_malloc(sizeof(struct inst_t));
3263    __top_itab[++tpii] = ip;
3264    /* initialize for unused by top fields */
3265    init_inst(ip);
3266 
3267    /* need to allocate symbol here - because may need name */
3268    /* but this symbol is in no symbol table - cannot be looked up */
3269    /* because there is no virtual top level module */
3270    syp = (struct sy_t *) __my_malloc(sizeof(struct sy_t));
3271    /* copying here in case implementing name removal comp. directives */
3272    syp->synam = __pv_stralloc(mdp->msym->synam);
3273    syp->sytyp = SYM_I;
3274    /* notice all symbols add during input phase */
3275    syp->sydecl = TRUE;
3276    syp->el.eip = ip;
3277    syp->syfnam_ind = mdp->msym->syfnam_ind;
3278    syp->sylin_cnt = mdp->msym->sylin_cnt;
3279    syp->spltsy = NULL;
3280 
3281    ip->isym = syp;
3282    ip->imsym = mdp->msym;
3283    /* top level modules have exactly 1 instance */
3284    mdp->flatinum = 1;
3285    ip->ipxprtab = NULL;
3286    ip->pprm_explicit = FALSE;
3287    ip->ip_explicit = FALSE;
3288    ip->ipins = NULL;
3289   }
3290  __top_ipind = (int32 *) __my_malloc(__numtopm*sizeof(int32));
3291  for (ii = 0; ii < __numtopm; ii++) __top_ipind[ii] = ii;
3292  qsort((char *) __top_ipind, (word32) __numtopm, sizeof(int32), topip_cmp);
3293 
3294  /* table of pointers to root entries */
3295  __it_roots = (struct itree_t **)
3296   __my_malloc(__numtopm*sizeof(struct itree_t *));
3297 
3298  /* allocate root itp entries for each top level module */
3299  for (ii = 0; ii < __numtopm; ii++)
3300   {
3301    /* alloc sets itree value */
3302    itp = (struct itree_t *) __my_malloc(sizeof(struct itree_t));
3303    __it_roots[ii] = itp;
3304    __init_itree_node(itp);
3305    itp->itip = __top_itab[ii];
3306    itp->up_it = NULL;
3307    /* since top instance number must be 0 */
3308    itp->itinum = 0;
3309   }
3310 }
3311 
3312 /*
3313  * comparison routines for sorting top modules index
3314  */
topip_cmp(const void * ii1,const void * ii2)3315 static int32 topip_cmp(const void *ii1, const void *ii2)
3316 {
3317  struct inst_t *ip1, *ip2;
3318 
3319  ip1 = __top_itab[*((int32 *) ii1)];
3320  ip2 = __top_itab[*((int32 *) ii2)];
3321  return(strcmp(ip1->imsym->synam, ip2->imsym->synam));
3322 }
3323 
__init_itree_node(struct itree_t * itp)3324 extern void __init_itree_node(struct itree_t *itp)
3325 {
3326  itp->up_it = NULL;
3327  itp->in_its = NULL;
3328  itp->itip = NULL;
3329  itp->itinum = 0;
3330 }
3331 
3332 /*
3333  * ROUTINES TO DETERMINE ARRAYS OF GATES/INSTANCES RANGES
3334  */
3335 
3336 /*
3337  *
3338  * save all design instance (not task/func) parameters values
3339  *
3340  * only called if need to set gia ranges from params
3341  *
3342  * this is point where gia ranges set so parameters evaluated but must
3343  * be put back because later defparams may change final values
3344  *
3345  * AIV 09/27/06 - since can't be changed do not need to save local params
3346  */
save_all_param_vals(void)3347 static void save_all_param_vals(void)
3348 {
3349  register int32 pi;
3350  register struct mod_t *mdp;
3351  register struct net_t *parm_np;
3352  int32 nbytes;
3353 
3354  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3355   {
3356    if (mdp->mprmnum == 0) continue;
3357 
3358    for (pi = 0, parm_np = &(mdp->mprms[0]); pi < mdp->mprmnum; pi++, parm_np++)
3359     {
3360      nbytes = 2*WRDBYTES*wlen_(parm_np->nwid);
3361      parm_np->nu2.wp = (word32 *) __my_malloc(nbytes);
3362      memcpy(parm_np->nu2.wp, parm_np->nva.wp, nbytes);
3363     }
3364   }
3365 }
3366 
3367 /*
3368  * free all param values - must do this so can reuse nu2 field
3369  */
free_all_param_vals()3370 static void free_all_param_vals()
3371 {
3372  register int32 pi;
3373  register struct mod_t *mdp;
3374  register struct net_t *parm_np;
3375 
3376  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3377   {
3378    if (mdp->mprmnum == 0) continue;
3379 
3380    for (pi = 0, parm_np = &(mdp->mprms[0]); pi < mdp->mprmnum; pi++, parm_np++)
3381     {
3382      /* DBG remove --- */
3383      if (parm_np->nu2.wp == NULL) __misc_terr(__FILE__, __LINE__);
3384      /* --- */
3385      __my_free((char *) parm_np->nu2.wp, 2*WRDBYTES*wlen_(parm_np->nwid));
3386      parm_np->nu2.wp = NULL;
3387     }
3388   }
3389 }
3390 
3391 /*
3392  * evaluate arrays of gates and instances ranges to number
3393  *
3394  * depends on convention that arrays of gate/inst range indices can use
3395  * pound params (parmeter values changed by # parameters) but evaluation
3396  * happens before defparams set (and splitting occurs) so values converted
3397  * to number because component parameters may ultimately have different value
3398  *
3399  * here because no defparams values are static instance tree dependent, i.e.
3400  * do not need to build and use itree
3401  *
3402  * trick is that because by here all modules with array of gate or instance
3403  * ranges determined by pound params, can set range as number
3404  */
set_giarr_ranges(void)3405 static void set_giarr_ranges(void)
3406 {
3407  register int32 gi, ii2;
3408  register struct mod_t *mdp;
3409  struct giarr_t *giap;
3410 
3411  /* assume some ranges do not have pound params because not much work */
3412  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3413   {
3414    __push_wrkitstk(mdp, 0);
3415 
3416    /* if module has arrays of gates expand first */
3417    if (mdp->mgarr != NULL)
3418     {
3419      for (gi = 0; gi < mdp->mgnum; gi++)
3420       {
3421        /* skip non array style gates */
3422        if ((giap = mdp->mgarr[gi]) == NULL) continue;
3423        /* if has pound param need to handle in special code below */
3424        if (giap->gia_rng_has_pnd) continue;
3425 
3426        eval1_arr_of_gates_rng(giap, mdp, (struct itree_t *) NULL, gi);
3427       }
3428     }
3429    if (mdp->miarr != NULL)
3430     {
3431      for (ii2 = 0; ii2 < mdp->minum; ii2++)
3432       {
3433        /* skip non array style instances */
3434        if ((giap = mdp->miarr[ii2]) == NULL) continue;
3435        /* if has pound param need to handle in special code below */
3436        if (giap->gia_rng_has_pnd) continue;
3437 
3438        eval1_arr_of_insts_rng(giap, mdp, (struct itree_t *) NULL, ii2);
3439       }
3440     }
3441    __pop_wrkitstk();
3442   }
3443 
3444  /* if design has no pound params in arrays of g/i ranges, nothing to do */
3445  if (__design_gia_pndparams) set_pnd_gi_rnges();
3446 }
3447 
3448 /*
3449  * evaluate array of gates ranges in module mdp
3450  *
3451  * for non pound param case just works on raw expr
3452  * for pound param case, code called to save and set elaborated (fixed)
3453  * param values from propagating pound params down then afterwards unsaving
3454  * elaborated values because defparams may change
3455  */
eval1_arr_of_gates_rng(struct giarr_t * giap,struct mod_t * mdp,struct itree_t * itp,int32 gi)3456 static void eval1_arr_of_gates_rng(struct giarr_t *giap, struct mod_t *mdp,
3457  struct itree_t *itp, int32 gi)
3458 {
3459  int32 bad_rng;
3460  struct gate_t *gp;
3461  struct xstk_t *xsp1, *xsp2;
3462 
3463  /* if error, since do not know range, convert to non array of gates */
3464  bad_rng = FALSE;
3465  /* know only first (master) auxiliary extra array non nil */
3466  gp = &(mdp->mgates[gi]);
3467 
3468  if (!gi_ndxexpr_chk(giap->giax1, gp->gsym->syfnam_ind,
3469   gp->gsym->sylin_cnt, "of gates first")) bad_rng = TRUE;
3470 
3471  /* save and set pound params by propagating up initial vals down */
3472  if (!bad_rng && itp != NULL) set_gia_expr_pndparms(giap->giax1, itp);
3473 
3474  /* although impossible to have any inst. specific values here */
3475  /* need something on it stk */
3476  if (itp == NULL)
3477   {
3478    /* if no passed itp - use wrk dummy inst (right mod) */
3479    xsp1 = __eval_xpr(giap->giax1);
3480   }
3481  else
3482   {
3483    __push_itstk(itp);
3484    xsp1 = __eval_xpr(giap->giax1);
3485    __pop_itstk();
3486   }
3487 
3488  /* unsave if pound case */
3489  if (!bad_rng && itp != NULL) unsave_gia_expr_pndparms(giap->giax1, itp);
3490 
3491  if (!gi_ndxval_chk(xsp1, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
3492   "of gates first")) bad_rng = TRUE;
3493 
3494  if (!gi_ndxexpr_chk(giap->giax2, gp->gsym->syfnam_ind,
3495   gp->gsym->sylin_cnt, "of gates second")) bad_rng = TRUE;
3496 
3497  /* save and set pound params by propagating up initial vals down */
3498  if (!bad_rng && itp != NULL) set_gia_expr_pndparms(giap->giax2, itp);
3499 
3500  if (itp == NULL)
3501   {
3502    /* if no passed itp - use wrk dummy inst (right mod) */
3503    xsp2 = __eval_xpr(giap->giax2);
3504   }
3505  else
3506   {
3507    __push_itstk(itp);
3508    xsp2 = __eval_xpr(giap->giax2);
3509    __pop_itstk();
3510   }
3511 
3512  if (!bad_rng && itp != NULL) unsave_gia_expr_pndparms(giap->giax2, itp);
3513 
3514  if (!gi_ndxval_chk(xsp2, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
3515   "of gates second")) bad_rng = TRUE;
3516  /* if error do not know range - convert back to one gate */
3517  if (!bad_rng)
3518   {
3519    giap->gia1 = (int32) xsp1->ap[0];
3520    giap->gia2 = (int32) xsp2->ap[0];
3521   }
3522  __pop_xstk();
3523  __pop_xstk();
3524 }
3525 
3526 /*
3527  * check a gate or instance array index constant expression
3528  * returns F on error
3529  */
gi_ndxexpr_chk(struct expr_t * xp,int32 lfnind,int32 lcnt,char * emsg)3530 static int32 gi_ndxexpr_chk(struct expr_t *xp, int32 lfnind, int32 lcnt,
3531  char *emsg)
3532 {
3533  if (__expr_has_glb(xp) || !__chk_giarr_ndx_expr(xp))
3534   {
3535    __gferr(1161, lfnind, lcnt,
3536     "array %s declaration index expression %s error - pound parameters and constants only",
3537     emsg, __msgexpr_tostr(__xs, xp));
3538    return(FALSE);
3539   }
3540  return(TRUE);
3541 }
3542 
3543 /*
3544  * check a gate or instance array value for 32 bits non x/z
3545  * emits error and returns F on error
3546  *
3547  * LOOKATME - maybe need warn or inform if >32 bits but higher 0's
3548  */
gi_ndxval_chk(struct xstk_t * xsp,int32 lfnind,int32 lcnt,char * emsg)3549 static int32 gi_ndxval_chk(struct xstk_t *xsp, int32 lfnind, int32 lcnt, char *emsg)
3550 {
3551  if (xsp->xslen > WBITS)
3552   {
3553    if (!vval_is0_(&(xsp->ap[1]), xsp->xslen - 64)
3554     || !vval_is0_(xsp->bp, xsp->xslen))
3555     {
3556      __gferr(1189, lfnind, lcnt,
3557       "array %s declaration index value %s not required %d bit non x/z number",
3558       emsg, __regab_tostr(__xs, xsp->ap, xsp->bp, xsp->xslen, BHEX, FALSE),
3559       WBITS);
3560      return(FALSE);
3561     }
3562   }
3563  return(TRUE);
3564 }
3565 
3566 /*
3567  * evaluate array of instances ranges in mdp
3568  *
3569  * for non pound param case just works on raw expr
3570  * for pound param case, code called to save and set elaborated (fixed)
3571  * param values from propagating pound params down then afterwards unsaving
3572  * elaborated values because defparams may change
3573  */
eval1_arr_of_insts_rng(struct giarr_t * giap,struct mod_t * mdp,struct itree_t * itp,int32 ii)3574 static void eval1_arr_of_insts_rng(struct giarr_t *giap, struct mod_t *mdp,
3575  struct itree_t *itp, int32 ii)
3576 {
3577  int32 bad_rng;
3578  struct inst_t *ip;
3579  struct xstk_t *xsp1, *xsp2;
3580 
3581  /* if error, since do not know range, convert to non array of gates */
3582  bad_rng = FALSE;
3583  /* know only first (master) auxiliary extra array non nil */
3584  ip = &(mdp->minsts[ii]);
3585 
3586  if (!gi_ndxexpr_chk(giap->giax1, ip->isym->syfnam_ind,
3587   ip->isym->sylin_cnt, "of instances first")) bad_rng = TRUE;
3588 
3589  /* save and set pound params by propagating up initial vals down */
3590  if (!bad_rng && itp != NULL) set_gia_expr_pndparms(giap->giax1, itp);
3591 
3592  /* although impossible to have any inst. specific values here */
3593  /* need something on it stk */
3594  if (itp == NULL)
3595   {
3596    /* if no passed itp - use wrk dummy inst (right mod) */
3597    xsp1 = __eval_xpr(giap->giax1);
3598   }
3599  else
3600   {
3601    __push_itstk(itp);
3602    xsp1 = __eval_xpr(giap->giax1);
3603    __pop_itstk();
3604   }
3605 
3606  /* unsave if pound case */
3607  if (!bad_rng && itp != NULL) unsave_gia_expr_pndparms(giap->giax1, itp);
3608 
3609  if (!gi_ndxval_chk(xsp1, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
3610   "of instances first")) bad_rng = TRUE;
3611 
3612  if (!gi_ndxexpr_chk(giap->giax2, ip->isym->syfnam_ind,
3613   ip->isym->sylin_cnt, "of gates second")) bad_rng = TRUE;
3614 
3615  /* save and set pound params by propagating up initial vals down */
3616  if (!bad_rng && itp != NULL) set_gia_expr_pndparms(giap->giax2, itp);
3617 
3618  if (itp == NULL)
3619   {
3620    /* if no passed itp - use wrk dummy inst (right mod) */
3621    xsp2 = __eval_xpr(giap->giax2);
3622   }
3623  else
3624   {
3625    __push_itstk(itp);
3626    xsp2 = __eval_xpr(giap->giax2);
3627    __pop_itstk();
3628   }
3629 
3630  /* unsave if pound case */
3631  if (!bad_rng && itp != NULL) unsave_gia_expr_pndparms(giap->giax2, itp);
3632 
3633  if (!gi_ndxval_chk(xsp2, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
3634   "of instances second")) bad_rng = TRUE;
3635  /* if error do not know range - convert back to one gate */
3636  if (!bad_rng)
3637   {
3638    giap->gia1 = (int32) xsp1->ap[0];
3639    giap->gia2 = (int32) xsp2->ap[0];
3640   }
3641  __pop_xstk();
3642  __pop_xstk();
3643 }
3644 
3645 /*
3646  * set all module instance gi ranges with pound params
3647  *
3648  * only need to do once per module because modules with pound params
3649  * in gi ranges always split off to one instance
3650  *
3651  * final hard case where need itree that is discarded after this step
3652  */
set_pnd_gi_rnges(void)3653 static void set_pnd_gi_rnges(void)
3654 {
3655  register int32 ii;
3656  struct itree_t *itp;
3657  struct mod_t *mdp;
3658 
3659  __bld_flat_itree();
3660 
3661  /* know top modules never have pound params */
3662  for (ii = 0; ii < __numtopm; ii++)
3663   {
3664    itp = __it_roots[ii];
3665    mdp = itp->itip->imsym->el.emdp;
3666    set2_pnd_gi_rnges(mdp, itp);
3667   }
3668 
3669  /* last step free itree - need to rebuild after defparam splitting */
3670  __free_flat_itree();
3671 }
3672 
3673 /*
3674  * descend down in itree setting pound param gia ranges
3675  *
3676  * when see first instance of module set ranges for all instances
3677  * and mark - after that just ignore instances of module
3678  */
set2_pnd_gi_rnges(struct mod_t * up_mdp,struct itree_t * up_itp)3679 static void set2_pnd_gi_rnges(struct mod_t *up_mdp, struct itree_t *up_itp)
3680 {
3681  register int32 gi, ii, ii2;
3682  struct mod_t *imdp;
3683  struct itree_t *itp;
3684  struct giarr_t *giap;
3685 
3686  /* first descend */
3687  for (ii = 0; ii < up_mdp->minum; ii++)
3688   {
3689    itp = &(up_itp->in_its[ii]);
3690    /* once module done, know all under also done - no need to descend */
3691    imdp = itp->itip->imsym->el.emdp;
3692    if (imdp->mpnd_girng_done) continue;
3693 
3694    /* need to descend even if does not have any in gia range pnd params */
3695    set2_pnd_gi_rnges(imdp, itp);
3696   }
3697  /* when this returns will be done even if none in range */
3698  up_mdp->mpnd_girng_done = TRUE;
3699  if (!up_mdp->mpndprm_ingirng) return;
3700 
3701  /* eval arrays of g/i ranges containing pnd params - others already done */
3702  if (up_mdp->mgarr != NULL)
3703   {
3704    for (gi = 0; gi < up_mdp->mgnum; gi++)
3705     {
3706      /* skip non array style gates */
3707      if ((giap = up_mdp->mgarr[gi]) == NULL) continue;
3708 
3709      /* if does not contain pound param already done */
3710      if (!giap->gia_rng_has_pnd) continue;
3711 
3712      __push_wrkitstk(up_mdp, 0);
3713      eval1_arr_of_gates_rng(giap, up_mdp, up_itp, gi);
3714      __pop_wrkitstk();
3715     }
3716   }
3717  if (up_mdp->miarr != NULL)
3718   {
3719    for (ii2 = 0; ii2 < up_mdp->minum; ii2++)
3720     {
3721      /* skip non array style instances */
3722      if ((giap = up_mdp->miarr[ii2]) == NULL) continue;
3723      /* if does not contain pound param already done */
3724      if (!giap->gia_rng_has_pnd) continue;
3725 
3726      __push_wrkitstk(up_mdp, 0);
3727      eval1_arr_of_insts_rng(giap, up_mdp, up_itp, ii2);
3728      __pop_wrkitstk();
3729     }
3730   }
3731 }
3732 
3733 /*
3734  * set all pound params in one g/i array range expression
3735  *
3736  * when done know all params in g/i array range expr. values elaborated (fixed)
3737  */
set_gia_expr_pndparms(struct expr_t * xp,struct itree_t * itp)3738 static void set_gia_expr_pndparms(struct expr_t *xp, struct itree_t *itp)
3739 {
3740  struct net_t *np;
3741 
3742  if (__isleaf(xp))
3743   {
3744    if (xp->optyp == ID && xp->lu.sy->sytyp == SYM_N)
3745     {
3746      np = xp->lu.sy->el.enp;
3747      if (np->n_isaparam) set1_giarr_pndparm(np, itp);
3748     }
3749    return;
3750   }
3751  if (xp->lu.x != NULL) set_gia_expr_pndparms(xp->lu.x, itp);
3752  if (xp->ru.x != NULL) set_gia_expr_pndparms(xp->ru.x, itp);
3753 }
3754 
3755 /*
3756  * for parameter determine if pound and if so set value by setting
3757  * values in up instance pound expr and evaluating it
3758  * new up value is then set as value of down parameter
3759  * may need to work up to top of itree
3760  */
set1_giarr_pndparm(struct net_t * np,struct itree_t * itp)3761 static void set1_giarr_pndparm(struct net_t *np, struct itree_t *itp)
3762 {
3763  int32 pndpi;
3764  struct itree_t *up_itp;
3765  struct mod_t *up_mdp;
3766  struct inst_t *up_ip;
3767  struct expr_t *up_pndxp;
3768  struct xstk_t *xsp;
3769  char s1[RECLEN];
3770 
3771  /* may need to access parameter (not pound) in top level module */
3772  up_itp = itp->up_it;
3773  /* if top or no pound params or no pound expr. passed down for this, done */
3774  up_ip = itp->itip;
3775  if (up_ip->ipxprtab == NULL) return;
3776  up_mdp = up_ip->imsym->el.emdp;
3777  pndpi = ((byte *) np - (byte *) up_mdp->mprms)/sizeof(struct net_t);
3778  if (up_ip->ipxprtab[pndpi] == NULL) return;
3779 
3780  /* know this is pound param */
3781  up_pndxp = up_ip->ipxprtab[pndpi];
3782 
3783  /* work up evaluating parmeters changing pound params to passed down val */
3784  /* this sets values in pound passed (up) expr - if it contains pound */
3785  /* params recursively repeats up as far as needed (maybe to top) */
3786  set_gia_expr_pndparms(up_pndxp, up_itp);
3787  /* now all pound param in expr. replaced by passed down pound value */
3788 
3789  /* although pound params never instance specific must access constants */
3790  /* from up module con tab */
3791  __push_itstk(up_itp);
3792  xsp = __eval_xpr(up_pndxp);
3793  __pop_itstk();
3794 
3795  /* change value - IS form impossible here */
3796  sprintf(s1, "%s (pound param)", __msg2_blditree(__xs, itp));
3797  __cnvt_param_stkval(xsp, up_pndxp, np, s1);
3798  __assgn_nonis_param(np, up_pndxp, xsp);
3799  __pop_xstk();
3800 
3801  /* free and put back temporary "as of now" parameter values of params */
3802  /* in up pound expr */
3803  unsave_gia_expr_pndparms(up_pndxp, up_itp);
3804 }
3805 
3806 /*
3807  * free and unsave pound params in expression
3808  *
3809  * non up pound params just ignored initial in source value was not changed
3810  * only needed for this expr. because if pnds worked up, evaled and unsaved
3811  */
unsave_gia_expr_pndparms(struct expr_t * xp,struct itree_t * itp)3812 static void unsave_gia_expr_pndparms(struct expr_t *xp, struct itree_t *itp)
3813 {
3814  int32 pndpi;
3815  struct net_t *np;
3816  struct itree_t *up_itp;
3817  struct inst_t *ip;
3818  struct mod_t *mdp;
3819 
3820  if (__isleaf(xp))
3821   {
3822    if (xp->optyp == ID && xp->lu.sy->sytyp == SYM_N)
3823     {
3824      np = xp->lu.sy->el.enp;
3825      if (np->n_isaparam)
3826       {
3827        if ((up_itp = itp->up_it) == NULL) return;
3828        ip = up_itp->itip;
3829        if (ip->ipxprtab == NULL) return;
3830        mdp = itp->itip->imsym->el.emdp;
3831        pndpi = ((byte *) np - (byte *) mdp->mprms)/sizeof(struct net_t);
3832        if (ip->ipxprtab[pndpi] == NULL) return;
3833 
3834        /* DBG remove --- */
3835        if (np->srep != SR_PNUM) __misc_terr(__FILE__, __LINE__);
3836        if (np->nu2.wp == NULL) __misc_terr(__FILE__, __LINE__);
3837        /* --- */
3838 
3839        /* need to unsave param value by copying back */
3840        /* this puts back intial value that is always SR_PNUM */
3841        memcpy(np->nva.wp, np->nu2.wp, 2*WRDBYTES*wlen_(np->nwid));
3842       }
3843     }
3844    return;
3845   }
3846  if (xp->lu.x != NULL) unsave_gia_expr_pndparms(xp->lu.x, itp);
3847  if (xp->ru.x != NULL) unsave_gia_expr_pndparms(xp->ru.x, itp);
3848 }
3849 
3850 /*
3851  * ROUTINES TO SPLIT ARRAY OF GATES AND INSTANCES
3852  */
3853 
3854 /*
3855  * rebuild mgates and miarr tables for each module with arrays of g/i
3856  *
3857  * for g/i arrays original symbol and pins store in giap
3858  * BEWARE - can not access symbol table in here until sorted and reconnected
3859  *          at end of gate and inst expansion
3860  */
rebld_mod_giarrs(void)3861 static void rebld_mod_giarrs(void)
3862 {
3863  register int32 i, i2, i3;
3864  register struct mod_t *mdp, *imdp;
3865  int32 has_iarrs, newgnum, newinum, giawid, j;
3866  int32 arrsynum, bi, gia_dir, new_stsiz;
3867  struct gate_t *gptab, *gp;
3868  struct inst_t *iptab, *ip;
3869  struct giarr_t *giap, **giatab;
3870  struct srcloc_t **sloctabp;
3871 
3872  has_iarrs = FALSE;
3873  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3874   {
3875    if (mdp->mgarr == NULL && mdp->miarr == NULL) continue;
3876 
3877    __push_wrkitstk(mdp, 0);
3878    arrsynum = 0;
3879    /* first count number of new */
3880    if (mdp->mgarr != NULL)
3881     {
3882      /* compute new size of mgates table */
3883      for (i = 0, newgnum = 0; i < mdp->mgnum; i++)
3884       {
3885        if ((giap = mdp->mgarr[i]) == NULL) { newgnum++; continue; }
3886        giap->gia_bi = newgnum;
3887        newgnum += __get_giarr_wide(giap);
3888        /* one extra symbol for every element of array but original gate */
3889        /* counted as one */
3890        arrsynum++;
3891       }
3892     }
3893    else newgnum = mdp->mgnum;
3894 
3895    if (mdp->miarr != NULL)
3896     {
3897      has_iarrs = TRUE;
3898      /* compute new size of minsts table */
3899      for (i = 0, newinum = 0; i < mdp->minum; i++)
3900       {
3901        if ((giap = mdp->miarr[i]) == NULL) { newinum++; continue; }
3902        giap->gia_bi = newinum;
3903        newinum += __get_giarr_wide(giap);
3904        arrsynum++;
3905       }
3906     }
3907    else newinum = mdp->minum;
3908 
3909    /* allocate room for new symbols now that know how many */
3910    /* notice every gate name symbol including first added */
3911    /* original moved to giap */
3912    new_stsiz = mdp->msymtab->numsyms + (newgnum - mdp->mgnum)
3913     + (newinum - mdp->minum) + arrsynum;
3914    /* SJM 07/02/05 - can't use realloc because need old stsyms during */
3915    /* build of new minst iptab - old worked only if realloc didn't move */
3916    /* can't free stsyms yet */
3917    __wrkstab = (struct sy_t **) __my_malloc(new_stsiz*sizeof(struct sy_t *));
3918    memcpy(__wrkstab, mdp->msymtab->stsyms,
3919     mdp->msymtab->numsyms*sizeof(struct sy_t *));
3920 
3921    __last_sy = mdp->msymtab->numsyms - 1;
3922    /* DBG remove --- */
3923    if (!mdp->msymtab->freezes) __misc_terr(__FILE__, __LINE__);
3924    /* --- */
3925 
3926    if (mdp->mgarr != NULL)
3927     {
3928      giatab = (struct giarr_t **)
3929       __my_malloc(newgnum*sizeof(struct giarr_t *));
3930      gptab = (struct gate_t *) __my_malloc(newgnum*sizeof(struct gate_t));
3931      /* copy from old to new gia and gate tables */
3932      /* i moves through old mgates, i2 through new */
3933      for (i = 0, i2 = 0; i < mdp->mgnum; i++)
3934       {
3935        if ((giap = mdp->mgarr[i]) == NULL)
3936         {
3937          giatab[i2] = NULL;
3938          /* copy body (insides) */
3939          gp = &(gptab[i2]);
3940          *gp = mdp->mgates[i];
3941          /* SJM 07/02/05 - for non arrayed insts in mod with inst arrays, */
3942          /* need to connect the sym to new iptab entry - needed because */
3943          /* ip tab is array of inst_t records not array of ptrs */
3944          gp->gsym->el.egp = gp;
3945          i2++;
3946          continue;
3947         }
3948        /* move original gpins to giap and point all to it */
3949        /* for now all gpins lists same and >1 ptrs to it */
3950        giap->giapins = mdp->mgates[i].gpins;
3951        giap->gia_base_syp = mdp->mgates[i].gsym;
3952        giap->gia_base_syp->el.egp = &(gptab[i2]);
3953        giap->gia_base_syp->sy_giabase = TRUE;
3954        giap->gia_xpnd = TRUE;
3955        giawid = __get_giarr_wide(giap);
3956        bi = giap->gia1;
3957        gia_dir = (giap->gia1 > giap->gia2) ? -1 : 1;
3958 
3959        /* stored in gia1 to gia2 order - not normalized to h:l as for nets */
3960        for (i3 = i2; i3 < i2 + giawid; i3++, bi += gia_dir)
3961         {
3962          /* point all expanded to same index record - can always find first */
3963          giatab[i3] = giap;
3964 
3965          /* copy body of declared array of gates */
3966          gp = &(gptab[i3]);
3967          *gp = mdp->mgates[i];
3968          gp->g_du.pdels = __copy_dellst(mdp->mgates[i].g_du.pdels);
3969          add_new_gsym(gp, bi);
3970         }
3971        i2 += giawid;
3972       }
3973      /* finally free old gate tables and allocate new */
3974      __my_free((char *) mdp->mgates, mdp->mgnum*sizeof(struct gate_t));
3975      mdp->mgates = gptab;
3976      mdp->mgarr = giatab;
3977      mdp->mgnum = newgnum;
3978     }
3979    if (mdp->miarr != NULL)
3980     {
3981      giatab = (struct giarr_t **)
3982       __my_malloc(newinum*sizeof(struct giarr_t *));
3983      iptab = (struct inst_t *) __my_malloc(newinum*sizeof(struct inst_t));
3984      sloctabp = (struct srcloc_t **)
3985       __my_malloc(newinum*sizeof(struct srcloc_t *));
3986 
3987      /* copy from old to new gia and gate tables */
3988      /* i moves through old minsts, i2 through new */
3989      for (i = 0, i2 = 0; i < mdp->minum; i++)
3990       {
3991        if ((giap = mdp->miarr[i]) == NULL)
3992         {
3993          /* non array inst - just copy */
3994          giatab[i2] = NULL;
3995 
3996          ip = &(iptab[i2]);
3997          *ip = mdp->minsts[i];
3998          /* SJM 07/02/05 - for non arrayed insts in mod with inst arrays, */
3999          /* need to connect the sym to new iptab entry - needed because */
4000          /* ip tab is array of inst_t records not array of ptrs */
4001          ip->isym->el.eip = ip;
4002 
4003          /* here just move ptr */
4004          sloctabp[i2] = mdp->iploctab[i];
4005          mdp->iploctab[i] = NULL;
4006          i2++;
4007          continue;
4008         }
4009 
4010        giap->giapins = mdp->minsts[i].ipins;
4011        giap->gia_base_syp = mdp->minsts[i].isym;
4012        giap->gia_base_syp->el.eip = &(iptab[i2]);
4013        giap->gia_base_syp->sy_giabase = TRUE;
4014        giap->gia_xpnd = TRUE;
4015 
4016        /* stored in gia1 to gia2 order - not normalized to h:l as for nets */
4017        giawid = __get_giarr_wide(giap);
4018        bi = giap->gia1;
4019        gia_dir = (giap->gia1 > giap->gia2) ? -1 : 1;
4020        /* stored in gia1 to gia2 order - not normalized to h:l as for nets */
4021        for (i3 = i2; i3 < i2 + giawid; i3++, bi += gia_dir)
4022         {
4023          /* point all expanded to same index record - can always find first */
4024          giatab[i3] = giap;
4025          ip = &(iptab[i3]);
4026          /* copy body of declared array of insts - no need to initialize */
4027          *ip = mdp->minsts[i];
4028          imdp = ip->imsym->el.emdp;
4029 
4030          /* symbol from base array of insts must point to first */
4031          if (i3 == i2)
4032           {
4033            /* first time move */
4034            sloctabp[i3] = mdp->iploctab[i];
4035            mdp->iploctab[i] = NULL;
4036           }
4037          else
4038           {
4039            /* thereafter alloc and copy */
4040            if (imdp->mpnum == 0) sloctabp[i3] = NULL;
4041            else
4042             {
4043              /* array of ptr to array of src locs each size different */
4044              /* because each inst. has different number of pins */
4045              sloctabp[i3] = (struct srcloc_t *)
4046               __my_malloc(imdp->mpnum*sizeof(struct srcloc_t));
4047              /* copy each source loc record */
4048              for (j = 0; j < imdp->mpnum; j++)
4049               sloctabp[i3][j] = sloctabp[i2][j];
4050             }
4051           }
4052          ip->ipxprtab = copy_pndxtab(&(mdp->minsts[i]));
4053          add_new_isym(ip, bi);
4054         }
4055        i2 += giawid;
4056        if (mdp->minstnum == 1 && giawid > 1) mdp->minstnum = 2;
4057       }
4058      /* finally free old insts tables and allocate new */
4059      __my_free((char *) mdp->minsts, mdp->minum*sizeof(struct inst_t));
4060      __my_free((char *) mdp->miarr, mdp->minum*sizeof(struct giarr_t *));
4061      __my_free((char *) mdp->iploctab, mdp->minum*sizeof(struct srcloc_t *));
4062      mdp->minsts = iptab;
4063      mdp->miarr = giatab;
4064      mdp->iploctab = sloctabp;
4065      mdp->minum = newinum;
4066     }
4067 
4068    /* must re-sort symbol table - because table of ptr el union right */
4069    qsort((char *) __wrkstab, (word32) new_stsiz, sizeof(struct sy_t *),
4070     gia_sym_cmp);
4071    /* SJM 07/02/05 - free the mod's symbtab stsyms to fix memory leak */
4072    /* symtab is ptr to syms - for non i/g array's sym record still used */
4073    __my_free((char *) mdp->msymtab->stsyms,
4074     mdp->msymtab->numsyms*sizeof(struct sy_t *));
4075    mdp->msymtab->numsyms = new_stsiz;
4076    mdp->msymtab->stsyms = __wrkstab;
4077    __pop_wrkitstk();
4078   }
4079  /* if any any arrays of instances, must recount */
4080  if (has_iarrs) count_flat_insts();
4081  /* mod level table remains same since more instance but no more types */
4082 }
4083 
4084 /*
4085  * comparison routine for sorting symbol table after expand g/i added
4086  */
gia_sym_cmp(const void * sy1,const void * sy2)4087 static int32 gia_sym_cmp(const void *sy1, const void *sy2)
4088 {
4089  return(strcmp((*((struct sy_t **) sy1))->synam,
4090   (*(struct sy_t **) sy2)->synam));
4091 }
4092 
4093 /*
4094  * get width of array of inst/gate
4095  */
__get_giarr_wide(struct giarr_t * giap)4096 extern int32 __get_giarr_wide(struct giarr_t *giap)
4097 {
4098  int32 r1, r2;
4099 
4100  r1 = giap->gia1;
4101  r2 = giap->gia2;
4102  /* DBG remove -- */
4103  if (r1 == -1 || r2 == -1) __arg_terr(__FILE__, __LINE__);
4104  /* --- */
4105  return((r1 >= r2) ? (r1 - r2 + 1) : (r2 - r1 + 1));
4106 }
4107 
4108 /*
4109  * routine to add new (still unusuable and unsorted) symbol table
4110  * because stored in range order never need to normalize here
4111  */
add_new_gsym(struct gate_t * gp,int32 bi)4112 static void add_new_gsym(struct gate_t *gp, int32 bi)
4113 {
4114  struct sy_t *gsyp;
4115  char nsynam[2*IDLEN];
4116 
4117  gsyp = (struct sy_t *) __my_malloc(sizeof(struct sy_t));
4118  *gsyp = *(gp->gsym);
4119  sprintf(nsynam, "%s[%d]", gp->gsym->synam, bi);
4120  gsyp->synam = __pv_stralloc(nsynam);
4121  __wrkstab[++__last_sy] = gsyp;
4122  gp->gsym = gsyp;
4123  gsyp->el.egp = gp;
4124 }
4125 
4126 /*
4127  * routine to update new (still unusuable and unsorted) symbol table
4128  * because stored in range order never need to normalize here
4129  */
add_new_isym(struct inst_t * ip,int32 bi)4130 static void add_new_isym(struct inst_t *ip, int32 bi)
4131 {
4132  struct sy_t *isyp;
4133  char nsynam[2*IDLEN];
4134 
4135  isyp = (struct sy_t *) __my_malloc(sizeof(struct sy_t));
4136  *isyp = *(ip->isym);
4137  sprintf(nsynam, "%s[%d]", ip->isym->synam, bi);
4138  isyp->synam = __pv_stralloc(nsynam);
4139  __wrkstab[++__last_sy] = isyp;
4140  ip->isym = isyp;
4141  isyp->el.eip = ip;
4142 }
4143 
4144 /*
4145  * routine to dump minsts for every module in the design
4146  */
__dmp_dsgn_minst(char * hdr_s)4147 extern void __dmp_dsgn_minst(char *hdr_s)
4148 {
4149  register struct mod_t *mdp;
4150  int32 ii;
4151  struct inst_t *ip;
4152 
4153  __dbg_msg("%s ===>\n", hdr_s);
4154  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4155   {
4156    __dbg_msg("+++ dumping instances in module %s:\n", mdp->msym->synam);
4157    for (ii = 0; ii < mdp->minum; ii++)
4158     {
4159      ip = &(mdp->minsts[ii]);
4160      __dmp_1minst(ip);
4161     }
4162   }
4163 }
4164 
4165 /*
4166  * dmp one minst element
4167  */
__dmp_1minst(struct inst_t * ip)4168 extern void __dmp_1minst(struct inst_t *ip)
4169 {
4170  char s1[RECLEN];
4171 
4172  if (ip->ipxprtab != NULL)
4173   {
4174    sprintf(s1, "ipxprtab[0]=%s", __msgexpr_tostr(__xs, ip->ipxprtab[0]));
4175   }
4176  else strcpy(s1, "[no ipxprtab]");
4177  __dbg_msg("     inst %s type %s %s\n", ip->isym->synam, ip->imsym->synam,
4178   s1);
4179  if (ip->isym->el.eip != ip)
4180   {
4181    __dbg_msg("inst %s type %s - other inst %s type %s\n",
4182      ip->isym->el.eip->isym->synam, ip->isym->el.eip->imsym->synam,
4183      ip->isym->synam, ip->imsym->synam);
4184    __misc_terr(__FILE__, __LINE__);
4185   }
4186 }
4187 
4188 /*
4189  * ROUTINES TO CHECK DEFPARAMS
4190  */
4191 
4192 /*
4193  * check defparam format parameter statements
4194  *
4195  * must be done before pound splitting because pound splitting copy
4196  * of defparam grefs must copy glb ref components
4197  *
4198  * if error, undef symbol - must ignore undef. symbols later
4199  */
chk_defparams(void)4200 static void chk_defparams(void)
4201 {
4202  register struct dfparam_t *dfpp;
4203  register struct mod_t *mdp;
4204  struct dfparam_t *dfpp2, *last_dfpp;
4205 
4206  __num_dfps = 0;
4207  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4208   {
4209    __push_wrkitstk(mdp, 0);
4210 
4211    for (last_dfpp = NULL, dfpp = __inst_mod->mdfps; dfpp != NULL;)
4212     {
4213      dfpp2 = dfpp->dfpnxt;
4214      __sfnam_ind = dfpp->dfpfnam_ind;
4215      __slin_cnt = dfpp->dfplin_cnt;
4216 
4217      /* must check and set widths here since can contain parameters defined */
4218      /* later in source according to LRM */
4219      if (!__chk_paramexpr(dfpp->dfpxrhs, 0))
4220       {
4221        __sgferr(1035,
4222         "defparam %s right hand side error - parameters and constants only",
4223         __msgexpr_tostr(__xs, dfpp->dfpxlhs));
4224        __free2_xtree(dfpp->dfpxrhs);
4225        __set_numval(dfpp->dfpxrhs, ALL1W, ALL1W, WBITS);
4226       }
4227      /* check and set value during src read since only previously defined */
4228      /* params on rhs and must use initial values */
4229 
4230      /* SJM 01/27/04 - old code was wrongly evaling defparam rhs to number */
4231      /* must be left as expr since dfps may need changed dependend param */
4232 
4233      if (!lhs_chk1dfparam(dfpp))
4234       {
4235        /* if error, remove from list on error */
4236        if (last_dfpp == NULL) __inst_mod->mdfps = dfpp2;
4237        else last_dfpp->dfpnxt = dfpp2;
4238        /* free the defparam - compeletly removed from circuit */
4239        __free_1dfparam(dfpp);
4240       }
4241      else { last_dfpp = dfpp; __num_dfps++; }
4242      dfpp = dfpp2;
4243     }
4244    __pop_wrkitstk();
4245   }
4246  /* final step is freeing all defparams in gref table, no longer needed */
4247  free_gone_glbs();
4248 }
4249 
4250 /*
4251  * check parameter lhs expression and return
4252  * resolution of defparam lhs global in here
4253  *
4254  * array of instance selects illegal in defparams
4255  */
lhs_chk1dfparam(struct dfparam_t * dfpp)4256 static int32 lhs_chk1dfparam(struct dfparam_t *dfpp)
4257 {
4258  struct gref_t *grp;
4259  struct expr_t *lhsndp;
4260  struct sy_t *syp;
4261  struct net_t *np;
4262 
4263  lhsndp = dfpp->dfpxlhs;
4264  grp = NULL;
4265  if (lhsndp->optyp == GLBREF)
4266   {
4267    grp = lhsndp->ru.grp;
4268    grp->gr_defparam = TRUE;
4269    /* know here none of the special scope or dumpvars bits set */
4270    __resolve_glbnam(grp);
4271    if (lhsndp->optyp == ID) goto is_local;
4272    __num_glbdfps++;
4273    /* if error in resolving global cannot check here - syp not set */
4274    if (grp->gr_err) return(FALSE);
4275    /* upward relative defparams illegal to match Cadence */
4276    if (grp->upwards_rel)
4277     {
4278      __sgferr(760,
4279       "upward relative defparam lvalue %s illegal - must be rooted or downward relative",
4280       grp->gnam);
4281      grp->upwards_rel = FALSE;
4282      grp->gr_err = TRUE;
4283      return(FALSE);
4284     }
4285 
4286    syp = lhsndp->lu.sy;
4287    np = syp->el.enp;
4288    if (syp->sytyp != SYM_N || !np->n_isaparam)
4289     {
4290      __sgferr(755, "defparam hierarchical name lvalue %s is not a parameter",
4291       grp->gnam);
4292      grp->gr_err = TRUE;
4293      return(FALSE);
4294     }
4295 
4296    /* AIV 09/27/06 - lhs of a defparam cannot be a localparam */
4297    if (np->nu.ct->p_locparam)
4298     {
4299      __sgferr(3430, "defparam hierarchical name lvalue %s cannot be a localparam",
4300       grp->gnam);
4301      grp->gr_err = TRUE;
4302      return(FALSE);
4303     }
4304 
4305    /* for any array of inst selects in defparams are illegal */
4306    if (gref_has_giarr_ndxes(grp))
4307     {
4308      __sgferr(691,
4309       "defparam lvalue %s instance array select illegal - use pound param",
4310       grp->gnam);
4311      grp->gr_err = TRUE;
4312      return(FALSE);
4313     }
4314 
4315    /* now have defparam global lhs path - so done with global move to defp */
4316    /* move guts of gref to defparam nil fields and mark global as gone */
4317    set_1defparam_iis(dfpp, grp);
4318    dfpp->gdfpnam = grp->gnam;
4319    grp->gnam = NULL;
4320 
4321    grp->last_gri = -1;
4322    dfpp->targsyp = grp->targsyp;
4323    dfpp->dfptskp = grp->targtskp;
4324    grp->targsyp = NULL;
4325    /* must remove gref since contents in defparam */
4326    grp->gr_gone = TRUE;
4327    lhsndp->ru.grp = NULL;
4328    return(TRUE);
4329   }
4330 
4331 is_local:
4332  /* this is local - if in module gref - converted to simple by here */
4333  syp = lhsndp->lu.sy;
4334  np = syp->el.enp;
4335  if (syp->sytyp != SYM_N || !np->n_isaparam)
4336   {
4337    __sgferr(756, "defparam local lvalue variable %s not a parameter",
4338     syp->synam);
4339    if (grp != NULL) grp->gr_err = TRUE;
4340    return(FALSE);
4341   }
4342  /* AIV 09/27/06 - lhs of a defparam cannot be a localparam */
4343  if (np->nu.ct->p_locparam)
4344   {
4345    __sgferr(3430, "defparam local lvalue variable %s cannot be a localparam",
4346     syp->synam);
4347    if (grp != NULL) grp->gr_err = TRUE;
4348    return(FALSE);
4349   }
4350  dfpp->dfp_local = TRUE;
4351  dfpp->gdfpnam = __pv_stralloc(syp->synam);
4352  dfpp->in_mdp = __inst_mod;
4353  dfpp->targsyp = syp;
4354  __num_locdfps++;
4355  return(TRUE);
4356 }
4357 
4358 /*
4359  * return T if resolved global name has instance array index component
4360  */
gref_has_giarr_ndxes(struct gref_t * grp)4361 static int32 gref_has_giarr_ndxes(struct gref_t *grp)
4362 {
4363  register int32 gri;
4364 
4365  for (gri = 0; gri <= grp->last_gri; gri++)
4366   {
4367    if (grp->grxcmps[gri] != NULL) return(TRUE);
4368   }
4369  return(FALSE);
4370 }
4371 
4372 /*
4373  * set defparam itree ii paths
4374  *
4375  * needed now because copying changes instance symbols
4376  * later will convert downward relative dfpiis to rooted and 1 design list
4377  */
set_1defparam_iis(struct dfparam_t * dfpp,struct gref_t * grp)4378 static void set_1defparam_iis(struct dfparam_t *dfpp,
4379  struct gref_t *grp)
4380 {
4381  register int32 gi;
4382  int32 ii;
4383  byte *bp1, *bp2;
4384  struct sy_t *syp;
4385  struct inst_t *ip;
4386  struct mod_t *up_mdp;
4387 
4388  dfpp->last_dfpi = grp->last_gri;
4389  dfpp->dfpiis = (int32 *) __my_malloc((dfpp->last_dfpi + 1)*sizeof(int32));
4390  dfpp->dfp_rooted = (grp->is_rooted) ? TRUE : FALSE;
4391  if (dfpp->dfp_rooted)
4392   {
4393    /* defparam path root wrong */
4394    syp = grp->grcmps[0];
4395    if ((ii = __ip_indsrch(syp->synam)) == -1) __misc_terr(__FILE__, __LINE__);
4396    dfpp->dfpiis[0] = ii;
4397    gi = 1;
4398    up_mdp = __top_itab[ii]->imsym->el.emdp;
4399   }
4400  else { gi = 0; up_mdp = __inst_mod; }
4401 
4402  for (; gi <= grp->last_gri; gi++)
4403   {
4404    /* grcmps components parallel here */
4405    syp = grp->grcmps[gi];
4406    ip = syp->el.eip;
4407    /* making use of c pointer subtraction correction object size here */
4408    /* changing to byte ptr because not sure of c ptr size object rules */
4409    bp1 = (byte *) ip;
4410    bp2 = (byte *) up_mdp->minsts;
4411    ii = (bp1 - bp2)/sizeof(struct inst_t);
4412 
4413    /* DBG remove --- */
4414    if (__debug_flg)
4415     {
4416      __dbg_msg(
4417       "^^ defparam %s component %s index %d instance %s type %s in module %s\n",
4418       grp->gnam, syp->synam, ii, ip->isym->synam, ip->imsym->synam,
4419       up_mdp->msym->synam);
4420     }
4421    /* --- */
4422    dfpp->dfpiis[gi] = ii;
4423    up_mdp = syp->el.eip->imsym->el.emdp;
4424   }
4425 }
4426 
4427 /*
4428  * resolve all non defparam xmrs in all modules
4429  *
4430  * since this is done after all splitting and fix up of itree and static
4431  * inst tree - all grefs will have correct syms
4432  * all defparams set by here
4433  */
resolve_xmrs(void)4434 static void resolve_xmrs(void)
4435 {
4436  register int32 gri;
4437  register struct gref_t *grp;
4438  register struct mod_t *mdp;
4439 
4440  /* notice must include any newly split off modules here */
4441  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4442   {
4443    __push_wrkitstk(mdp, 0);
4444    grp = &(__inst_mod->mgrtab[0]);
4445    for (gri = 0; gri < __inst_mod->mgrnum; gri++, grp++)
4446     {
4447      /* FIXME - for now leaving defparams but marked as gone here */
4448      /* why not remove? */
4449      if (grp->gr_err) continue;
4450      __resolve_glbnam(grp);
4451      /* must count here because must resolve globals from pli and debugger */
4452      if (!grp->gr_err) __num_glbs++;
4453     }
4454    __pop_wrkitstk();
4455   }
4456  /* must free because can be many PLI systf args that are converted back */
4457  free_gone_glbs();
4458 }
4459 
4460 /*
4461  * build the global path name component symbol list for 1 global
4462  *
4463  * SJM 01/14/00
4464  * this requires that inst mod be set usually by push wrk itstk routine
4465  * it just decompoes xmr into path components so does not need itree context
4466  */
__resolve_glbnam(struct gref_t * grp)4467 extern void __resolve_glbnam(struct gref_t *grp)
4468 {
4469  register int32 gi;
4470  struct sy_t *syp;
4471  struct sy_t **syarr;
4472  struct expr_t *gcmp_ndp, **syxarr;
4473 
4474  __sfnam_ind = grp->grfnam_ind;
4475  __slin_cnt = grp->grflin_cnt;
4476 
4477  /* DBG remove --- */
4478  if (grp->gxndp->optyp != GLBREF) __arg_terr(__FILE__, __LINE__);
4479  if (grp->glbref->optyp != GLBPTH) __arg_terr(__FILE__, __LINE__);
4480  if (grp->glbref->ru.x == NULL || grp->glbref->ru.x->optyp != XMRCOM)
4481   __arg_terr(__FILE__, __LINE__);
4482  /* --- */
4483  gcmp_ndp = grp->glbref->ru.x;
4484 
4485  /* separate handling for intra-module (really local) hierarchical paths */
4486  /* does all processing and then returns */
4487  /* defparam lhs may be hierarchical local - changed to def param later */
4488  /* all 1 component special instance/prim globals caught here */
4489  /* also any illegal selects caught because know non-inst scope objects */
4490  if (resolve_local_path(grp, gcmp_ndp)) return;
4491 
4492  /* SJM 09/15/00 - because of inst tree dependent upward rel forms */
4493  /* reauired by LRM must use old routine for defparams to fill head */
4494  if (grp->gr_defparam)
4495   {
4496    /* fill the defparam lhs head - notice after first component found */
4497    /* and filled rest is same as normal XMR */
4498    /* different needed because itree needed for full XMR processing */
4499    if (!fill_dfp_gsymhead(grp, gcmp_ndp)) goto bad_end;
4500   }
4501  else
4502   {
4503    /* fill root of non defparam xmr path */
4504    if (!fill_gsymhead(grp, gcmp_ndp)) goto bad_end;
4505   }
4506 
4507  /* handle special scope form 1 component global */
4508  /* only scope place [top mod] or [inst] as simple name can get here */
4509  /* LOOKATME think this case handled in resolve local path */
4510  if (gcmp_ndp->ru.x == NULL)
4511   {
4512    /* fake last component index - since only access one back from end */
4513    syp = NULL;
4514    if (grp->gr_inst_ok)
4515     {
4516      /* this needs to be 1 component global where targsyp and path same */
4517      /* here both target and last inst. scope symbol are the same */
4518      syp = __glbsycmps[0];
4519      grp->targsyp = syp;
4520     }
4521    else if (grp->is_upreltsk)
4522     {
4523      /* upward rel converts to [mod name].[func name] */
4524      syp = __glbsycmps[0];
4525      grp->targsyp = __glbsycmps[1];
4526     }
4527    else __case_terr(__FILE__, __LINE__);
4528    goto fill_glb;
4529   }
4530  /* this is a normal xmr - fill rest of xmr path */
4531  /* this removes the intra-module path (except last) from glb sy cmps */
4532  if (!fill_grestsyms(grp, gcmp_ndp->ru.x)) goto bad_end;
4533 
4534  /* fill various gref fields - target symbol always last even if inst. */
4535  grp->targsyp = __glbsycmps[__last_gsc];
4536 
4537  /* need to set syp as ending inst. not var for setting targmdp */
4538  if (grp->targsyp->sytyp == SYM_I || grp->targsyp->sytyp == SYM_M)
4539   syp = grp->targsyp;
4540  /* notice syp is 1 before target end - usually will be inst. */
4541  else syp = __glbsycmps[__last_gsc - 1];
4542 
4543 fill_glb:
4544  /* may be dumpvars or scope style instance reference */
4545  if (syp->sytyp == SYM_I) grp->targmdp = syp->el.eip->imsym->el.emdp;
4546  else if (syp->sytyp == SYM_M) grp->targmdp = syp->el.emdp;
4547  else
4548   {
4549    __sgferr(1107,
4550     "hierarchical path reference %s target symbol %s type %s illegal",
4551     grp->gnam, syp->synam, __to_sytyp(__xs, syp->sytyp));
4552    goto bad_end;
4553   }
4554 
4555  /* handle special scope globals */
4556  /* can be module for top only or upward relative one component */
4557  if (grp->targsyp->sytyp == SYM_I || grp->targsyp->sytyp == SYM_M)
4558   {
4559    /* notice task scope form looks like normal here and checked elsewhere */
4560    if (!grp->gr_inst_ok)
4561     {
4562      __sgferr(1030,
4563       "special system task instance form argument %s not allowed here",
4564       grp->gnam);
4565      goto bad_end;
4566     }
4567    /* adjust last component so it stays as part of path here */
4568    /* targsyp and last are same symbol */
4569    grp->last_gri = (short int) __last_gsc;
4570   }
4571  else grp->last_gri = (short int) __last_gsc - 1;
4572  if (!chk_glb_inst_sels(grp)) goto bad_end;
4573 
4574  /* allocate the array of symbols in malloced storage */
4575  syarr = (struct sy_t **)
4576    __my_malloc((__last_gsc + 1)*sizeof(struct sy_t *));
4577  grp->grcmps = syarr;
4578 
4579  syxarr = (struct expr_t **)
4580    __my_malloc((__last_gsc + 1)*sizeof(struct expr_t *));
4581  grp->grxcmps = syxarr;
4582 
4583  /* tail pointed to by targsyp end of syarr is last instance symbol */
4584  /* for scope object targsyp and last syarr same */
4585  for (gi = 0; gi <= __last_gsc; gi++)
4586   {
4587    syarr[gi] = __glbsycmps[gi];
4588    /* will be nil for non inst. select */
4589    syxarr[gi] = __glbxcmps[gi];
4590   }
4591 
4592  /* check and fold gref instance array select constant select expressions */
4593  if (grp->path_has_isel)
4594   {
4595    char s1[RECLEN];
4596 
4597    for (gi = 0; gi <= grp->last_gri; gi++)
4598     {
4599      if (grp->grxcmps[gi] == NULL) continue;
4600 
4601      sprintf(s1, "hierarchical reference instance array index (pos. %d)",
4602       gi + 1);
4603      if (!__chkndx_expr(grp->grxcmps[gi], s1)) goto bad_end;
4604     }
4605   }
4606 
4607  /* even though downward really rooted, must not treat as rooted */
4608  /* until variable xmr converted to location - for defparam need to */
4609  /* add module name (1 level) prefix */
4610 
4611  /* fill symbol grp expr and grp ru expr field already cross linked */
4612  /* for disable will point to disable expr. */
4613  /* LOOKATME - although XMRCOM expr contents no longer accessible */
4614  /* can not free because grp points to grcmps - slight memory leak here */
4615  grp->gxndp->ru.grp = grp;
4616  grp->gxndp->lu.sy = grp->targsyp;
4617  return;
4618 
4619 bad_end:
4620  grp->gr_err = TRUE;
4621 }
4622 
4623 /*
4624  * resolve a local name that is a qualified path name
4625  * if really local path, converted and checked as id later
4626  *
4627  * here caller handled instance arrays - know in module scope symbols
4628  * are never arrayed (error emitted if select appears)
4629  */
resolve_local_path(struct gref_t * grp,struct expr_t * ghd_ndp)4630 static int32 resolve_local_path(struct gref_t *grp, struct expr_t *ghd_ndp)
4631 {
4632  struct symtab_t *sytp;
4633  struct sy_t *syphd, *syptail;
4634  struct expr_t *ndp, *locndp;
4635  char *ncmp;
4636 
4637  if (ghd_ndp->lu.x->optyp == XMRID) ndp = ghd_ndp->lu.x;
4638  else if (ghd_ndp->lu.x->optyp == LSB) ndp = ghd_ndp->lu.x->lu.x;
4639  else { __case_terr(__FILE__, __LINE__); return(FALSE); }
4640 
4641  ncmp = ndp->ru.qnchp;
4642  /* work up task chains searching for local */
4643  for (syphd = NULL, sytp = grp->grsytp; sytp != NULL; sytp = sytp->sytpar)
4644   {
4645    if ((syphd = __zget_sym(ncmp, sytp->stsyms, sytp->numsyms)) != NULL) break;
4646   }
4647  if (syphd == NULL) return(FALSE);
4648 
4649  /* handle xmr's that were guessed to be xmrs but are really either errors */
4650  /* or guessed wrong and just simple wires - if this is place wire cannot */
4651  /* go, error will be caught in item (such as task enable) checking */
4652  if (syphd->sytyp == SYM_N)
4653   {
4654    /* if this is hierarchical global whose head is wire - error */
4655    /* i.e. if only 1 component ok */
4656    if (ghd_ndp->ru.x != NULL || !grp->gr_inst_ok)
4657     {
4658      __sgferr(754, "hierarchical reference %s first component %s %s illegal",
4659       grp->gnam, __to_wtnam(__xs, syphd->el.enp), syphd->synam);
4660      grp->gr_err = TRUE;
4661      return(TRUE);
4662     }
4663    /* must be wire not parameter here at end - param use xmr's illegal */
4664    if (!chk_xmr_tail_wire(grp, syphd, TRUE))
4665     { grp->gr_err = TRUE; return(TRUE); }
4666 
4667 local_1cmp:
4668    /* if this is xmr that is 1 component - change back to simple wire */
4669    grp->gr_gone = TRUE;
4670    /* LOOKATME - why is this needed since removing glb */
4671    if (syphd->sytyp == SYM_TSK || syphd->sytyp == SYM_F ||
4672     syphd->sytyp == SYM_LB) grp->targtskp = syphd->el.etskp;
4673    /* this can be local task call too - not just wire */
4674    if (ghd_ndp->lu.x->optyp == XMRID)
4675     {
4676      /* first free the XMRCOM grp expr. part */
4677      locndp = grp->gxndp;
4678      __free2_xtree(locndp);
4679      locndp->optyp = ID;
4680      locndp->ru.grp = NULL;
4681      locndp->lu.sy = syphd;
4682     }
4683    else
4684     {
4685      /* here gxndp is GLB REF with ru ptr to XMR COM (list) */
4686      /* here rearranging so can not free */
4687      locndp = grp->gxndp;
4688      locndp->optyp = LSB;
4689      locndp->ru.grp = NULL;
4690      locndp->lu.x = ghd_ndp->lu.x->lu.x;
4691      locndp->lu.x->optyp = ID;
4692      locndp->lu.x->lu.sy = syphd;
4693      locndp->ru.x = ghd_ndp->lu.x->ru.x;
4694     }
4695    /* global is now removed and do not need to save name since only one comp */
4696    return(TRUE);
4697   }
4698  /* know only way for this to happen is gr loc is scope object */
4699  /* if this is 1 component task enable or function call will never be */
4700  /* seen as global in source reading */
4701  /* handle in normal global code since it cannot be local */
4702 
4703  /* not a wire - handle case of 1 component scope object */
4704  /* this is global caused by appearing in scope legal place */
4705  if (ghd_ndp->ru.x == NULL)
4706   {
4707    /* can be task/func/named block in which case convert back to local */
4708    /* also can be udp or gate primitive */
4709    /* and no need to check for possibility of wrong param will check in */
4710    /* sys task enable code */
4711    if (syphd->sytyp == SYM_TSK || syphd->sytyp == SYM_F ||
4712     syphd->sytyp == SYM_LB)
4713     {
4714      /* any scope array that is not array of insts is illegal */
4715      if (ghd_ndp->lu.x->optyp == LSB)
4716       {
4717 local_sel_err:
4718        __sgferr(690,
4719         "hierarchical reference %s illegal - array of %s illegal",
4720         grp->gnam, __to_sytyp(__xs, syphd->sytyp));
4721        grp->gr_err = TRUE;
4722        return(TRUE);
4723       }
4724      goto local_1cmp;
4725     }
4726 
4727    /* normal 1 component inst. or top mod. global - handled elsewhere */
4728    return(FALSE);
4729   }
4730  /* if in module symbol head instance, then not local */
4731  if (syphd->sytyp != SYM_TSK && syphd->sytyp != SYM_F &&
4732   syphd->sytyp != SYM_LB) return(FALSE);
4733 
4734  /* know this local name expressed with qualified path */
4735  /* 1st check head to see if also a module name */
4736  if (__get_sym(ncmp, __modsyms) != NULL)
4737   {
4738    __sgfwarn(532,
4739     "local hierarchical name %s path head is also module name - local used",
4740     grp->gnam);
4741   }
4742  /* NULL means undecl. - error but getting here still means local */
4743  /* checks for parameter at end of path in here */
4744  /* getting here means first symbol is is declared in module */
4745  if ((syptail = find_inmod_sym(grp, ghd_ndp, syphd, &sytp)) == NULL)
4746   {
4747    grp->gr_err = TRUE;
4748    return(TRUE);
4749   }
4750  /* after end of instances, local scope object can not be array ref. */
4751  if (ghd_ndp->lu.x->optyp == LSB) goto local_sel_err;
4752 
4753  /* know task/func/mod */
4754  /* notice ...lb.lb as scope is ok - just like local - and >2 elements */
4755  if (syphd->sytyp == SYM_LB && ghd_ndp->ru.x != NULL
4756   && ghd_ndp->ru.x->ru.x != NULL)
4757   {
4758    __sgfinform(401,
4759     "local hierarchical path %s first component is named block", grp->gnam);
4760   }
4761  /* finally convert to ID but save name for printing */
4762  grp->gr_gone = TRUE;
4763  /* LOOKATME - again why is this needed since gone turned on */
4764  grp->targtskp = syphd->el.etskp;
4765 
4766  locndp = grp->gxndp;
4767  __free2_xtree(locndp);
4768  /* must set non xmr node tail */
4769  locndp->lu.sy = syptail;
4770  locndp->optyp = ID;
4771  /* re-allocate this so can eventually if needed free global */
4772  /* notice must not free gnam field in case free globals (shouldn't) */
4773  /* FIXME - should for inst. array references need to convert to numbers */
4774  locndp->ru.qnchp = grp->gnam;
4775  grp->gnam = NULL;
4776  locndp->locqualnam = TRUE;
4777  /* global is now removed */
4778  return(TRUE);
4779 }
4780 
4781 /*
4782  * check a wire tail to make sure not illegal parameter wire form
4783  * know symbol is wire to be called
4784  */
chk_xmr_tail_wire(struct gref_t * grp,struct sy_t * tailsyp,int32 is_loc1cmp)4785 static int32 chk_xmr_tail_wire(struct gref_t *grp, struct sy_t *tailsyp,
4786  int32 is_loc1cmp)
4787 {
4788  struct net_t *np;
4789 
4790  switch ((byte) tailsyp->sytyp) {
4791   /* these are legal in some places - various kinds of xmrs checked for in */
4792   /* place of use */
4793   case SYM_I: case SYM_M: case SYM_LB: case SYM_F: case SYM_TSK: break;
4794   case SYM_N:
4795    /* this if fixup of guessed wrong because sys. task special arg xmr */
4796    /* that is really net */
4797    np = tailsyp->el.enp;
4798    /* if resolving defparam lhs xmr, parameter ok and required but */
4799    /* if not error caught later */
4800    if (grp->gr_defparam) break;
4801 
4802    if (!is_loc1cmp && np->n_isaparam)
4803     {
4804      __sgferr(769,
4805       "hierarchical reference %s tail variable %s cannot be a parameter",
4806       grp->gnam, np->nsym->synam);
4807      return(FALSE);
4808     }
4809    break;
4810   default:
4811    __sgferr(766, "hierarchical reference %s tail %s cannot be a %s",
4812     grp->gnam, tailsyp->synam, __to_sytyp(__xs, tailsyp->sytyp));
4813   }
4814  return(TRUE);
4815 }
4816 
4817 /*
4818  * fill defparam component symbol array first element
4819  * this forces symbol location of all remaining components
4820  *
4821  * only legal possibilites are 1) instance in current module 2) top level
4822  * module, and 3) upward module type reference (this is error caught by
4823  * caller)
4824  *
4825  * return F on error else T - error message emitted here
4826  */
fill_dfp_gsymhead(struct gref_t * grp,struct expr_t * ghd_ndp)4827 static int32 fill_dfp_gsymhead(struct gref_t *grp, struct expr_t *ghd_ndp)
4828 {
4829  int32 comp_isel;
4830  struct sy_t *syp, *modsyp;
4831  struct symtab_t *sytp;
4832  struct expr_t *ndp;
4833  char *ncmp;
4834 
4835  comp_isel = FALSE;
4836  if (ghd_ndp->lu.x->optyp == XMRID) ndp = ghd_ndp->lu.x;
4837  else if (ghd_ndp->lu.x->optyp == LSB)
4838    { ndp = ghd_ndp->lu.x->lu.x; comp_isel = TRUE; }
4839  else { __case_terr(__FILE__, __LINE__); return(FALSE); }
4840 
4841  ncmp = ndp->ru.qnchp;
4842  /* if can possibly be rooted from top module or above module, save symbol */
4843  modsyp = __get_sym(ncmp, __modsyms);
4844 
4845  /* 1st priority is instance (must exist) in mod where glb ref. appeared */
4846  /* but maybe accessed from contained task or named block scope */
4847  for (sytp = grp->grsytp; sytp != NULL; sytp = sytp->sytpar)
4848   { if (sytp->sypofsyt->sytyp == SYM_M) goto got_inst; }
4849  __misc_terr(__FILE__, __LINE__);
4850 
4851  /* look up in inst. symbol table only */
4852 got_inst:
4853  if ((syp = __zget_sym(ncmp, sytp->stsyms, sytp->numsyms)) != NULL)
4854   {
4855    if (syp->sytyp != SYM_I)
4856     {
4857      __sgfwarn(533,
4858       "defparam left hand side %s head %s %s in %s not instance - assuming rooted",
4859       grp->gnam, __to_sytyp(__xs, syp->sytyp), ncmp, sytp->sypofsyt->synam);
4860      syp = NULL;
4861      goto try_mod1st;
4862     }
4863    /* emit warning if also could be rooted but use inst. */
4864    if (modsyp != NULL)
4865     {
4866      __sgfwarn(534,
4867       "defparam left hand side %s head %s both upward module and downward instance - instance used",
4868       grp->gnam, ncmp);
4869     }
4870    __glbsycmps[0] = syp;
4871    if (comp_isel)
4872     {
4873      __glbxcmps[0] = ghd_ndp->lu.x->ru.x;
4874      grp->path_has_isel = TRUE;
4875     }
4876    else __glbxcmps[0] = NULL;
4877    __last_gsc = 0;
4878    return(TRUE);
4879   }
4880 
4881  /* did not find instance name - see if matches module name */
4882 try_mod1st:
4883  if (modsyp == NULL)
4884   {
4885    __sgferr(757,
4886     "rooted or upward relative defparam left hand side %s first component %s illegal or undeclared",
4887     grp->gnam, ncmp);
4888    return(FALSE);
4889   }
4890  /* since upward module not instance, error if select */
4891  if (comp_isel)
4892   {
4893    __sgferr(692,
4894     "rooted or upward relative path %s head %s not instance array - select illegal",
4895     grp->gnam, ncmp);
4896    return(FALSE);
4897   }
4898 
4899  /* know this is module and if non rooted for now assume above */
4900  __glbsycmps[0] = modsyp;
4901  __glbxcmps[0] = NULL;
4902  __last_gsc = 0;
4903  /* notice cannot check if upward really above in itree until prep. time */
4904  if (modsyp->el.emdp->minstnum != 0) grp->upwards_rel = TRUE;
4905  else grp->is_rooted = TRUE;
4906  return(TRUE);
4907 }
4908 
4909 /*
4910  * fill global component symbol array first element
4911  * this forces symbol location of all remaining components
4912  *
4913  * 09/14/00 - SJM now allow insts above this inst as first to check
4914  * LOOKATME - for now module type found above must be same for all insts
4915  *            but can come from inst or mod (happens when same name)
4916  *
4917  * only legal possibilites are 1) instance in current module 2) instance
4918  * above 3) top level module, and 4) upward module
4919  *
4920  * return F on error else T - error message emitted here
4921  */
fill_gsymhead(struct gref_t * grp,struct expr_t * ghd_ndp)4922 static int32 fill_gsymhead(struct gref_t *grp, struct expr_t *ghd_ndp)
4923 {
4924  int32 comp_isel;
4925  struct sy_t *syp, *syp2, *modsyp, *scope_syp;
4926  struct symtab_t *sytp;
4927  struct expr_t *ndp;
4928  struct mod_t *imdp;
4929  struct itree_t *in_itp;
4930  char *ncmp;
4931 
4932  comp_isel = FALSE;
4933  if (ghd_ndp->lu.x->optyp == XMRID) ndp = ghd_ndp->lu.x;
4934  else if (ghd_ndp->lu.x->optyp == LSB)
4935    { ndp = ghd_ndp->lu.x->lu.x; comp_isel = TRUE; }
4936  else { __case_terr(__FILE__, __LINE__); return(FALSE); }
4937 
4938  ncmp = ndp->ru.qnchp;
4939  /* if can possibly be rooted from top module or above module, save symbol */
4940  /* but first priority is instance in module and then instance above */
4941  modsyp = __get_sym(ncmp, __modsyms);
4942 
4943  /* if ref in task/named block, first move up to inst sym tab */
4944  /* will always find it and usually already there */
4945  /* know if is it not XMR but really local path ref, won't get here */
4946  for (sytp = grp->grsytp; sytp != NULL; sytp = sytp->sytpar)
4947   { if (sytp->sypofsyt->sytyp == SYM_M) goto inst_sytab; }
4948  __misc_terr(__FILE__, __LINE__);
4949 
4950 inst_sytab:
4951  /* case 1: first priority downward relative inst name */
4952  syp = __zget_sym(ncmp, sytp->stsyms, sytp->numsyms);
4953  if (syp == NULL) goto try_rooted;
4954  if (syp->sytyp != SYM_I)
4955   {
4956    /* LOOKATME - think this can only happen for top level named blocks */
4957    __sgfwarn(533,
4958     "hierarchical path %s head defined as %s %s in %s not instance - assuming upward name or rooted",
4959     grp->gnam, __to_sytyp(__xs, syp->sytyp), ncmp, sytp->sypofsyt->synam);
4960    syp = NULL;
4961    goto try_rooted;
4962   }
4963  /* emit inform if can also be rooted */
4964  if (modsyp != NULL && modsyp->el.emdp->minstnum == 0)
4965   {
4966    __sgfinform(464,
4967     "hierarchical path %s head %s downward relative but also top level module - could be rooted path",
4968     grp->gnam, ncmp);
4969   }
4970  /* emit inform if can be upward relative instance - just check one 0th inst */
4971  if (fnd_uprel_inst(ncmp, grp->gin_mdp->moditps[0]) != NULL)
4972   {
4973    __sgfinform(464,
4974     "hierarchical path %s head %s downward relative but also upward instance - could be upward relative path",
4975     grp->gnam, ncmp);
4976   }
4977  /* emit inform if can be upward relative instance - just check 0th inst */
4978  if (modsyp != NULL && fnd_uprel_mod(modsyp, grp->gin_mdp->moditps[0]))
4979   {
4980    __sgfinform(464,
4981     "hierarchical path %s head %s downward relative but also upward module type name - could be upward relative path",
4982     grp->gnam, ncmp);
4983   }
4984  __glbsycmps[0] = syp;
4985  if (comp_isel)
4986   {
4987    __glbxcmps[0] = ghd_ndp->lu.x->ru.x;
4988    grp->path_has_isel = TRUE;
4989   }
4990  else __glbxcmps[0] = NULL;
4991  __last_gsc = 0;
4992  return(TRUE);
4993 
4994 try_rooted:
4995  /* SJM 09/18/00 - LRM says upward relative inst before rooted-think wrong */
4996  if (modsyp != NULL && modsyp->el.emdp->minstnum == 0)
4997   {
4998    imdp = modsyp->el.emdp;
4999    /* first inform if upward instance but not top */
5000    if ((syp2 = fnd_uprel_inst(ncmp, grp->gin_mdp->moditps[0])) != NULL
5001     && syp2->el.emdp->minstnum != 0)
5002     {
5003      __sgfinform(464,
5004       "hierarchical path %s rooted but head %s also other and lower upward instance - rooted path used",
5005       grp->gnam, ncmp);
5006    }
5007    /* notice can't be upward module since module is top or not get here */
5008    goto found_ref;
5009   }
5010  /* see if upward inst that is not rooted - use 0th instance for find */
5011  /* works because all upward relative paths must find same module type */
5012  in_itp = grp->gin_mdp->moditps[0];
5013  if ((syp = fnd_uprel_inst(ncmp, in_itp)) != NULL)
5014   {
5015    /* found an upward relative inst, if more than one in src, error */
5016    /* if do not find same module for all */
5017    if (grp->gin_mdp->minstnum > 1)
5018     {
5019      /* if instantiated in many places must always find exactly same */
5020      /* uprel module type */
5021      if (!chk_all_uprels_same(grp, modsyp, ncmp, ghd_ndp)) return(FALSE);
5022     }
5023 
5024    /* inform if found inst and head also upward mod name - know not rooted */
5025    if (modsyp != NULL && fnd_uprel_mod(modsyp, in_itp))
5026     {
5027      __sgfinform(464,
5028       "hierarchical path %s head %s upward relative instance but %s also upward module - instance used",
5029       grp->gnam, ncmp, ncmp);
5030     }
5031    /* if found, uprel instance it becomes mod sym */
5032    modsyp = syp;
5033    if (grp->gin_mdp->minstnum > 1)
5034     {
5035      /* if instantiated in many places must always find exactly same */
5036      /* uprel module type */
5037      if (!chk_all_uprels_same(grp, modsyp, ncmp, ghd_ndp)) return(FALSE);
5038     }
5039    goto found_ref;
5040   }
5041  /* see if upward relative module - inst array select impossible */
5042  if (comp_isel)
5043   {
5044    __sgferr(692,
5045     "rooted or upward relative path %s head instance array select %s not found",
5046     grp->gnam, ncmp);
5047    return(FALSE);
5048   }
5049  /* if head is type name, see if upward relative module name */
5050  if (modsyp != NULL)
5051   {
5052    if (!fnd_uprel_mod(modsyp, in_itp)) goto try_tskscope;
5053 
5054    /* here no conflict possible but check for all same module containing */
5055    /* reference instantiated in source in different places */
5056 
5057    if (grp->gin_mdp->minstnum > 1)
5058     {
5059      /* if instantiated in many places must always find exactly same */
5060      /* uprel module type */
5061      if (!chk_all_uprels_same(grp, modsyp, ncmp, ghd_ndp)) return(FALSE);
5062     }
5063    goto found_ref;
5064   }
5065 
5066 try_tskscope:
5067  /* FIXME - will this be seen as XMR? - think not and test */
5068  /* finally try to find name as task/func/named block (other scope) */
5069  /* anywhere in upward module - must be one component non select form */
5070  if (ghd_ndp->ru.x == NULL)
5071   {
5072    if ((imdp = fnd_uprel_tskfunc(&scope_syp, ncmp, in_itp)) == NULL)
5073     goto ref_err;
5074 
5075    __last_gsc = 1;
5076    __glbsycmps[0] = imdp->msym;
5077    __glbxcmps[0] = NULL;
5078    __glbsycmps[__last_gsc] = scope_syp;
5079    __glbxcmps[__last_gsc] = NULL;
5080 
5081    /* this must always be upward relative even if in top module */
5082    grp->upwards_rel = TRUE;
5083    grp->is_upreltsk = TRUE;
5084    grp->targtskp = scope_syp->el.etskp;
5085    /* here can't call fill grest syms */
5086    return(TRUE);
5087   }
5088 
5089  /* finally, not found */
5090 ref_err:
5091  /* SJM 03/29/02 - for 1 component - assume undeclared */
5092  if (ghd_ndp->ru.x == NULL)
5093   {
5094    /* DBG remove */
5095    if (strcmp(ncmp, grp->gnam) != 0) __misc_terr(__FILE__, __LINE__);
5096    /* --- */
5097    __sgferr(757,
5098     "%s undeclared - possibly undeclared one component cross module reference",
5099     grp->gnam);
5100   }
5101  else
5102   {
5103    __sgferr(757,
5104     "rooted, downward relative or upward relative hierarchical reference %s first component %s not found - illegal path head or undeclared",
5105     grp->gnam, ncmp);
5106   }
5107  return(FALSE);
5108 
5109 found_ref:
5110  /* know this is module and if non rooted for now assume above */
5111  __glbsycmps[0] = modsyp;
5112  __glbxcmps[0] = NULL;
5113  __last_gsc = 0;
5114  /* notice cannot check if upward really above in itree until prep. time */
5115  if (modsyp->el.emdp->minstnum != 0) grp->upwards_rel = TRUE;
5116  else grp->is_rooted = TRUE;
5117  return(TRUE);
5118 }
5119 
5120 /*
5121  * for every instance of gin module type, find uprel dest and check to
5122  * make sure destination the same
5123  *
5124  * also checks each instance's uprel
5125  */
chk_all_uprels_same(struct gref_t * grp,struct sy_t * modsyp,char * ncmp,struct expr_t * ghd_ndp)5126 static int32 chk_all_uprels_same(struct gref_t *grp, struct sy_t *modsyp,
5127  char *ncmp, struct expr_t *ghd_ndp)
5128 {
5129  register int32 ii;
5130  register struct itree_t *in_itp;
5131  int32 uprel_typ, got_one, fnd_ii, sav_ecnt;
5132  struct sy_t *uprel_syp, *scope_syp, *syp;
5133  struct mod_t *imdp;
5134 
5135  uprel_typ = -1;
5136  uprel_syp = NULL;
5137  fnd_ii = -1;
5138  got_one = FALSE;
5139  sav_ecnt = __pv_err_cnt;
5140  for (ii = 0; ii < grp->gin_mdp->flatinum; ii++)
5141   {
5142    in_itp = grp->gin_mdp->moditps[ii];
5143    /* upward relative instance name - symbol is module not inst */
5144    if ((syp = fnd_uprel_inst(ncmp, in_itp)) != NULL)
5145     {
5146      if (!got_one)
5147       { uprel_typ = SYM_I; uprel_syp = syp; got_one = TRUE; fnd_ii = ii; }
5148      else
5149       {
5150        if (uprel_typ != SYM_I || syp != uprel_syp)
5151         {
5152         __sgferr(939,
5153          "rooted or upward relative instance reference %s for instance %s differs from upward reference for instance %s",
5154          grp->gnam, __msg2_blditree(__xs, in_itp),
5155          __msg2_blditree(__xs2, grp->gin_mdp->moditps[fnd_ii]));
5156         }
5157       }
5158      continue;
5159     }
5160 
5161    /* upward relative type name */
5162    if (modsyp != NULL)
5163     {
5164      /* this returns T on success */
5165      if (fnd_uprel_mod(modsyp, in_itp))
5166       {
5167        if (!got_one)
5168         { uprel_typ = SYM_M; uprel_syp = modsyp; got_one = TRUE; fnd_ii = ii; }
5169        else
5170         {
5171          if (uprel_typ != SYM_M || modsyp != uprel_syp)
5172           {
5173            __sgferr(3402,
5174            "upward relative module type reference %s for instance %s differs from upward reference for instance %s",
5175            grp->gnam, __msg2_blditree(__xs, in_itp),
5176            __msg2_blditree(__xs2, grp->gin_mdp->moditps[fnd_ii]));
5177           }
5178         }
5179        continue;
5180       }
5181     }
5182 
5183    /* if only one component, look for upward somwhere task/func */
5184    if (ghd_ndp->ru.x == NULL)
5185     {
5186      if ((imdp = fnd_uprel_tskfunc(&scope_syp, ncmp, in_itp)) != NULL)
5187       {
5188        if (!got_one)
5189         {
5190          uprel_typ = SYM_TSK;
5191          uprel_syp = scope_syp;
5192          got_one = TRUE;
5193          fnd_ii = ii;
5194         }
5195        else
5196         {
5197          if (uprel_typ != SYM_TSK || scope_syp != uprel_syp)
5198           {
5199            __sgferr(3402,
5200            "upward relative task/func/named block reference %s for instance %s differs from upward reference for instance %s",
5201            grp->gnam, __msg2_blditree(__xs, in_itp),
5202            __msg2_blditree(__xs2, grp->gin_mdp->moditps[fnd_ii]));
5203           }
5204         }
5205        continue;
5206       }
5207     }
5208    __sgferr(757,
5209     "rooted or upward relative hierarchical reference %s first component %s not found for instance %s - illegal symbol or undeclared",
5210     grp->gnam, ncmp, __msg2_blditree(__xs, in_itp));
5211   }
5212  if (__pv_err_cnt > sav_ecnt) return(FALSE);
5213  return(TRUE);
5214 }
5215 
5216 /*
5217  * match upward relative instance - if found returns mod symbol
5218  */
fnd_uprel_inst(char * ncmp,struct itree_t * in_itp)5219 static struct sy_t *fnd_uprel_inst(char *ncmp, struct itree_t *in_itp)
5220 {
5221  register struct itree_t *up_itp;
5222  struct inst_t *ip;
5223 
5224  for (up_itp = in_itp; up_itp != NULL;)
5225   {
5226    ip = up_itp->itip;
5227    /* know insts in split off module types have unchanged inst name */
5228    /* FIXME - should compare inst exprs not just iarr element name */
5229    if (strcmp(ncmp, ip->isym->synam) == 0) return(ip->imsym);
5230    up_itp = up_itp->up_it;
5231   }
5232  return(NULL);
5233 }
5234 
5235 /*
5236  * match upward relative instance - if found returns T else FALSE
5237  */
fnd_uprel_mod(struct sy_t * modsyp,struct itree_t * in_itp)5238 static int32 fnd_uprel_mod(struct sy_t *modsyp, struct itree_t *in_itp)
5239 {
5240  register struct itree_t *up_itp;
5241  struct mod_t *up_mdp, *up_mast_mdp, *imdp, *mast_imdp;
5242  struct inst_t *ip;
5243 
5244  up_mdp = modsyp->el.emdp;
5245  up_mast_mdp = __get_mast_mdp(up_mdp);
5246  for (up_itp = in_itp; up_itp != NULL;)
5247   {
5248    /* must match master mod type */
5249    ip = up_itp->itip;
5250    imdp = ip->imsym->el.emdp;
5251    mast_imdp = __get_mast_mdp(imdp);
5252    if (mast_imdp == up_mast_mdp) return(TRUE);
5253    up_itp = up_itp->up_it;
5254   }
5255  return(FALSE);
5256 }
5257 
5258 /*
5259  * find an upward relative task/func/named block anywhere in uprel inst
5260  * if found return module type and set scope syp
5261  */
fnd_uprel_tskfunc(struct sy_t ** scope_syp,char * ncmp,struct itree_t * in_itp)5262 static struct mod_t *fnd_uprel_tskfunc(struct sy_t **scope_syp, char *ncmp,
5263  struct itree_t *in_itp)
5264 {
5265  register struct itree_t *up_itp;
5266  struct sy_t *tskfunc_syp;
5267  struct mod_t *imdp;
5268 
5269  for (up_itp = in_itp; up_itp != NULL;)
5270   {
5271    imdp = up_itp->itip->imsym->el.emdp;
5272    if ((tskfunc_syp = fnd_tskfunc_inscope(ncmp, imdp->msymtab)) != NULL)
5273     {
5274      *scope_syp = tskfunc_syp;
5275      return(imdp);
5276     }
5277    up_itp = up_itp->up_it;
5278   }
5279  return(NULL);
5280 }
5281 
5282 /*
5283  * find a scope symbol inside one symbol table scope level
5284  */
fnd_tskfunc_inscope(char * ncmp,struct symtab_t * scope_sytp)5285 static struct sy_t *fnd_tskfunc_inscope(char *ncmp,
5286  struct symtab_t *scope_sytp)
5287 {
5288  struct symtab_t *sytp;
5289  struct sy_t *match_syp;
5290 
5291  for (sytp = scope_sytp->sytofs; sytp != NULL; sytp = sytp->sytsib)
5292   {
5293    if (strcmp(sytp->sypofsyt->synam, ncmp) == 0) return(sytp->sypofsyt);
5294    if ((match_syp = fnd_tskfunc_inscope(ncmp, sytp)) != NULL)
5295     return(match_syp);
5296   }
5297  return(NULL);
5298 }
5299 
5300 /*
5301  * set hierarchical global reference symbols for rest of path
5302  * know head (pos. 0) filled
5303  */
fill_grestsyms(struct gref_t * grp,struct expr_t * gcmp_ndp)5304 static int32 fill_grestsyms(struct gref_t *grp, struct expr_t *gcmp_ndp)
5305 {
5306  register int32 gi;
5307  int32 comp_isel;
5308  struct sy_t *syp;
5309  struct symtab_t *sytp;
5310  struct expr_t *ndp;
5311  char *ncmp;
5312 
5313  syp = __glbsycmps[0];
5314  if (syp->sytyp == SYM_I) sytp = syp->el.eip->imsym->el.emdp->msymtab;
5315  else sytp = syp->el.emdp->msymtab;
5316 
5317  for (gi = 1;; gi++)
5318   {
5319    comp_isel = FALSE;
5320    if (gcmp_ndp->lu.x->optyp == XMRID) ndp = gcmp_ndp->lu.x;
5321    else if (gcmp_ndp->lu.x->optyp == LSB)
5322     { ndp = gcmp_ndp->lu.x->lu.x; comp_isel = TRUE; }
5323    /* SJM 02/02/05 - part select legal but same as ID here */
5324    else if (gcmp_ndp->lu.x->optyp == PARTSEL) ndp = gcmp_ndp->lu.x->lu.x;
5325    else { __case_terr(__FILE__, __LINE__); return(FALSE); }
5326 
5327    ncmp = ndp->ru.qnchp;
5328    if ((syp = __zget_sym(ncmp, sytp->stsyms, sytp->numsyms)) == NULL)
5329     {
5330      __sgferr(758, "hierarchical path %s component %s undeclared in %s",
5331       grp->gnam, ncmp, sytp->sypofsyt->synam);
5332      return(FALSE);
5333     }
5334    if (++__last_gsc >= MAXGLBCOMPS - 1)
5335     {
5336      __pv_terr(310, "hierarchical path %s has too many components (%d)",
5337       grp->gnam, MAXGLBCOMPS);
5338     }
5339    __glbsycmps[__last_gsc] = syp;
5340    if (comp_isel)
5341     {
5342      __glbxcmps[__last_gsc] = gcmp_ndp->lu.x->ru.x;
5343      grp->path_has_isel = TRUE;
5344     }
5345    else __glbxcmps[__last_gsc] = NULL;
5346 
5347    /* here global ending with instance name is ok - non scope caught later */
5348    if (syp->sytyp == SYM_I)
5349     {
5350      /* if instance, move to it module type symbol table */
5351      sytp = syp->el.eip->imsym->el.emdp->msymtab;
5352      if ((gcmp_ndp = gcmp_ndp->ru.x) == NULL) return(TRUE);
5353      continue;
5354     }
5355    /* if not legal in module hierarchical name type, error */
5356    if (syp->sytyp == SYM_N)
5357     {
5358      if (gcmp_ndp->ru.x != NULL)
5359       {
5360        __sgferr(761,
5361         "hierarchical path %s net %s not rightmost path element",
5362         grp->gnam, ncmp);
5363        return(FALSE);
5364       }
5365      /* SJM 05/02/00 - hierarchical params legal following XL - add if not */
5366      /* --
5367      if (syp->el.enp->n_isaparam)
5368       {
5369        __sgferr(762, "path %s component %s illegal hierachical reference to parameter",
5370         grp->gnam, ncmp, __to_sytyp(__xs, syp->sytyp));
5371        return(FALSE);
5372       }
5373      --- */
5374      break;
5375     }
5376    if (syp->sytyp != SYM_TSK && syp->sytyp != SYM_F && syp->sytyp != SYM_LB)
5377     {
5378      __sgferr(762, "hierarchical path %s component %s illegal %s symbol type",
5379       grp->gnam, ncmp, __to_sytyp(__xs, syp->sytyp));
5380      return(FALSE);
5381     }
5382    /* if last symbol, end with task not wire type symbol which is ok */
5383    if (gcmp_ndp->ru.x == NULL)
5384     {
5385      if (gcmp_ndp->lu.x->optyp == LSB)
5386       {
5387        __sgferr(693,
5388         "hierarchical reference %s select of last symbol task %s illegal",
5389         grp->gnam, __to_sytyp(__xs, syp->sytyp));
5390        return(FALSE);
5391       }
5392      grp->targtskp = syp->el.etskp;
5393      break;
5394     }
5395 
5396    /* must be some kind of task or will not get here */
5397    sytp = syp->el.etskp->tsksymtab;
5398    /* section of path containing in module symbols removed since only need */
5399    /* pointer to symbol and inst. number for var. access same */
5400    /* will check for parameter at end of path or wrong thing in here */
5401    gcmp_ndp = gcmp_ndp->ru.x;
5402    if ((syp = find_inmod_sym(grp, gcmp_ndp, syp, &sytp)) != NULL)
5403     {
5404      /* by here skipped over all in module symbols, syp is the end */
5405      __last_gsc = gi;
5406      __glbsycmps[__last_gsc] = syp;
5407      /* since in mod, can never be select - error already caught */
5408      __glbxcmps[__last_gsc] = NULL;
5409      grp->targtskp = sytp->sypofsyt->el.etskp;
5410      break;
5411     }
5412    /* if found match but rest is not in module global - keep looking */
5413    /* and will emit error */
5414   }
5415  return(TRUE);
5416 }
5417 
5418 /*
5419  * find in module symbol - know previous symbol selected module
5420  * or local task/block/function hierarchical name root
5421  *
5422  * end of path here can be scope named block/func/task/mod/inst etc.
5423  * this must also return (set) symbol table where last symbol declared
5424  */
find_inmod_sym(struct gref_t * grp,struct expr_t * gcmp_ndp,struct sy_t * syp,struct symtab_t ** endsytp)5425 static struct sy_t *find_inmod_sym(struct gref_t *grp, struct expr_t *gcmp_ndp,
5426  struct sy_t *syp, struct symtab_t **endsytp)
5427 {
5428  struct expr_t *ndp;
5429  struct symtab_t *sytp;
5430 
5431  sytp = *endsytp;
5432  for (;;)
5433   {
5434    if (gcmp_ndp->lu.x->optyp == XMRID) ndp = gcmp_ndp->lu.x;
5435    else if (gcmp_ndp->lu.x->optyp == LSB)
5436     {
5437      __sgferr(694,
5438      "hierarchical path %s select of %s component illegal - not instance array",
5439       grp->gnam, __to_sytyp(__xs, syp->sytyp));
5440      return(NULL);
5441     }
5442    else { __case_terr(__FILE__, __LINE__); return(FALSE); }
5443 
5444    syp = __zget_sym(ndp->ru.qnchp, sytp->stsyms, sytp->numsyms);
5445    if (gcmp_ndp->ru.x == NULL) break;
5446 
5447    if (syp == NULL)
5448     {
5449      /* did not find next path component */
5450      __sgferr(763, "hierarchical path %s component %s undeclared", grp->gnam,
5451       ndp->ru.qnchp);
5452      return(NULL);
5453     }
5454    /* SJM 10/07/06 - also legal for local XMR reference nets in tasks and */
5455    /* functions declared within the current module (i.e. t.r) */
5456    if (syp->sytyp != SYM_LB && syp->sytyp != SYM_TSK && syp->sytyp != SYM_F)
5457     {
5458      __sgferr(764,
5459       "hierarchical path %s internal component %s type %s instead of expected named block",
5460       grp->gnam, ndp->ru.qnchp, __to_sytyp(__xs, syp->sytyp));
5461      return(NULL);
5462     }
5463    sytp = syp->el.etskp->tsksymtab;
5464    gcmp_ndp = gcmp_ndp->ru.x;
5465   }
5466  /* syp is tail (actual variable), if declared replace - checking later */
5467  if (syp == NULL)
5468   {
5469    __sgferr(765,
5470     "internal hierarchical path %s part last component %s undeclared",
5471     grp->gnam, ndp->ru.qnchp);
5472    return(NULL);
5473   }
5474  if (!chk_xmr_tail_wire(grp, syp, FALSE)) return(NULL);
5475  *endsytp = sytp;
5476  return(syp);
5477 }
5478 
5479 /*
5480  * check global selects
5481  *
5482  * error if select of non inst array and non select of inst. array
5483  * this is called during global input, can not check select exprs
5484  */
chk_glb_inst_sels(struct gref_t * grp)5485 static int32 chk_glb_inst_sels(struct gref_t *grp)
5486 {
5487  register int32 gi;
5488  int32 good, ii;
5489  struct sy_t *syp, *up_syp;
5490  struct inst_t *ip;
5491  struct mod_t *mdp, *up_mdp;
5492 
5493  for (good = TRUE, up_syp = NULL, gi = 0; gi <= __last_gsc; gi++)
5494   {
5495    syp = __glbsycmps[gi];
5496    if (syp->sytyp != SYM_I)
5497     {
5498      if (__glbxcmps[gi] != NULL)
5499       {
5500        __sgferr(695,
5501         "hierarchical path %s illegal select of %s symbol - never arrayed",
5502         grp->gnam, __to_sytyp(__xs, syp->sytyp));
5503        good = FALSE;
5504       }
5505      continue;
5506     }
5507    /* know symbol is instance */
5508    /* if inst select but not array of instances, select illegal */
5509    ip = syp->el.eip;
5510    mdp = ip->imsym->el.emdp;
5511    /* know this component inst, need to access up module */
5512    if (gi == 0)
5513     {
5514      /* first component instance mean down relative */
5515      /* DBG remove -- */
5516      if (grp->is_rooted) __misc_terr(__FILE__, __LINE__);
5517      /* --- */
5518      up_mdp = grp->gin_mdp;
5519     }
5520    else
5521     {
5522      up_syp = __glbsycmps[gi - 1];
5523      if (up_syp->sytyp == SYM_I) up_mdp = up_syp->el.eip->imsym->el.emdp;
5524      else if (up_syp->sytyp == SYM_M) up_mdp = up_syp->el.emdp;
5525      else { up_mdp = NULL;__case_terr(__FILE__, __LINE__); }
5526     }
5527    ii = ((byte *) ip - (byte *) up_mdp->minsts)/sizeof(struct inst_t);
5528 
5529    if (up_mdp->miarr == NULL || up_mdp->miarr[ii] == NULL)
5530     {
5531      if (__glbxcmps[gi] == NULL) continue;
5532      __sgferr(696,
5533       "hierarchical path %s select illegal for non vectored instance %s (type %s)",
5534       grp->gnam, ip->isym->synam, mdp->msym->synam);
5535      good = FALSE;
5536      continue;
5537     }
5538    /* final case vectored instance - select required */
5539    if (__glbxcmps[gi] != NULL) continue;
5540    __sgferr(697,
5541     "hierarchical path %s missing required select of vectored instance %s (type %s)",
5542     grp->gnam, ip->isym->synam, mdp->msym->synam);
5543    good = FALSE;
5544   }
5545  return(good);
5546 }
5547 
5548 /*
5549  * ROUTINES TO ACCESS AND BUILD GLOBALS USING STRINGS
5550  */
5551 
5552 /*
5553  * convert global reference as string into global path expression
5554  *
5555  * no white space allowed except to end escaped IDs
5556  * handles escaped IDs (\...[white space] and ending [<number>] for inst arrays
5557  * source xmr's can have spaces but not allowed here - make sure documented
5558  *
5559  * this can return one component xmr
5560  */
__glbnam_to_expr(char * irefs)5561 extern struct expr_t *__glbnam_to_expr(char *irefs)
5562 {
5563  int32 slen, ind, esc_name;
5564  struct expr_t *glbndp, *gcmp_ndp, *sel_ndp;
5565  char *chp, *chp2, *chp3, *sepchp;
5566  char s1[IDLEN], s2[IDLEN], s3[IDLEN];
5567 
5568  /* allocate top node */
5569  glbndp = __alloc_newxnd();
5570  glbndp->optyp = GLBREF;
5571  gcmp_ndp = glbndp;
5572  for (chp = irefs;;)
5573   {
5574    /* separate out one component */
5575    /* case 1: escaped name */
5576    esc_name = FALSE;
5577    if (*chp == '\\')
5578     {
5579      if (chp[1] == ' ')
5580       {
5581        __sgferr(1138,
5582         "global reference %s illegal - empty escaped component illegal",
5583         irefs);
5584 bad_end:
5585        __free_xtree(glbndp);
5586        return(NULL);
5587       }
5588      if ((chp2 = strchr(chp, ' ')) == NULL)
5589       {
5590        __sgferr(1138,
5591         "global reference %s illegal - escaped component ending space missing",
5592         irefs);
5593        goto bad_end;
5594       }
5595      /* include one space in escaped ID */
5596      chp2++;
5597      strncpy(s1, chp, chp2 - chp);
5598      /* escaped ID now extracted into s1 */
5599      s1[chp2 - chp] = '\0';
5600      while (*chp2 == ' ') chp2++;
5601      if (*chp2 == '[')
5602       {
5603        if ((chp3 = strchr(chp2, ']')) == NULL)
5604         {
5605          __sgferr(1139,
5606           "global reference %s illegal - instance array select missing ']'",
5607           irefs);
5608          goto bad_end;
5609         }
5610        chp3++;
5611        strncpy(s2, chp2, chp3 - chp2);
5612        s2[chp3 - chp2] = '\0';
5613        strcat(s1, s2);
5614        /* one past ending ']' */
5615        sepchp = chp3;
5616       }
5617      else sepchp = chp2;
5618      esc_name = TRUE;
5619     }
5620    else
5621     {
5622      /* case 2: non escaped maybe instance array select */
5623      if ((chp2 = strchr(chp, '.')) != NULL)
5624       {
5625        strncpy(s1, chp, chp2 - chp);
5626        s1[chp2 - chp] = '\0';
5627        /* point to '.' separator */
5628        sepchp = chp2;
5629       }
5630      else
5631       {
5632        strcpy(s1, chp);
5633        slen = strlen(chp);
5634        /* point to '\0' */
5635        sepchp = &(chp[slen]);
5636       }
5637     }
5638    /* s1 contains component maybe with select */
5639    if (esc_name || (chp = strchr(s1, '[')) == NULL)
5640     {
5641      /* case 1: non instance select form */
5642      gcmp_ndp->ru.x = __alloc_newxnd();
5643      gcmp_ndp->ru.x->optyp = XMRCOM;
5644      gcmp_ndp = gcmp_ndp->ru.x;
5645      gcmp_ndp->lu.x = __alloc_newxnd();
5646      gcmp_ndp->lu.x->optyp = XMRID;
5647      gcmp_ndp->lu.x->ru.qnchp = __pv_stralloc(s1);
5648     }
5649    else
5650     {
5651      /* case 2: instance select form */
5652      /* chp points into [ in s1 */
5653      strncpy(s2, s1, chp - s1);
5654      s2[chp - s1] = '\0';
5655      if ((chp2 = strchr(chp, ']')) == NULL)
5656       {
5657        __sgferr(1139,
5658         "global reference %s illegal - instance array select missing ']'",
5659         irefs);
5660        goto bad_end;
5661       }
5662      chp++;
5663      /* chp point to first digit that gets put into s3 */
5664      strncpy(s3, chp, chp2 - chp);
5665      s3[chp2 - chp] = '\0';
5666      for (chp = s3; *chp != '\0'; chp++)
5667       {
5668        if (!isdigit(*chp))
5669         {
5670 bad_sel_index:
5671           __sgferr(1139,
5672           "global reference %s illegal - instance select must be number",
5673           irefs);
5674          goto bad_end;
5675         }
5676       }
5677      if (sscanf(s3, "%d", &ind) != 1 || ind < 0) goto bad_sel_index;
5678      sel_ndp = __alloc_newxnd();
5679      sel_ndp->optyp = LSB;
5680      sel_ndp->lu.x = __alloc_newxnd();
5681      sel_ndp->lu.x->optyp = XMRID;
5682      sel_ndp->lu.x->ru.qnchp = __pv_stralloc(s2);
5683      sel_ndp->ru.x = __alloc_newxnd();
5684      __set_numval(sel_ndp->ru.x, (word32) ind, 0L, WBITS);
5685 
5686      gcmp_ndp->ru.x = __alloc_newxnd();
5687      gcmp_ndp->ru.x->optyp = XMRCOM;
5688      gcmp_ndp = gcmp_ndp->ru.x;
5689      gcmp_ndp->lu.x = sel_ndp;
5690     }
5691    /* sepchp points into separae iref string */
5692    if (*sepchp  == '\0') break;
5693    else if (*sepchp != '.')
5694     {
5695      __sgferr(1139,
5696       "global reference %s internal component not followed by '.' separator",
5697       irefs);
5698      goto bad_end;
5699     }
5700    chp = sepchp;
5701    chp++;
5702   }
5703  return(glbndp);
5704 }
5705 
5706 /*
5707  * return pointer to component name of current component of global expr
5708  *
5709  * FIXME - this returns instance name but does not deal with number index
5710  */
__to_glbcmp_nam(struct expr_t * gcmp_ndp)5711 extern char *__to_glbcmp_nam(struct expr_t *gcmp_ndp)
5712 {
5713  char *chp;
5714 
5715  if (gcmp_ndp->lu.x->optyp == XMRID) chp = gcmp_ndp->lu.x->ru.qnchp;
5716  else if (gcmp_ndp->lu.x->optyp == LSB || gcmp_ndp->lu.x->optyp == PARTSEL)
5717   chp = gcmp_ndp->lu.x->lu.x->ru.qnchp;
5718  else { __case_terr(__FILE__, __LINE__); return(NULL); }
5719  return(chp);
5720 }
5721 
5722 /*
5723  * ROUTINES TO FREE GLOBAL DATA STRUCTURES
5724  */
5725 
5726 /*
5727  * free a defparam
5728  * may want to keep defparams and global for debugging
5729  * but latest value of parameter is what is needed not defparam
5730  *
5731  * global marked as gone so will be freed later
5732  */
__free_1dfparam(struct dfparam_t * dfpp)5733 extern void __free_1dfparam(struct dfparam_t *dfpp)
5734 {
5735  if (dfpp->last_dfpi > -1 && dfpp->dfpiis != NULL)
5736   __my_free((char *) dfpp->dfpiis, (dfpp->last_dfpi + 1)*sizeof(int32));
5737  __free_xtree(dfpp->dfpxlhs);
5738  /* notice cannot free rhs since moved to parameter value rhs */
5739  /* if error, will stop so no need to free */
5740  __my_free((char *) dfpp, sizeof(struct dfparam_t));
5741 }
5742 
5743 /*
5744  * free globals marked to be freed - mostly for defparam tmp globals
5745  *
5746  * must remove gone and err from grtab and fix up gxndp ptrs or
5747  * will process with empty guts and can't skip steps if only defparams
5748  */
free_gone_glbs(void)5749 static void free_gone_glbs(void)
5750 {
5751  register int32 gri, ngri;
5752  register struct gref_t *grp;
5753  register struct mod_t *mdp;
5754  struct gref_t *ngrtab;
5755  int32 ngrnum;
5756 
5757  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
5758   {
5759    if (mdp->mgrnum == 0) continue;
5760    __push_wrkitstk(mdp, 0);
5761 
5762    /* first count remaining */
5763    grp = &(mdp->mgrtab[0]);
5764    for (ngrnum = gri = 0; gri < __inst_mod->mgrnum; grp++, gri++)
5765     {
5766      /* if global gone or error will not get counted at all */
5767      if (grp->gr_err || grp->gr_gone) continue;
5768      ngrnum++;
5769     }
5770    /* nothing to remove */
5771    if (ngrnum == __inst_mod->mgrnum) goto nxt_mod;
5772    /* all removed */
5773    if (ngrnum == 0)
5774     {
5775      __my_free((char *) __inst_mod->mgrtab,
5776       __inst_mod->mgrnum*sizeof(struct gref_t));
5777      __inst_mod->mgrtab = NULL;
5778      __inst_mod->mgrnum = 0;
5779      goto nxt_mod;
5780     }
5781 
5782    ngrtab = (struct gref_t *) __my_malloc(ngrnum*sizeof(struct gref_t));
5783    grp = &(mdp->mgrtab[0]);
5784    for (ngri = gri = 0; gri < __inst_mod->mgrnum; grp++, gri++)
5785     {
5786      /* this frees contents of global but left in table */
5787      if (grp->gr_err || grp->gr_gone) { __free_1glb_flds(grp); continue; }
5788 
5789      ngrtab[ngri] = *grp;
5790      ngrtab[ngri].gxndp->ru.grp = &(ngrtab[ngri]);
5791      ngri++;
5792     }
5793    __my_free((char *) __inst_mod->mgrtab,
5794     __inst_mod->mgrnum*sizeof(struct gref_t));
5795    __inst_mod->mgrtab = ngrtab;
5796    __inst_mod->mgrnum = ngrnum;
5797 
5798 nxt_mod:
5799    __pop_wrkitstk();
5800   }
5801 }
5802 
5803 /*
5804  * allocate and fill new gref table
5805  *
5806  * also always fixes up r_u ptrs from expr. to to newly alloced global
5807  */
__alloc_grtab(struct gref_t * oldgrtab,int32 grnum)5808 extern struct gref_t *__alloc_grtab(struct gref_t *oldgrtab, int32 grnum)
5809 {
5810  register int32 gri;
5811  register struct gref_t *grp;
5812  struct gref_t *ngrtab;
5813 
5814  /* DBG remove -- */
5815  if (grnum <= 0) __arg_terr(__FILE__, __LINE__);
5816  /* --- */
5817  ngrtab = (struct gref_t *) __my_malloc(grnum*sizeof(struct gref_t));
5818  memcpy(ngrtab, oldgrtab, grnum*sizeof(struct gref_t));
5819 
5820  /* pointer from expr nodes need to be fixed to point to new addr */
5821  grp = &(ngrtab[0]);
5822  for (gri = 0; gri < grnum; grp++, gri++) grp->gxndp->ru.grp = grp;
5823  return(ngrtab);
5824 }
5825 
5826 /*
5827  * free 1 global's fields
5828  *
5829  * caller must free table containing this global if needed
5830  * LOOKATME - what if gnam in name table (think never calling this then)?
5831  */
__free_1glb_flds(struct gref_t * grp)5832 extern void __free_1glb_flds(struct gref_t *grp)
5833 {
5834  /* if using this for local qualifed name will be set to nil */
5835  if (grp->gnam != NULL) __my_free((char *) grp->gnam, strlen(grp->gnam + 1));
5836  grp->gnam = NULL;
5837  /* also free glb ref exprssion - always in malloced memory here */
5838  __free_xtree(grp->glbref);
5839 
5840  /* only sized targu is upwards rel list - may not have been alloced yet */
5841  if (grp->upwards_rel && grp->targu.uprel_itps != NULL)
5842   {
5843    __my_free((char *) grp->targu.uprel_itps,
5844     grp->gin_mdp->flatinum*sizeof(struct itree_t *));
5845   }
5846  if (grp->grcmps != NULL)
5847   {
5848    __my_free((char *) grp->grcmps, (grp->last_gri + 1)*sizeof(struct sy_t *));
5849    grp->grcmps = NULL;
5850   }
5851  if (grp->grxcmps != NULL)
5852   {
5853    __my_free((char *) grp->grxcmps,
5854     (grp->last_gri + 1)*sizeof(struct expr_t *));
5855    grp->grxcmps = NULL;
5856   }
5857 }
5858 
5859 /*
5860  * ROUTINES TO DO POUND PARAM SPLITTING
5861  */
5862 
5863 /*
5864  * work form bottom up marking all instances that need to be split
5865  * and all params that are width determining or indirect width determining
5866  */
mark_poundparam_splitinsts(void)5867 static void mark_poundparam_splitinsts(void)
5868 {
5869  register int32 ii, mlevel, pi;
5870  int32 split_inst;
5871  struct mod_t *mdp;
5872  int32 giawid;
5873  struct inst_t *ip;
5874  struct mod_t *imdp;
5875  struct giarr_t *giap;
5876  struct expr_t *pxp;
5877  struct net_t *modnp;
5878 
5879  /* bottom modules which do not instantiate anything special case */
5880  for (mdp = __mdlevhdr[0]; mdp != NULL; mdp = mdp->mlevnxt)
5881   {
5882    /* for bottom pound params, if only one flat instance - nothing to do */
5883    /* because if only one flat instance then know anything instantiating */
5884    /* also only one flat inst */
5885    if (mdp->flatinum == 1) continue;
5886 
5887    __push_wrkitstk(mdp, 0);
5888    /* this also set mod has width determining bit */
5889    if (!mdp->mwiddetdone)
5890     { __mark_widdet_params(mdp); mdp->mwiddetdone = TRUE; }
5891    __pop_wrkitstk();
5892   }
5893 
5894  /* work upward in levelized dag marking width determining params and */
5895  /* instance that need to be split */
5896  __pndparam_splits = FALSE;
5897  for (mlevel = 1; mlevel <= __dagmaxdist; mlevel++)
5898   {
5899    for (mdp = __mdlevhdr[mlevel]; mdp != NULL; mdp = mdp->mlevnxt)
5900     {
5901      __push_wrkitstk(mdp, 0);
5902 
5903      /* width determining needs module context - always set here */
5904      /* if has width determining, becomes probable if ever instantiated */
5905      /* if only 1 inst in design no need to mark width determining */
5906      if (mdp->flatinum > 1)
5907       {
5908        if (!mdp->mwiddetdone)
5909         { __mark_widdet_params(mdp); mdp->mwiddetdone = TRUE; }
5910       }
5911 
5912      /* even if only one inst of mod, must still try to split insts of mod in*/
5913 
5914      /* for every instance in module, see if need to split */
5915      for (ii = 0; ii < __inst_mod->minum; ii++)
5916       {
5917        /* if instance in mod is inst array (first) never split and do not */
5918        /* even check other expanded from in source instance array */
5919        /* pound param splitting in inst arrays illegal */
5920        /* LOOKATME - is error emitted somewhere? */
5921        /* for contained insts that came from mi arrays, no pnd param split */
5922        if (__inst_mod->miarr != NULL && (giap = __inst_mod->miarr[ii]) != NULL)
5923         {
5924          giawid = __get_giarr_wide(giap);
5925          /* always inc by one in for loop above */
5926          ii += (giawid - 1);
5927          continue;
5928         }
5929 
5930        ip = &(__inst_mod->minsts[ii]);
5931        if (ip->ipxprtab == NULL) continue;
5932 
5933        /* LOOKATME - think these not used */
5934        __sfnam_ind = ip->isym->syfnam_ind;
5935        __slin_cnt = ip->isym->sylin_cnt;
5936 
5937        /* imdp is module type of instance that has pound param */
5938        imdp = ip->imsym->el.emdp;
5939 
5940        /* if one inst never split - even if in later splitting by here */
5941        /* spliting would result in 0 insts, mark here but stop when split */
5942        if (imdp->flatinum == 1)
5943         {
5944          if (__debug_flg)
5945           {
5946            __dbg_msg("++ # form inst. %s(%s) not split - only one instance\n",
5947            ip->isym->synam, imdp->msym->synam);
5948           }
5949          continue;
5950         }
5951        /* know contained module has all width determining params set */
5952        /* if no width determining and no indir width determining, done */
5953        if (!imdp->mhas_widthdet && !imdp->mhas_indir_widdet)
5954         {
5955          if (__debug_flg)
5956           {
5957            __dbg_msg(
5958             "++ # form inst. %s(%s) not split - no params in ranges\n",
5959             ip->isym->synam, imdp->msym->synam);
5960           }
5961          continue;
5962         }
5963 
5964        split_inst = FALSE;
5965        /* go through defined params in one down mod */
5966        for (pi = 0; pi < imdp->mprmnum; pi++)
5967         {
5968          pxp = ip->ipxprtab[pi];
5969          /* explicit form this one unused or short list */
5970          if (pxp == NULL) continue;
5971 
5972          modnp = &(imdp->mprms[pi]);
5973          /* if down mod has width determining, but none of the width */
5974          /* determining passed down to this inst. as pound param, no split */
5975          if (modnp->nu.ct->n_widthdet || modnp->nu.ct->n_indir_widthdet)
5976           {
5977            /* set indirect width determining */
5978 
5979            /* if no up expr params set as indirect width determining, do not */
5980            /* need to split, but other source locs insts of type may split */
5981            /* returns T if any set */
5982            if (indir_widthdet_markparam(pxp)) split_inst = TRUE;
5983           }
5984         }
5985        /* if no width determining and no indir width determining, done */
5986        if (!split_inst)
5987         {
5988          if (__debug_flg)
5989           {
5990            __dbg_msg(
5991             "++ # form inst. %s(%s) not split - no range # params\n",
5992             ip->isym->synam, imdp->msym->synam);
5993           }
5994         }
5995        ip->i_pndsplit = TRUE;
5996       }
5997      __pop_wrkitstk();
5998     }
5999   }
6000 }
6001 
6002 /*
6003  * set the indirect width determining bit for any wire up pound param expr
6004  * return T if any params in this up expr else F
6005  */
indir_widthdet_markparam(struct expr_t * xp)6006 static int32 indir_widthdet_markparam(struct expr_t *xp)
6007 {
6008  int32 rv, rv2;
6009  struct net_t *np;
6010 
6011  rv = rv2 = FALSE;
6012  if (__isleaf(xp))
6013   {
6014    if (xp->optyp == ID && xp->lu.sy->sytyp == SYM_N)
6015     {
6016      np = xp->lu.sy->el.enp;
6017      if (np->n_isaparam)
6018       {
6019        /* if already width determining, can't be indir width determining */
6020        if (!np->nu.ct->n_widthdet)
6021         {
6022          np->nu.ct->n_indir_widthdet = TRUE;
6023          __inst_mod->mhas_indir_widdet = TRUE;
6024          rv = TRUE;
6025         }
6026       }
6027     }
6028    return(rv);
6029   }
6030  if (xp->lu.x != NULL) rv = indir_widthdet_markparam(xp->lu.x);
6031  if (xp->ru.x != NULL) rv2 = indir_widthdet_markparam(xp->ru.x);
6032  if (rv || rv2) return(TRUE);
6033  return(FALSE);
6034 }
6035 
6036 /*
6037  * work from top down splitting off static instance locations for
6038  * pound parameters that are width determining or indirect width determining
6039  * such instances are already marked
6040  *
6041  * splitting here may produce modules with more than 1 flat instance
6042  */
do_poundparam_splitting(void)6043 static void do_poundparam_splitting(void)
6044 {
6045  register int32 ii, mlevel;
6046  register struct mod_t *mdp;
6047  int32 giawid;
6048  struct inst_t *ip;
6049  struct mod_t *imdp;
6050  struct giarr_t *giap;
6051 
6052  __pndparam_splits = FALSE;
6053  /* work from top (mod) down - since need fixed no pound param start */
6054  /* LOOKATME - wonder if bottom up works - think not */
6055  for (mlevel = __dagmaxdist; mlevel >= 1; mlevel--)
6056   {
6057    /* SJM 03/16/04 - notice processing from one up and splitting (if needed) */
6058    /* contained insts - therefore mlevel of md lev hdr list not chged */
6059    /* inside this loop - mlevel one less may use update list */
6060    for (mdp = __mdlevhdr[mlevel]; mdp != NULL; mdp = mdp->mlevnxt)
6061     {
6062      __push_wrkitstk(mdp, 0);
6063 
6064      /* do all splitting from pound params - also check but cannot set */
6065      /* for every instance in module */
6066      for (ii = 0; ii < __inst_mod->minum; ii++)
6067       {
6068        /* if instance in mod is inst array (first) never split and do not */
6069        /* even check other expanded from in source instance array */
6070        /* for contained insts that came from mi arrays, no pnd param split */
6071        if (__inst_mod->miarr != NULL && (giap = __inst_mod->miarr[ii]) != NULL)
6072         {
6073          giawid = __get_giarr_wide(giap);
6074          /* always inc by one in for loop above */
6075          ii += (giawid - 1);
6076          continue;
6077         }
6078 
6079        ip = &(__inst_mod->minsts[ii]);
6080        if (!ip->i_pndsplit) continue;
6081 
6082        /* when splitting marked, marked for all but do not split last */
6083        /* when splitting would result in nonsense 0 insts */
6084 
6085        imdp = ip->imsym->el.emdp;
6086        if (imdp->flatinum == 1 || imdp->flatinum == __inst_mod->flatinum)
6087         {
6088          if (__debug_flg)
6089           {
6090            __dbg_msg(
6091             "++ # form inst. %s(%s) not split - last %d splittable insts\n",
6092             ip->isym->synam, ip->imsym->synam, __inst_mod->flatinum);
6093           }
6094          continue;
6095         }
6096 
6097        /* DBG remove -- */
6098        if (__inst_mod->flatinum == 0) __misc_terr(__FILE__, __LINE__);
6099        /* --- */
6100 
6101        if (__debug_flg)
6102         {
6103          __dbg_msg(
6104           "++ # form inst. %s(%s) split (%d new instances)\n",
6105           ip->isym->synam, imdp->msym->synam, __inst_mod->flatinum);
6106         }
6107 
6108        __sfnam_ind = ip->isym->syfnam_ind;
6109        __slin_cnt = ip->isym->sylin_cnt;
6110 
6111        /* imdp is module type of instance that has pound param */
6112        /* SJM 03/16/04 - notice mlevel is one above imdp being split off */
6113        split_upd_mod(imdp, ip, mlevel);
6114       }
6115      __pop_wrkitstk();
6116     }
6117   }
6118 }
6119 
6120 /*
6121  * split (copy) module from pound params or arrays of gate/insts where
6122  * assumes tmp itree loc set and sets/uses various other globals
6123  *
6124  * called after conditions for split determined to be true
6125  * does copy and update the static (in source text) instance d.s.
6126  */
split_upd_mod(struct mod_t * imdp,struct inst_t * ip,int32 mlevel)6127 static void split_upd_mod(struct mod_t *imdp, struct inst_t *ip, int32 mlevel)
6128 {
6129  struct mod_t *ipmdp, *sav_inst_mod;
6130 
6131  /* this is one up module containing instance for which new module split off */
6132  sav_inst_mod = __inst_mod;
6133  __do_mdsplit(imdp);
6134  __pndparam_splits = TRUE;
6135 
6136  /* after here new (in __inst_mod) set to new, and old set to old - 1 */
6137  /* ipmdp is newly split off, sav cur mod if old split from */
6138  ipmdp = __inst_mod;
6139  /* adjust type of this instance */
6140  ip->imsym = ipmdp->msym;
6141  /* adjust inst numbers (spilt set new number to 1 and old to old - 1) */
6142  ipmdp->flatinum = sav_inst_mod->flatinum;
6143  if (ipmdp->flatinum > 1) ipmdp->minstnum = 2;
6144 
6145  /* imdp is old, reduce by number of times containing module instantiated */
6146  imdp->flatinum -= sav_inst_mod->flatinum;
6147  /* during splitting reduced count by one too many - adjust back */
6148  imdp->flatinum++;
6149  /* SJM 02/17/00 - must adjust new split off module to have right inst */
6150  /* num */
6151  if (imdp->flatinum > 1) imdp->minstnum = 2;
6152 
6153  /* now adjust so both are masters that can be split from */
6154  /* this may cause lots of $$[num] prefixes */
6155  /* DBG remove --- */
6156  if (imdp->msplit) __misc_terr(__FILE__, __LINE__);
6157  /* --- */
6158  ipmdp->msplit = FALSE;
6159  /* if split off others from new, add new prefix starting at 1 */
6160  ipmdp->mversno = 0;
6161  imdp->mhassplit = FALSE;
6162  /* this must remain a defparm master since master applies only to */
6163  /* pealing off 1 instance paths from defparams */
6164  ipmdp->mspltmst = NULL;
6165  ipmdp->mpndsplit = TRUE;
6166  /* but need to record master of pound split off */
6167  ipmdp->mpndspltmst = imdp;
6168 
6169  /* SJM 03/16/04 - passed mlevel is one higher than imdp being split */
6170  /* must add new split to dag list but for one down that is processed later */
6171  /* but must incrementally update the md lev hdr list during splitting */
6172  ipmdp->mlevnxt = __mdlevhdr[mlevel - 1];
6173  __mdlevhdr[mlevel - 1] = ipmdp;
6174  /* put back current module to up module instances in */
6175  __inst_mod = sav_inst_mod;
6176 }
6177 
6178 /*
6179  * ROUTINES TO SPLIT (COPY) MODULES
6180  */
6181 
6182 /*
6183  * copy the module and link in to list module list unless only 1 inst.
6184  * __modsyms updated when this is done so split module insts. can be split
6185  *
6186  * if from pound param splitting must also copy non rooted defparams
6187  * split off module, splitting sets __inst_mod to point to it
6188  * so caller must save and restore __inst_mod
6189  */
__do_mdsplit(struct mod_t * smdp)6190 extern void __do_mdsplit(struct mod_t *smdp)
6191 {
6192  char s1[IDLEN];
6193  struct sy_t *syp;
6194 
6195  /* for master, version no. is highest of split off, else actual no. */
6196  if (!smdp->msplit)
6197   {
6198    /* __splitting a module effects exactly one flattened inst. too */
6199    /* flat inst counts and version numbers only kept in original master */
6200    (smdp->mversno)++;
6201    sprintf(s1, "%s$$%d", smdp->msym->synam, smdp->mversno);
6202   }
6203  else
6204   {
6205    /* for module, should never split from already split */
6206    __misc_terr(__FILE__, __LINE__);
6207   }
6208  __splitting = TRUE;
6209  copy_mod(smdp, s1);
6210  /* new split off module now pointed to by __inst_mod */
6211  __splitting = FALSE;
6212 
6213  /* must link on end so gets processed later */
6214  if (__end_mdp == NULL) __modhdr = __inst_mod;
6215   else __end_mdp->mnxt = __inst_mod;
6216  __end_mdp = __inst_mod;
6217  syp = smdp->msym;
6218  __gfinform(409, syp->syfnam_ind, syp->sylin_cnt,
6219   "module %s converted to new type - defparam or # parameter changes width",
6220   syp->synam);
6221 }
6222 
6223 /*
6224  * copy a module - point __inst_mod to new module
6225  *
6226  * this is passed the master to copy out of
6227  * expects splitting to be true and adjust old module counts
6228  * new module does not have any defparams since info from master's
6229  * if from pound must copy non rooted defparams also
6230  *
6231  * this copies internal module components but does not insert new module
6232  * type in itree or up module's inst_t list
6233  *
6234  * BEWARE - non standard use of inst mod required here no itstk value
6235  */
copy_mod(struct mod_t * omdp,char * newnam)6236 static void copy_mod(struct mod_t *omdp, char *newnam)
6237 {
6238  struct sy_t *syp;
6239 
6240  __oinst_mod = omdp;
6241  __inst_mod = (struct mod_t *) __my_malloc(sizeof(struct mod_t));
6242 
6243  /* notice this copies the flags which always stay the same */
6244  *__inst_mod = *omdp;
6245 
6246  __inst_mod->msplit = TRUE;
6247  __oinst_mod->mhassplit = TRUE;
6248  /* must add new name to modsyms - copy here can not effect undef mods */
6249  /* because all references resolved or will not get here */
6250  if ((syp = __add_modsym(newnam)) == NULL)
6251   {
6252    /* unable to split module to version and name */
6253    __misc_gfterr(__FILE__, __LINE__, omdp->msym->syfnam_ind,
6254     omdp->msym->sylin_cnt);
6255   }
6256 
6257  /* must set new sym and new version */
6258  syp->sydecl = TRUE;
6259  syp->el.emdp = __inst_mod;
6260  syp->syfnam_ind = __oinst_mod->msym->syfnam_ind;
6261  syp->sylin_cnt = __oinst_mod->msym->sylin_cnt;
6262  /* never need to connect through old splt sym here */
6263  __inst_mod->msym = syp;
6264 
6265  /* __splitting off from already split impossible */
6266  if (__oinst_mod->mspltmst != NULL) __misc_terr(__FILE__, __LINE__);
6267 
6268  /* not decing non flattented module insts. = only used to determine tops */
6269  (__oinst_mod->flatinum)--;
6270  /* can never be 0 instances of old copied from */
6271  if (__oinst_mod->flatinum == 1) __oinst_mod->minstnum = 1;
6272  __inst_mod->minstnum = 1;
6273  __inst_mod->flatinum = 1;
6274 
6275  /* connect current module to module type that was its source */
6276  /* if split off already split, link to real master */
6277  /* once split off no way to resplit since params frozen at split point */
6278  if (__oinst_mod->mspltmst != NULL)
6279   __inst_mod->mspltmst = __oinst_mod->mspltmst;
6280  else __inst_mod->mspltmst = __oinst_mod;
6281 
6282  /* caller responsible for linking into list */
6283  __inst_mod->mnxt = NULL;
6284  /* copy symbol table including all lower such as tasks and named blocks */
6285  copy_modsymtabs();
6286 
6287  /* must copy global references before copy any expressions */
6288  copy_mgrefs();
6289 
6290  /* never copy module's defparams since already moved to design wide list */
6291  /* also any grefs related to defparams removed by here */
6292  __inst_mod->mdfps = NULL;
6293 
6294  /* notice since params and ports really wires, must copy nets first */
6295  /* but after symbol table copied */
6296  copy_wires(__oinst_mod->msymtab);
6297  copy_modports();
6298  __inst_mod->mprms = copy_params(__oinst_mod->mprms, __oinst_mod->mprmnum,
6299   MODULE);
6300 
6301  /* AIV 09/27/06 - need to copy the local params as well */
6302  __inst_mod->mlocprms = copy_params(__oinst_mod->mlocprms,
6303   __oinst_mod->mlocprmnum, MODULE);
6304 
6305  if (__oinst_mod->mdfps != NULL) copy_defparams();
6306  if (__oinst_mod->mattrs != NULL)
6307   __inst_mod->mattrs = copy_attrs(__oinst_mod->mattrs);
6308  if (__oinst_mod->mvarinits != NULL)
6309   __inst_mod->mvarinits = copy_varinits(__oinst_mod->mvarinits);
6310 
6311  copy_insts();
6312  copy_miarr();
6313 
6314  copy_gates();
6315  copy_mgarr();
6316 
6317  copy_contas();
6318  copy_mdtasks();
6319 
6320  __inst_mod->ialst = copy_ialst(__oinst_mod->ialst);
6321  if (__oinst_mod->mspfy != NULL) copy_specify();
6322 }
6323 
6324 
6325 /*
6326  * copy module symbol table structure
6327  * expects __oinst_mod to be set to old inst mod, __inst_mod to newly alloced
6328  * still must set all symbol el. union values
6329  * this does not copy specify symbol table for specparams
6330  */
copy_modsymtabs(void)6331 static void copy_modsymtabs(void)
6332 {
6333  struct symtab_t *nsytp, *osytp;
6334 
6335  osytp = __oinst_mod->msymtab;
6336  nsytp = copy_1symtab(osytp);
6337  nsytp->sytpar = NULL;
6338  nsytp->sytsib = NULL;
6339  nsytp->sytofs = NULL;
6340  /* this copyeis and connects by linking in pointers */
6341  if (osytp->sytofs != NULL) copy_lowsymtab(osytp->sytofs, nsytp);
6342  __inst_mod->msymtab = nsytp;
6343  nsytp->sypofsyt = __inst_mod->msym;
6344 }
6345 
6346 /*
6347  * depth first symbol table tree traversal across offspring
6348  */
copy_lowsymtab(register struct symtab_t * osytp,struct symtab_t * nupsytp)6349 static void copy_lowsymtab(register struct symtab_t *osytp,
6350  struct symtab_t *nupsytp)
6351 {
6352  struct symtab_t *nsytp, *last_nsytp;
6353 
6354  for (last_nsytp = NULL; osytp != NULL; osytp = osytp->sytsib)
6355   {
6356    nsytp = copy_1symtab(osytp);
6357    if (last_nsytp == NULL) nupsytp->sytofs = nsytp;
6358    else last_nsytp->sytsib = nsytp;
6359 
6360    /* link up */
6361    nsytp->sytpar = nupsytp;
6362    /* copy underneath level (know only frozen tables copied) */
6363    if (osytp->sytofs != NULL) copy_lowsymtab(osytp->sytofs, nsytp);
6364    nsytp->sytsib = NULL;
6365    last_nsytp = nsytp;
6366   }
6367 }
6368 
6369 /*
6370  * copy one symbol table
6371  * caller fills in up and down links
6372  */
copy_1symtab(struct symtab_t * osytp)6373 static struct symtab_t *copy_1symtab(struct symtab_t *osytp)
6374 {
6375  int32 ofreezes;
6376  struct symtab_t *nsytp;
6377 
6378  ofreezes = osytp->freezes;
6379  nsytp = __alloc_symtab(ofreezes);
6380  *nsytp = *osytp;
6381  /* must leave as NULL if empty table */
6382  if (osytp->numsyms == 0) nsytp->stsyms = NULL;
6383  else nsytp->stsyms = copy_stsyms(osytp->stsyms, osytp->numsyms);
6384 
6385  /* when above symbol table was copied, old symbol links to new */
6386  /* SJM 12/26/03 - specify symbol table has no associated symbol */
6387  if (osytp->sypofsyt != NULL) nsytp->sypofsyt = osytp->sypofsyt->spltsy;
6388  else nsytp->sypofsyt = NULL;
6389 
6390  /* must link old to point to new (n_head now unused) */
6391  osytp->n_head = (struct tnode_t *) nsytp;
6392  return(nsytp);
6393 }
6394 
6395 /*
6396  * copy stsyms - know at least one symbol in table
6397  */
copy_stsyms(struct sy_t ** osytab,word32 nsyms)6398 static struct sy_t **copy_stsyms(struct sy_t **osytab,
6399  word32 nsyms)
6400 {
6401  register int32 i;
6402  struct sy_t **sytbp;
6403  struct sy_t *nsyp;
6404  int32 bytes;
6405 
6406  bytes = nsyms*sizeof(struct sy_t *);
6407  __wrkstab = (struct sy_t **) __my_malloc(bytes);
6408  for (i = 0; i < (int32) nsyms; i++)
6409   {
6410    /* allocate the new symbol */
6411    nsyp = (struct sy_t *) __my_malloc(sizeof(struct sy_t));
6412    *nsyp = *(osytab[i]);
6413    /* set union to NULL, any member will do */
6414    nsyp->el.ecp = NULL;
6415    __wrkstab[i] = nsyp;
6416    /* tmp link from old to new */
6417    osytab[i]->spltsy = nsyp;
6418   }
6419  sytbp = __wrkstab;
6420  return(sytbp);
6421 }
6422 
6423 /*
6424  * copy module ports
6425  */
copy_modports(void)6426 static void copy_modports(void)
6427 {
6428  register int32 pi;
6429  register struct mod_pin_t *ompp, *nmpp;
6430  int32 pnum;
6431 
6432  if ((pnum = __oinst_mod->mpnum) == 0) return;
6433 
6434  __inst_mod->mpins = (struct mod_pin_t *)
6435   __my_malloc(pnum*sizeof(struct mod_pin_t));
6436 
6437  nmpp = &(__inst_mod->mpins[0]);
6438  for (pi = 0, ompp = &(__oinst_mod->mpins[0]); pi < pnum; pi++, ompp++, nmpp++)
6439   {
6440    *nmpp = *ompp;
6441    nmpp->mpref = __copy_expr(ompp->mpref);
6442   }
6443 }
6444 
6445 /*
6446  * copy wires from __oinst_mod to __inst_mod
6447  * also link in nsym and symbol table el.enp
6448  * know decl. symbol tables for these
6449  *
6450  * at this point do not know if wire correct - must copy from symbol table
6451  */
copy_wires(struct symtab_t * sytp)6452 static void copy_wires(struct symtab_t *sytp)
6453 {
6454  register int32 syi;
6455  struct sy_t **syms;
6456  struct sy_t *syp;
6457  struct net_t *onp, *nnp;
6458 
6459  for (syms = sytp->stsyms, syi = 0; syi < (int32) sytp->numsyms; syi++)
6460   {
6461    syp = syms[syi];
6462    if (syp->sytyp != SYM_N) continue;
6463    onp = syp->el.enp;
6464    /* do not copy parameters or specparams here */
6465    if (onp->n_isaparam) continue;
6466 
6467    /* must copy depending or original storage method */
6468    nnp = (struct net_t *) __my_malloc(sizeof(struct net_t));
6469    /* copy body */
6470    *nnp = *onp;
6471    /* allocate extra storage area */
6472    nnp->nu.ct = __alloc_arrncomp();
6473    /* copy ncomp body */
6474    *(nnp->nu.ct) = *(onp->nu.ct);
6475    /* DBG remove --- */
6476    if (nnp->nrngrep != NX_CT) __misc_terr(__FILE__, __LINE__);
6477    /* --- */
6478    if (nnp->n_isavec)
6479     {
6480      nnp->nu.ct->nx1 = __copy_expr(onp->nu.ct->nx1);
6481      nnp->nu.ct->nx2 = __copy_expr(onp->nu.ct->nx2);
6482     }
6483    else nnp->nu.ct->nx1 = nnp->nu.ct->nx2 = NULL;
6484 
6485    if (nnp->n_isarr)
6486     {
6487      nnp->nu.ct->ax1 = __copy_expr(onp->nu.ct->ax1);
6488      /* notice this copies initial value expr. for params */
6489      nnp->nu.ct->ax2 = __copy_expr(onp->nu.ct->ax2);
6490     }
6491    else nnp->nu.ct->ax1 = nnp->nu.ct->ax2 = NULL;
6492 
6493    if (onp->nattrs != NULL) nnp->nattrs = copy_attrs(onp->nattrs);
6494    else nnp->nattrs = NULL;
6495 
6496    nnp->nu.ct->n_dels_u.pdels = __copy_dellst(onp->nu.ct->n_dels_u.pdels);
6497 
6498    /* when symbol table copied old spltsy field pointed to new */
6499    /* copying symbol table copies symbols */
6500    syp = (struct sy_t *) onp->nsym->spltsy;
6501    nnp->nsym = syp;
6502    syp->el.enp = nnp;
6503    /* mutual links now separated */
6504    /* must not change splt sym since still needed by param type regs */
6505   }
6506 }
6507 
6508 /*
6509  * copy params (storage same as nets and also by here will be in tab form)
6510  * for both module and task/func params
6511  *
6512  * also links in nsym and symbol table el.enp
6513  * know decl. symbol tables for these
6514  *
6515  * value of param as parm_var net is assumed to be in pxp format
6516  * and expr. copied.
6517  */
copy_params(struct net_t * onptab,int32 oprmnum,int32 pclass)6518 static struct net_t *copy_params(struct net_t *onptab, int32 oprmnum,
6519  int32 pclass)
6520 {
6521  register int32 ni;
6522  int32 nbytes, awid;
6523  struct sy_t *syp;
6524  struct net_t *nnp, *onp, *nnptab;
6525 
6526  if (oprmnum == 0) return(NULL);
6527  nbytes = oprmnum*sizeof(struct net_t);
6528  /* allocate and copy new parameter (really nets) as a block */
6529  nnptab = (struct net_t *) __my_malloc(nbytes);
6530  memcpy(nnptab, onptab, nbytes);
6531 
6532  /* need to also allocate and copy ncomp union field for each */
6533  for (ni = 0; ni < oprmnum; ni++)
6534   {
6535    nnp = &(nnptab[ni]);
6536    onp = &(onptab[ni]);
6537    /* DBG remove --- */
6538    if (pclass == MODULE)
6539     { if (!onp->n_isaparam) __misc_terr(__FILE__, __LINE__); }
6540    else if (pclass == SPECIFY)
6541     { if (!onp->n_isaparam) __misc_terr(__FILE__, __LINE__); }
6542    else __case_terr(__FILE__, __LINE__);
6543    /* --- */
6544 
6545    /* get area from special block */
6546    nnp->nu.ct = __alloc_arrncomp();
6547 
6548    *(nnp->nu.ct) = *(onp->nu.ct);
6549    if (nnp->n_isavec)
6550     {
6551      nnp->nu.ct->nx1 = __copy_expr(onp->nu.ct->nx1);
6552      nnp->nu.ct->nx2 = __copy_expr(onp->nu.ct->nx2);
6553     }
6554    else nnp->nu.ct->nx1 = nnp->nu.ct->nx2 = NULL;
6555 
6556    /* know rhs will still be one expr. (SR_PNUM) here pointed to by nva */
6557    /* DBG remove --- */
6558    if (onp->srep != SR_PNUM) __misc_terr(__FILE__, __LINE__);
6559    /* --- */
6560 
6561    /* must also handle parameter arrays */
6562    if (onp->n_isarr)
6563     {
6564      nnp->nu.ct->ax1 = __copy_expr(onp->nu.ct->ax1);
6565      nnp->nu.ct->ax2 = __copy_expr(onp->nu.ct->ax2);
6566      awid = __get_arrwide(onp);
6567      /* arrays of parameters never packed always take at least 8 bytes */
6568      nbytes = 2*WRDBYTES*awid*wlen_(onp->nwid);
6569     }
6570    else
6571     {
6572      nnp->nu.ct->ax1 = nnp->nu.ct->ax2 = NULL;
6573      nbytes = 2*WRDBYTES*wlen_(onp->nwid);
6574     }
6575    /* alloc and copy value */
6576    nnp->nva.wp = (word32 *) __my_malloc(nbytes);
6577    memcpy(nnp->nva.wp, onp->nva.wp, nbytes);
6578 
6579    /* and copy source expr for params kept in n_dels_u field */
6580    /* DBG remove --- */
6581    if (onp->nu.ct->parm_srep != SR_PXPR) __misc_terr(__FILE__, __LINE__);
6582    /* --- */
6583    nnp->nu.ct->n_dels_u.d1x = __copy_expr(onp->nu.ct->n_dels_u.d1x);
6584 
6585    /* when symbol table copied old splt sym field pointed to new */
6586    /* copying symbol table copies symbols */
6587    syp = (struct sy_t *) onp->nsym->spltsy;
6588    nnp->nsym = syp;
6589    syp->el.enp = nnp;
6590    /* mutual links now separated */
6591    /* must not change splt sym since still needed by param type regs */
6592   }
6593  return(nnptab);
6594 }
6595 
6596 /*
6597  * copy downward relative only defparams - know checking completed
6598  */
copy_defparams(void)6599 static void copy_defparams(void)
6600 {
6601  register struct dfparam_t *odfpp, *ndfpp;
6602  register int32 dfi;
6603  struct dfparam_t *ndfphdr, *ndfpend;
6604 
6605  ndfphdr = ndfpend = NULL;
6606  for (odfpp = __oinst_mod->mdfps; odfpp != NULL; odfpp = odfpp->dfpnxt)
6607   {
6608    /* for rooted defparam in copied has no effect */
6609    /* if copying during splitting from defparams, down relative gone */
6610    if (odfpp->dfp_rooted) continue;
6611 
6612    /* always copy local defparams */
6613    ndfpp = (struct dfparam_t *) __my_malloc(sizeof(struct dfparam_t));
6614    *ndfpp = *odfpp;
6615    ndfpp->dfpxlhs = __copy_expr(odfpp->dfpxlhs);
6616    ndfpp->dfpxrhs = __copy_expr(odfpp->dfpxrhs);
6617    ndfpp->in_mdp = __inst_mod;
6618    ndfpp->gdfpnam = __pv_stralloc(odfpp->gdfpnam);
6619    /* since resetting do not need this code --
6620    if (odfpp->dfptskp != NULL)
6621     ndfpp->dfptskp = odfpp->dfptskp->tsksyp->spltsy->el.etskp;
6622    --- */
6623    ndfpp->dfpnxt = NULL;
6624 
6625    /* must look up target symbols for defparam at end, no copy here */
6626    ndfpp->dfpiis = (int32 *) __my_malloc((ndfpp->last_dfpi + 1)*sizeof(int32));
6627    /* SJM 06/03/05 - index was wrongly not starting at 0 */
6628    for (dfi = 0; dfi < ndfpp->last_dfpi + 1; dfi++)
6629     ndfpp->dfpiis[dfi] = odfpp->dfpiis[dfi];
6630 
6631    if (ndfphdr == NULL) ndfphdr = ndfpp;
6632    else ndfpend->dfpnxt = ndfpp;
6633    ndfpend = ndfpp;
6634   }
6635  __inst_mod->mdfps = ndfphdr;
6636 }
6637 
6638 /*
6639  * copy Verilog 2000 attributes
6640  */
copy_attrs(struct attr_t * oattrp)6641 static struct attr_t *copy_attrs(struct attr_t *oattrp)
6642 {
6643  register struct attr_t *nattrp, *nattr_hd, *last_nattrp;
6644 
6645  last_nattrp = NULL;
6646  nattr_hd = NULL;
6647  for (; oattrp != NULL; oattrp = oattrp->attrnxt)
6648   {
6649    nattrp = (struct attr_t *) __my_malloc(sizeof(struct attr_t));
6650    *nattrp = *oattrp;
6651    nattrp->attrnam = __pv_stralloc(oattrp->attrnam);
6652    if (oattrp->attr_xp != NULL)
6653     nattrp->attr_xp = __copy_expr(oattrp->attr_xp);
6654    nattrp->attrnxt = NULL;
6655    if (last_nattrp == NULL) nattr_hd = nattrp;
6656    else last_nattrp->attrnxt = nattrp;
6657    last_nattrp = nattrp;
6658   }
6659  return(nattr_hd);
6660 }
6661 
6662 /*
6663  * routine for copy module variable initializ assign var init records
6664  *
6665  * notice this must be copied after copying wires and parameters
6666  */
copy_varinits(struct varinitlst_t * oinitp)6667 static struct varinitlst_t *copy_varinits(struct varinitlst_t *oinitp)
6668 {
6669  register struct varinitlst_t *ninitp, *nvarinit_hd, *last_initp;
6670 
6671  last_initp = NULL;
6672  nvarinit_hd = NULL;
6673  ninitp = NULL;
6674  for (; oinitp != NULL; oinitp = oinitp->varinitnxt)
6675   {
6676    ninitp = (struct varinitlst_t *) __my_malloc(sizeof(struct varinitlst_t));
6677    *ninitp = *oinitp;
6678    ninitp->init_syp = oinitp->init_syp->spltsy;
6679    ninitp->init_xp = __copy_expr(oinitp->init_xp);
6680    ninitp->varinitnxt = NULL;
6681    if (last_initp == NULL) nvarinit_hd = ninitp;
6682    else last_initp->varinitnxt = ninitp;
6683    last_initp = ninitp;
6684   }
6685  return(ninitp);
6686 }
6687 
6688 /*
6689  * routine for copying module instances
6690  */
copy_insts(void)6691 static void copy_insts(void)
6692 {
6693  register int32 ii, ii2;
6694  int32 giawid;
6695  struct inst_t *oip, *nip;
6696  struct giarr_t *giap;
6697 
6698  /* if no instances - original copy set fields to nil and 0 */
6699  if (__oinst_mod->minum == 0) return;
6700 
6701  __inst_mod->minsts = (struct inst_t *)
6702   __my_malloc(__oinst_mod->minum*sizeof(struct inst_t));
6703 
6704  for (ii = 0; ii < __oinst_mod->minum;)
6705   {
6706    oip = &(__oinst_mod->minsts[ii]);
6707    nip = &(__inst_mod->minsts[ii]);
6708    /* notice for earliest copying miarr always nil */
6709    /* giap here is old since new does not yet exist */
6710    if (__oinst_mod->miarr != NULL && (giap = __oinst_mod->miarr[ii]) != NULL)
6711     {
6712      copy_1inst(nip, oip, TRUE);
6713      giawid = __get_giarr_wide(giap);
6714      for (ii2 = ii + 1; ii2 < ii + giawid; ii2++)
6715       {
6716        oip = &(__oinst_mod->minsts[ii2]);
6717        nip = &(__inst_mod->minsts[ii2]);
6718        copy_1inst(nip, oip, FALSE);
6719        nip->ipins = giap->giapins;
6720       }
6721      ii = ii2;
6722     }
6723    else { copy_1inst(nip, oip, TRUE); ii++; }
6724   }
6725 }
6726 
6727 /*
6728  * copy 1 instance
6729  */
copy_1inst(struct inst_t * nip,struct inst_t * oip,int32 nd_cp_ipins)6730 static void copy_1inst(struct inst_t *nip, struct inst_t *oip, int32 nd_cp_ipins)
6731 {
6732  struct sy_t *syp;
6733 
6734  /* this copies instance must split for later if needed (>1 unsplit) */
6735  *nip = *oip;
6736  /* when symbol copied old splt sym field pointed to new */
6737  syp = (struct sy_t *) oip->isym->spltsy;
6738  if (syp == NULL) __misc_terr(__FILE__, __LINE__);
6739  nip->isym = syp;
6740  syp->el.eip = nip;
6741  /* mutual links now separated */
6742  /* notice module symbol (in modsyms) the same until splitting completed */
6743  nip->ipxprtab = copy_pndxtab(oip);
6744 
6745  if (oip->iattrs != NULL) nip->iattrs = copy_attrs(oip->iattrs);
6746  else nip->iattrs = NULL;
6747 
6748  if (nd_cp_ipins) copy_iports(nip, oip); else nip->ipins = NULL;
6749 }
6750 
6751 /*
6752  * copy pound param expression table
6753  *
6754  * if pound param expr. table exists it has loc (maybe nil) for every mod param
6755  */
copy_pndxtab(struct inst_t * oip)6756 static struct expr_t **copy_pndxtab(struct inst_t *oip)
6757 {
6758  register int32 pi;
6759  struct expr_t **nnpxtab, **onpxtab;
6760  struct mod_t *imdp;
6761 
6762  if ((onpxtab = oip->ipxprtab) == NULL) return(NULL);
6763 
6764  imdp = oip->imsym->el.emdp;
6765  nnpxtab = (struct expr_t **)
6766   __my_malloc(imdp->mprmnum*sizeof(struct expr_t *));
6767  for (pi = 0; pi < imdp->mprmnum; pi++)
6768   {
6769    if (onpxtab[pi] == NULL) nnpxtab[pi] = NULL;
6770    else nnpxtab[pi] = __copy_expr(onpxtab[pi]);
6771   }
6772  return(nnpxtab);
6773 }
6774 
6775 /*
6776  * copy module instance ports
6777  */
copy_iports(struct inst_t * nip,struct inst_t * oip)6778 static void copy_iports(struct inst_t *nip, struct inst_t *oip)
6779 {
6780  register int32 pi, pnum;
6781 
6782  if ((pnum = oip->imsym->el.emdp->mpnum) != 0)
6783   {
6784    nip->ipins = (struct expr_t **) __my_malloc(pnum*sizeof(struct expr_t *));
6785    for (pi = 0; pi < pnum; pi++) nip->ipins[pi] = __copy_expr(oip->ipins[pi]);
6786   }
6787  else nip->ipins = NULL;
6788 }
6789 
6790 /*
6791  * copy module array of instances (miarr)
6792  *
6793  * this is copy of index into individual insts in normal insts tab
6794  */
copy_miarr(void)6795 static void copy_miarr(void)
6796 {
6797  register int32 ii, ii2;
6798  int32 giawid;
6799  struct giarr_t *ogiap, *ngiap;
6800  struct sy_t *syp;
6801 
6802  /* if no arrays of instances - original copy set fields to nil and 0 */
6803  if (__oinst_mod->miarr == NULL) return;
6804 
6805  /* this is pointer to elements not array of elements */
6806  __inst_mod->miarr = (struct giarr_t **)
6807   __my_malloc(__oinst_mod->minum*sizeof(struct giarr_t *));
6808 
6809  for (ii = 0; ii < __oinst_mod->minum;)
6810   {
6811    ogiap = __oinst_mod->miarr[ii];
6812    if (ogiap == NULL) { __inst_mod->miarr[ii] = NULL; continue; }
6813 
6814    ngiap = (struct giarr_t *) __my_malloc(sizeof(struct giarr_t));
6815    *ngiap = *ogiap;
6816    /* new needs to point to right (its) module's ipins list */
6817    ngiap->giapins = __inst_mod->minsts[ii].ipins;
6818 
6819    syp = (struct sy_t *) ogiap->gia_base_syp->spltsy;
6820    if (syp == NULL) __misc_terr(__FILE__, __LINE__);
6821    ngiap->gia_base_syp = syp;
6822    /* points back to first (base) */
6823    /* LOOKATME - is this needed */
6824    syp->el.eip = &(__inst_mod->minsts[ii]);
6825    syp->sy_giabase = TRUE;
6826 
6827    /* only other fields that need copying is expression */
6828    ngiap->giax1 = __copy_expr(ogiap->giax1);
6829    ngiap->giax2 = __copy_expr(ogiap->giax2);
6830    __inst_mod->miarr[ii] = ngiap;
6831    /* LOOKATME - for new generate maybe need to change this */
6832    /* notice all giap's for expanded instances point to same master */
6833    giawid = __get_giarr_wide(ogiap);
6834    for (ii2 = ii + 1; ii2 < ii + giawid; ii2++) __inst_mod->miarr[ii2] = ngiap;
6835    ii = ii2;
6836   }
6837 }
6838 
6839 /*
6840  * routine for copying module gates
6841  */
copy_gates(void)6842 static void copy_gates(void)
6843 {
6844  register int32 gi, gi2;
6845  int32 giawid;
6846  struct gate_t *ogp, *ngp;
6847  struct giarr_t *giap;
6848 
6849  /* inst mod is new */
6850  if (__oinst_mod->mgnum != 0)
6851   __inst_mod->mgates = (struct gate_t *)
6852    __my_malloc(__oinst_mod->mgnum*sizeof(struct gate_t));
6853 
6854  for (gi = 0; gi < __oinst_mod->mgnum;)
6855   {
6856    ogp = &(__oinst_mod->mgates[gi]);
6857    ngp = &(__inst_mod->mgates[gi]);
6858 
6859    /* notice for earliest copying miarr always nil */
6860    /* giap here is old since new does not yet exist */
6861    if (__oinst_mod->mgarr != NULL && (giap = __oinst_mod->mgarr[gi]) != NULL)
6862     {
6863      copy_1gate(ngp, ogp, TRUE);
6864      giawid = __get_giarr_wide(giap);
6865      for (gi2 = gi + 1; gi2 < gi + giawid; gi2++)
6866       {
6867        ogp = &(__oinst_mod->mgates[gi2]);
6868        ngp = &(__inst_mod->mgates[gi2]);
6869        copy_1gate(ngp, ogp, FALSE);
6870        ngp->gpins = giap->giapins;
6871       }
6872      gi = gi2;
6873     }
6874    else { copy_1gate(ngp, ogp, TRUE); gi++; }
6875   }
6876 }
6877 
6878 /*
6879  * copy 1 gate (passes already allocated address in gate tables)
6880  */
copy_1gate(struct gate_t * ngp,struct gate_t * ogp,int32 nd_cp_gpins)6881 static void copy_1gate(struct gate_t *ngp, struct gate_t *ogp, int32 nd_cp_gpins)
6882 {
6883  register int32 pi;
6884  int32 pnum;
6885  struct sy_t *syp;
6886 
6887  pnum = ogp->gpnum;
6888  /* copy everything but port connection expressions */
6889  *ngp = *ogp;
6890 
6891  /* when symbol copied old splt sym field pointed to new */
6892  syp = (struct sy_t *) ogp->gsym->spltsy;
6893  ngp->gsym = syp;
6894  syp->el.egp = ngp;
6895  /* mutual links now separated */
6896  /* notice module symbol (in modsyms) the same until splitting completed */
6897 
6898  /* copy output that is still expr.  - gets changed to wire later */
6899  ngp->g_du.pdels = __copy_dellst(ogp->g_du.pdels);
6900 
6901  if (ogp->gattrs != NULL) ngp->gattrs = copy_attrs(ogp->gattrs);
6902  else ngp->gattrs = NULL;
6903 
6904  ngp->gpins = (struct expr_t **) __my_malloc(pnum*sizeof(struct expr_t *));
6905  if (nd_cp_gpins)
6906   {
6907    /* copy the input port expressions */
6908    for (pi = 0; pi < pnum; pi++)
6909     ngp->gpins[pi] = __copy_expr(ogp->gpins[pi]);
6910   }
6911  else ngp->gpins = NULL;
6912 }
6913 
6914 /*
6915  * copy module array of gates (mgarr)
6916  */
copy_mgarr(void)6917 static void copy_mgarr(void)
6918 {
6919  register int32 gi, gi2;
6920  int32 giawid;
6921  struct giarr_t *ogiap, *ngiap;
6922  struct sy_t *syp;
6923 
6924  /* if no arrays of instances - original copy set fields to nil and 0 */
6925  if (__oinst_mod->mgarr == NULL) return;
6926 
6927  /* this is pointer to elements not array of elements */
6928  __inst_mod->mgarr = (struct giarr_t **)
6929   __my_malloc(__oinst_mod->mgnum*sizeof(struct giarr_t *));
6930 
6931  for (gi = 0; gi < __oinst_mod->mgnum; gi++)
6932   {
6933    ogiap = __oinst_mod->mgarr[gi];
6934    if (ogiap == NULL) { __inst_mod->mgarr[gi] = NULL; continue; }
6935 
6936    ngiap = (struct giarr_t *) __my_malloc(sizeof(struct giarr_t));
6937    *ngiap = *ogiap;
6938 
6939    /* new needs to point to right (its) module's ipins list */
6940    ngiap->giapins = __inst_mod->mgates[gi].gpins;
6941 
6942    syp = (struct sy_t *) ogiap->gia_base_syp->spltsy;
6943    if (syp == NULL) __misc_terr(__FILE__, __LINE__);
6944    ngiap->gia_base_syp = syp;
6945    /* points back to first (base) */
6946    /* LOOKATME - is this needed */
6947    syp->el.egp = &(__inst_mod->mgates[gi]);
6948    syp->sy_giabase = TRUE;
6949 
6950    /* only other fields that need copying is expression */
6951    ngiap->giax1 = __copy_expr(ogiap->giax1);
6952    ngiap->giax2 = __copy_expr(ogiap->giax2);
6953    __inst_mod->mgarr[gi] = ngiap;
6954 
6955    /* LOOKATME - for new generate maybe need to change this */
6956    /* notice all giap's for expanded instances point to same master */
6957    giawid = __get_giarr_wide(ogiap);
6958    for (gi2 = gi + 1; gi2 < gi + giawid; gi2++)
6959      __inst_mod->mgarr[gi2] = ngiap;
6960    /* AIV 06/08/06 - was skipping one because gi2 is + 1 */
6961    gi = gi2 - 1;
6962   }
6963 }
6964 
6965 /*
6966  * copy continuous assigns
6967  */
copy_contas(void)6968 static void copy_contas(void)
6969 {
6970  register struct conta_t *ocap;
6971  struct conta_t *ncap, *last_ncap;
6972  struct sy_t *syp;
6973 
6974  __inst_mod->mcas = NULL;
6975  last_ncap = NULL;
6976  for (ocap = __oinst_mod->mcas; ocap != NULL; ocap = ocap->pbcau.canxt)
6977   {
6978    ncap = (struct conta_t *) __my_malloc(sizeof(struct conta_t));
6979 
6980    /* when symbol copied old splt sym field pointed to new */
6981    *ncap = *ocap;
6982    syp = (struct sy_t *) ocap->casym->spltsy;
6983    ncap->casym = syp;
6984    syp->el.ecap = ncap;
6985 
6986    ncap->ca_du.pdels = __copy_dellst(ocap->ca_du.pdels);
6987    ncap->lhsx = __copy_expr(ocap->lhsx);
6988    ncap->rhsx = __copy_expr(ocap->rhsx);
6989    if (last_ncap == NULL) __inst_mod->mcas = ncap;
6990    else last_ncap->pbcau.canxt = ncap;
6991    last_ncap = ncap;
6992   }
6993  if (last_ncap != NULL) last_ncap->pbcau.canxt = NULL;
6994 }
6995 
6996 /*
6997  * copy all mod tasks
6998  */
copy_mdtasks(void)6999 static void copy_mdtasks(void)
7000 {
7001  register struct task_t *otskp, *ntskp;
7002  struct task_t *last_ntskp;
7003 
7004  last_ntskp = NULL;
7005  __inst_mod->mtasks = NULL;
7006  for (otskp = __oinst_mod->mtasks; otskp != NULL; otskp = otskp->tsknxt)
7007   {
7008    ntskp = (struct task_t *) __my_malloc(sizeof(struct task_t));
7009    *ntskp = *otskp;
7010    /* fill link from task to symbol table and symbol */
7011    ntskp->tsksymtab = (struct symtab_t *) otskp->tsksymtab->n_head;
7012    /* notice must link both directions */
7013    ntskp->tsksyp = (struct sy_t *) otskp->tsksyp->spltsy;
7014    ntskp->tsksyp->el.etskp = ntskp;
7015 
7016    /* for tasks everything is a reg so must copy first */
7017    copy_wires(otskp->tsksymtab);
7018 
7019    /* for named blocks, connect from task to named block filled when named */
7020    /* block statement filled (st_namblkin field) */
7021 
7022    /* copy task pins */
7023    ntskp->tskpins = copy_tskargs(otskp);
7024 
7025    /* copy task params */
7026    ntskp->tsk_prms = copy_params(otskp->tsk_prms, otskp->tprmnum, MODULE);
7027 
7028    /* AIV 09/27/06 - need to copy the local params as well */
7029    ntskp->tsk_locprms = copy_params(otskp->tsk_locprms, otskp->tlocprmnum,
7030     MODULE);
7031 
7032    /* copy the 1 statement */
7033    ntskp->tskst = copy_lstofsts(otskp->tskst);
7034 
7035    if (last_ntskp == NULL) __inst_mod->mtasks = ntskp;
7036    else last_ntskp->tsknxt = ntskp;
7037    last_ntskp = ntskp;
7038   }
7039 }
7040 
7041 /*
7042  * copy task ports - only regs can be ports
7043  */
copy_tskargs(struct task_t * otskp)7044 static struct task_pin_t *copy_tskargs(struct task_t *otskp)
7045 {
7046  register struct task_pin_t *otpp;
7047  struct task_pin_t *last_ntpp, *ntpp, *ntpp_hdr;
7048 
7049  last_ntpp = NULL;
7050  ntpp_hdr = NULL;
7051  for (otpp = otskp->tskpins; otpp != NULL; otpp = otpp->tpnxt)
7052   {
7053    ntpp = (struct task_pin_t *) __my_malloc(sizeof(struct task_pin_t));
7054    /* this copies trtyp field */
7055    *ntpp = *otpp;
7056    ntpp->tpsy = (struct sy_t *) otpp->tpsy->spltsy;
7057    ntpp->tpnxt = NULL;
7058    if (last_ntpp == NULL) ntpp_hdr = ntpp; else last_ntpp->tpnxt = ntpp;
7059    last_ntpp = ntpp;
7060   }
7061  return(ntpp_hdr);
7062 }
7063 
7064 /*
7065  * copy a statement entry
7066  */
copy_stmt(struct st_t * ostp)7067 static struct st_t *copy_stmt(struct st_t *ostp)
7068 {
7069  struct st_t *nstp;
7070  struct sy_t *nsyp;
7071 
7072  if (ostp == NULL) return(NULL);
7073 
7074  nstp = (struct st_t *) __my_malloc(sizeof(struct st_t));
7075  *nstp = *ostp;
7076  nstp->stnxt = NULL;
7077 
7078  switch ((byte) ostp->stmttyp) {
7079   /* null just has type value and NULL pointer (i.e. ; by itself) */
7080   case S_NULL: case S_STNONE: break;
7081   case S_PROCA: case S_FORASSGN: case S_RHSDEPROCA: case S_NBPROCA:
7082    nstp->st.spra.lhsx = __copy_expr(ostp->st.spra.lhsx);
7083    nstp->st.spra.rhsx = __copy_expr(ostp->st.spra.rhsx);
7084    break;
7085   case S_IF:
7086    nstp->st.sif.condx = __copy_expr(ostp->st.sif.condx);
7087    nstp->st.sif.thenst = copy_lstofsts(ostp->st.sif.thenst);
7088    nstp->st.sif.elsest = copy_lstofsts(ostp->st.sif.elsest);
7089    break;
7090   case S_CASE:
7091    nstp->st.scs.castyp = ostp->st.scs.castyp;
7092    nstp->st.scs.maxselwid = ostp->st.scs.maxselwid;
7093    nstp->st.scs.csx = __copy_expr(ostp->st.scs.csx);
7094 
7095    /* this also copies default which is first (always present) */
7096    /* if case has no default, st field nil */
7097    nstp->st.scs.csitems = copy_csitemlst(ostp->st.scs.csitems);
7098    break;
7099   case S_REPEAT:
7100    nstp->st.srpt.repx = __copy_expr(ostp->st.srpt.repx);
7101    /* per inst. temporaries not allocated by here */
7102    nstp->st.srpt.reptemp = NULL;
7103    nstp->st.srpt.repst = copy_lstofsts(ostp->st.srpt.repst);
7104    break;
7105   case S_FOREVER:
7106   case S_WHILE:
7107    nstp->st.swh.lpx = __copy_expr(ostp->st.swh.lpx);
7108    nstp->st.swh.lpst = copy_lstofsts(ostp->st.swh.lpst);
7109    break;
7110   case S_WAIT:
7111    nstp->st.swait.lpx = __copy_expr(ostp->st.swait.lpx);
7112    nstp->st.swait.lpst = copy_lstofsts(ostp->st.swait.lpst);
7113    /* until prep, this dctp is just allocated unfilled version */
7114    nstp->st.swait.wait_dctp = __alloc_dctrl();
7115    *(nstp->st.swait.wait_dctp) = *(ostp->st.swait.wait_dctp);
7116    break;
7117   case S_FOR:
7118    {
7119     struct for_t *nfrp, *ofrp;
7120 
7121     nfrp = (struct for_t *) __my_malloc(sizeof(struct for_t));
7122     nstp->st.sfor = nfrp;
7123     ofrp = ostp->st.sfor;
7124     nfrp->forassgn = copy_stmt(ofrp->forassgn);
7125     nfrp->fortermx = __copy_expr(ofrp->fortermx);
7126     nfrp->forinc = copy_stmt(ofrp->forinc);
7127     nfrp->forbody = copy_lstofsts(ofrp->forbody);
7128    }
7129    break;
7130   case S_DELCTRL:
7131    {
7132     struct delctrl_t *ndcp, *odcp;
7133 
7134     ndcp = (struct delctrl_t *) __my_malloc(sizeof(struct delctrl_t));
7135     nstp->st.sdc = ndcp;
7136     odcp = ostp->st.sdc;
7137     ndcp->dctyp = odcp->dctyp;
7138     ndcp->dc_iact = odcp->dc_iact;
7139     /* SJM 08/02/02 - need to also explicitly copy new non blking flag */
7140     ndcp->dc_nblking = odcp->dc_nblking;
7141     /* SJM 08/17/04 - f2016 was failing because this was not set */
7142     ndcp->implicit_evxlst = odcp->implicit_evxlst;
7143     ndcp->dc_delrep = odcp->dc_delrep;
7144     ndcp->dc_du.pdels = __copy_dellst(odcp->dc_du.pdels);
7145     ndcp->repcntx = __copy_expr(odcp->repcntx);
7146 
7147     /* SJM 10/07/06 - repcnts not yet set - set in v prp2 */
7148     /* DBG remove --- */
7149     if (odcp->dce_repcnts != NULL) __misc_terr(__FILE__, __LINE__);
7150     /* --- */
7151 
7152     ndcp->dce_repcnts = NULL;
7153     ndcp->dceschd_tevs = NULL;
7154     /* can be list because of #10 begin ... end */
7155     ndcp->actionst = copy_lstofsts(odcp->actionst);
7156    }
7157    break;
7158   case S_NAMBLK:
7159    {
7160     /* know task copied and old sy points to new - new el is new task */
7161     nsyp = (struct sy_t *) ostp->st.snbtsk->tsksyp->spltsy;
7162     nstp->st.snbtsk = nsyp->el.etskp;
7163     nsyp->el.etskp->st_namblkin = nstp;
7164    }
7165    break;
7166   case S_UNBLK:
7167    nstp->st.sbsts = copy_lstofsts(ostp->st.sbsts);
7168    break;
7169   case S_UNFJ:
7170    {
7171     register int32 fji;
7172     int32 num_fji;
7173     struct st_t *ofjstp;
7174 
7175     /* first count number of statements in fj */
7176     for (num_fji = 0;; num_fji++)
7177      { if (ostp->st.fj.fjstps[num_fji] == NULL) break; }
7178 
7179     nstp->st.fj.fjstps = (struct st_t **)
7180      __my_malloc((num_fji + 1)*sizeof(struct st_t *));
7181     nstp->st.fj.fjlabs = (int32 *) __my_malloc((num_fji + 1)*sizeof(int32));
7182 
7183     /* know fork-join will always have at least 1 statement (maybe null) */
7184     /* also if labeled it will be surrounded by named block */
7185     for (fji = 0;; fji++)
7186      {
7187       if ((ofjstp = ostp->st.fj.fjstps[fji]) == NULL) break;
7188       nstp->st.fj.fjstps[fji] = copy_lstofsts(ofjstp);
7189 
7190       /* code gen label unused here but still copy */
7191       nstp->st.fj.fjlabs[fji] = ostp->st.fj.fjlabs[fji];
7192      }
7193     nstp->st.fj.fjstps[num_fji] = NULL;
7194     nstp->st.fj.fjlabs[num_fji] = -1;
7195    }
7196    break;
7197   case S_TSKCALL:
7198    /* find new task through old to new symbol */
7199    /* for system tasks since points to itself gets same (right) sym */
7200    nstp->st.stkc.tsksyx = __copy_expr(ostp->st.stkc.tsksyx);
7201    nstp->st.stkc.targs = __copy_expr(ostp->st.stkc.targs);
7202 
7203    /* field for pli tasks filled during prep */
7204    nstp->st.stkc.tkcaux.trec = NULL;
7205    break;
7206   case S_QCONTA:
7207    {
7208     /* SJM 06/23/02 - now aneed more room in qcont stmt specific area */
7209     struct qconta_t *nqcafs;
7210 
7211     nqcafs = (struct qconta_t *) __my_malloc(sizeof(struct qconta_t));
7212 
7213     nstp->st.sqca = nqcafs;
7214     nstp->st.sqca->qcatyp = ostp->st.sqca->qcatyp;
7215     nstp->st.sqca->regform = ostp->st.sqca->regform;
7216     nstp->st.sqca->qclhsx = __copy_expr(ostp->st.sqca->qclhsx);
7217     nstp->st.sqca->qcrhsx = __copy_expr(ostp->st.sqca->qcrhsx);
7218     /* lst of dce lists field nil until near end of prep */
7219     nstp->st.sqca->rhs_qcdlstlst = NULL;
7220    }
7221    break;
7222   case S_QCONTDEA:
7223    nstp->st.sqcdea.qcdatyp = ostp->st.sqcdea.qcdatyp;
7224    nstp->st.sqcdea.regform = ostp->st.sqcdea.regform;
7225    nstp->st.sqcdea.qcdalhs = __copy_expr(ostp->st.sqcdea.qcdalhs);
7226    break;
7227   case S_CAUSE:
7228    /* must copy expr. even though know just event name */
7229    nstp->st.scausx = __copy_expr(ostp->st.scausx);
7230    break;
7231   case S_DSABLE:
7232    nstp->st.sdsable.dsablx = __copy_expr(ostp->st.sdsable.dsablx);
7233    nstp->st.sdsable.func_nxtstp = NULL;
7234    break;
7235   /* name resolving statement type no. */
7236   default: __case_terr(__FILE__, __LINE__);
7237  }
7238  return(nstp);
7239 }
7240 
7241 /*
7242  * copy a statement list (linked list of statements)
7243  */
copy_lstofsts(register struct st_t * ostp)7244 static struct st_t *copy_lstofsts(register struct st_t *ostp)
7245 {
7246  struct st_t *nstp_hdr, *nstp, *last_nstp;
7247 
7248  nstp_hdr = NULL;
7249  for (last_nstp = NULL; ostp != NULL; ostp = ostp->stnxt)
7250   {
7251    nstp = copy_stmt(ostp);
7252    if (last_nstp == NULL) nstp_hdr = nstp; else last_nstp->stnxt = nstp;
7253    nstp->stnxt = NULL;
7254    last_nstp = nstp;
7255   }
7256  return(nstp_hdr);
7257 }
7258 
7259 /*
7260  * copy a list of ialst blocks
7261  */
copy_ialst(register struct ialst_t * oialp)7262 static struct ialst_t *copy_ialst(register struct ialst_t *oialp)
7263 {
7264  struct ialst_t *nialp, *last_nialp, *nialst_hdr;
7265 
7266  nialst_hdr = NULL;
7267  for (last_nialp = NULL; oialp != NULL; oialp = oialp->ialnxt)
7268   {
7269    nialp = (struct ialst_t *) __my_malloc(sizeof(struct ialst_t));
7270    *nialp = *oialp;
7271    /* notice here initial/always exactly 1 statement, for always 2nd loop */
7272    /* back added during prep. */
7273    nialp->iastp = copy_lstofsts(oialp->iastp);
7274    nialp->ialnxt = NULL;
7275 
7276    if (last_nialp == NULL) nialst_hdr = nialp;
7277    else last_nialp->ialnxt = nialp;
7278    last_nialp = nialp;
7279   }
7280  return(nialst_hdr);
7281 }
7282 
7283 /*
7284  * copy the case item list
7285  * notice in common case of no default, pass nil - returns nil
7286  *
7287  * this copies default which is first too
7288  */
copy_csitemlst(register struct csitem_t * ocsip)7289 static struct csitem_t *copy_csitemlst( register struct csitem_t *ocsip)
7290 {
7291  struct csitem_t *ncsip, *ncsip_hdr, *last_ncsip;
7292 
7293  ncsip_hdr = NULL;
7294  for (last_ncsip = NULL; ocsip != NULL; ocsip = ocsip->csinxt)
7295   {
7296    ncsip = __alloc_csitem();
7297    if (last_ncsip == NULL) ncsip_hdr = ncsip; else last_ncsip->csinxt = ncsip;
7298    ncsip->csixlst = copy_xprlst(ocsip->csixlst);
7299    if (ocsip->csist == NULL) ncsip->csist = NULL;
7300    else ncsip->csist = copy_lstofsts(ocsip->csist);
7301    ncsip->csinxt = NULL;
7302    last_ncsip = ncsip;
7303   }
7304  return(ncsip_hdr);
7305 }
7306 
7307 /*
7308  * copy an expression list
7309  */
copy_xprlst(struct exprlst_t * oxplp)7310 static struct exprlst_t *copy_xprlst(struct exprlst_t *oxplp)
7311 {
7312  register struct exprlst_t *xplp;
7313  struct exprlst_t *nxplp_hdr, *nxplp, *last_nxplp;
7314 
7315  nxplp_hdr = NULL;
7316  for (last_nxplp = NULL, xplp = oxplp; xplp != NULL; xplp = xplp->xpnxt)
7317   {
7318    nxplp = __alloc_xprlst();
7319    if (last_nxplp == NULL) nxplp_hdr = nxplp; else last_nxplp->xpnxt = nxplp;
7320    nxplp->xp = __copy_expr(xplp->xp);
7321    last_nxplp = nxplp;
7322   }
7323  return(nxplp_hdr);
7324 }
7325 
7326 
7327 /*
7328  * copy an expression
7329  * this must deal with ID and symbol and globals (or need 2nd vers.)
7330  * update expression nodes to point to new modules symbols not old
7331  * if needed, caller must free src
7332  *
7333  */
__copy_expr(struct expr_t * src)7334 extern struct expr_t *__copy_expr(struct expr_t *src)
7335 {
7336  struct expr_t *dst;
7337  struct sy_t *syp;
7338 
7339  /* loops can have null expr. slots */
7340  if (src == NULL) return(NULL);
7341 
7342  dst = __alloc_newxnd();
7343  /* think long constant values can be shared but for now copying */
7344  /* copy of number node does node body including type copy */
7345  switch ((byte) src->optyp) {
7346   case NUMBER: case REALNUM:
7347    /* for non IS form constants can share (use same pointer) */
7348    *dst = *src;
7349    break;
7350   case ISNUMBER: case ISREALNUM:
7351    *dst = *src;
7352    /* 2 cases - if splitting - IS forms impossible else can't share con tab */
7353    if (__splitting)
7354     {
7355      __misc_terr(__FILE__, __LINE__);
7356     }
7357    break;
7358   case ID:
7359    /* must point new modules symbol - nothing points back */
7360    *dst = *src;
7361    /* if not splitting a module, copy has same symbol */
7362    if (__splitting)
7363     {
7364      syp = src->lu.sy;
7365      /* for system tasks/functions copied symbol is same as original */
7366      if (syp->sytyp != SYM_STSK && syp->sytyp != SYM_SF
7367       && syp->synam[0] != '$')
7368       dst->lu.sy = (struct sy_t *) syp->spltsy;
7369     }
7370    break;
7371   case XMRID:
7372    /* LOOKATME - copying pointers to make sure no shared storage */
7373    /* but since both read only maybe do not need to */
7374    *dst = *src;
7375    /* DBG remove ---*/
7376    if (src->ru.qnchp == NULL) __misc_terr(__FILE__, __LINE__);
7377    /* --- */
7378    dst->ru.qnchp = __pv_stralloc(src->ru.qnchp);
7379    break;
7380   case GLBREF:
7381    /* need to copy only top level expr because global already copied */
7382    /* LOOKATME - if not splitting gref point to original not copied gxndp */
7383    /* since not really copying gref think this must work - i.e. not using */
7384    *dst = *src;
7385    /* know symbol points to old gref entry - this sets new copied gref */
7386    /* and expr. cross linking */
7387    if (__splitting)
7388     {
7389      struct gref_t *dgrp, *sgrp;
7390 
7391      /* trick is that src gref field points to dst gref */
7392      sgrp = src->ru.grp;
7393      /* SJM 06/03/05 - when copying checked defparam, grp gone */
7394      /* happens when defparam definition in mode split from pound param */
7395      if (sgrp == NULL) dst->ru.grp = NULL;
7396      else
7397       {
7398        /* destionation global reference saved */
7399        dgrp = sgrp->spltgrp;
7400        /* dest. gref points to new gref entry */
7401        dst->ru.grp = dgrp;
7402        /* also finally link dest. group entry expr. ID node ptr to new node */
7403        dgrp->gxndp = dst;
7404        /* do not need to set lu.sy since later global name resolution sets */
7405        /* to target in some other part of design */
7406       }
7407     }
7408    break;
7409   default:
7410    /* know this is a operator node */
7411    /* must copy all contents - need optyp, rest mostly recomputed */
7412    *dst = *src;
7413    if (src->lu.x != NULL) dst->lu.x = __copy_expr(src->lu.x);
7414    if (src->ru.x != NULL) dst->ru.x = __copy_expr(src->ru.x);
7415  }
7416  return(dst);
7417 }
7418 
7419 /*
7420  * copy an expressions - special version for xform and vpi
7421  * that does not count in size of expr table
7422  */
__sim_copy_expr(struct expr_t * src)7423 extern struct expr_t *__sim_copy_expr(struct expr_t *src)
7424 {
7425  int32 sav_stnum, sav_exprnum;
7426  struct expr_t *dst;
7427 
7428  sav_stnum = 0;
7429  sav_exprnum = 0;
7430  if (__inst_mod != NULL)
7431   {
7432    sav_stnum = __inst_mod->mstnum;
7433    sav_exprnum = __inst_mod->mexprnum;
7434   }
7435 
7436  dst = __copy_expr(src);
7437 
7438  if (__inst_mod != NULL)
7439   {
7440    __inst_mod->mstnum = sav_stnum;
7441    __inst_mod->mexprnum = sav_exprnum;
7442   }
7443  return(dst);
7444 }
7445 
7446 /*
7447  * copy modules' global list
7448  *
7449  * must copy grefs before copying any expression so can link new expr
7450  * to new global
7451  */
copy_mgrefs(void)7452 static void copy_mgrefs(void)
7453 {
7454  register int32 gri;
7455  register struct gref_t *ogrp, *ngrp;
7456  int32 num_grefs;
7457 
7458  if (__oinst_mod->mgrnum == 0) return;
7459 
7460  num_grefs = __oinst_mod->mgrnum;
7461  __inst_mod->mgrtab = (struct gref_t *)
7462   __my_malloc(num_grefs*sizeof(struct gref_t));
7463 
7464  ogrp = &(__oinst_mod->mgrtab[0]);
7465  ngrp = &(__inst_mod->mgrtab[0]);
7466  for (gri = 0; gri < __oinst_mod->mgrnum; gri++, ogrp++, ngrp++)
7467   {
7468    copy_1gref_flds(ngrp, ogrp);
7469   }
7470 }
7471 
7472 /*
7473  * copy 1 gref guts - operation depends on type (processing state) of gref
7474  * copies from 2nd ogrp to new ngrp
7475  *
7476  * notice copying done before xmr resolution - so only need to copy
7477  * things that determine where appears
7478  */
copy_1gref_flds(struct gref_t * ngrp,struct gref_t * ogrp)7479 static void copy_1gref_flds(struct gref_t *ngrp, struct gref_t *ogrp)
7480 {
7481  *ngrp = *ogrp;
7482  /* this will be set when, expr. copied */
7483  ngrp->gxndp = NULL;
7484  ngrp->grsytp = (struct symtab_t *) ogrp->grsytp->n_head;
7485  ngrp->gin_mdp = __inst_mod;
7486  /* need to copy global path because later folding inst/gate array selects */
7487  ngrp->glbref = __copy_expr(ogrp->glbref);
7488 
7489  /* this is needed so when expr. copied will point to gref in copied mod */
7490  ogrp->spltgrp = ngrp;
7491  /* no need to copy grcmps because all copying before resolution */
7492 }
7493 
7494 /*
7495  * copy specify section if old has specify
7496  */
copy_specify(void)7497 static void copy_specify(void)
7498 {
7499  struct spfy_t *ospfyp, *nspfyp;
7500 
7501  /* first allocate new module's specify section */
7502  ospfyp = __oinst_mod->mspfy;
7503  nspfyp = (struct spfy_t *) __my_malloc(sizeof(struct spfy_t));
7504  /* AIV 06/08/06 - need to do copy of old to new */
7505  *nspfyp = *ospfyp;
7506  __inst_mod->mspfy = nspfyp;
7507  /* if has symbol table for specparams copy */
7508  /* this will link old specparams to new */
7509  if (ospfyp->spfsyms != NULL) nspfyp->spfsyms = copy_1symtab(ospfyp->spfsyms);
7510  /* copy parameters */
7511  nspfyp->msprms = copy_params(ospfyp->msprms, ospfyp->sprmnum, SPECIFY);
7512  copy_spcpths(ospfyp, nspfyp);
7513  copy_timchks(ospfyp, nspfyp);
7514 }
7515 
7516 /*
7517  * copy list of specify paths (port to port delay paths)
7518  */
copy_spcpths(struct spfy_t * ospfyp,struct spfy_t * nspfyp)7519 static void copy_spcpths(struct spfy_t *ospfyp, struct spfy_t *nspfyp)
7520 {
7521  struct spcpth_t *npthp, *opthp, *last_npthp, *npthp_hdr;
7522  struct sy_t *syp;
7523 
7524  last_npthp = NULL;
7525  npthp_hdr = NULL;
7526  for (opthp = ospfyp->spcpths; opthp != NULL; opthp = opthp->spcpthnxt)
7527   {
7528    npthp = (struct spcpth_t *) __my_malloc(sizeof(struct spcpth_t));
7529    /* for path this copies most of fields (part of packed constants) */
7530    *npthp = *opthp;
7531    /* must link copied symbol */
7532    syp = (struct sy_t *) opthp->pthsym->spltsy;
7533    npthp->pthsym = syp;
7534    syp->el.epthp = npthp;
7535 
7536    /* copy the path input and and path output that is here a cast expr list */
7537    npthp->peins = (struct pathel_t *)
7538     copy_xprlst((struct exprlst_t *) opthp->peins);
7539    npthp->peouts = (struct pathel_t *)
7540     copy_xprlst((struct exprlst_t *) opthp->peouts);
7541 
7542    /* copy the optional conditional path fields */
7543    npthp->datasrcx = __copy_expr(opthp->datasrcx);
7544    npthp->pthcondx = __copy_expr(opthp->pthcondx);
7545 
7546    /* copy the delay list - always CMPLST and can be long (up to 12?) */
7547    npthp->pth_du.pdels = __copy_dellst(opthp->pth_du.pdels);
7548 
7549    /* finally, link on end */
7550    npthp->spcpthnxt = NULL;
7551    if (last_npthp == NULL) npthp_hdr = npthp;
7552    else last_npthp->spcpthnxt = npthp;
7553    last_npthp = npthp;
7554   }
7555  nspfyp->spcpths = npthp_hdr;
7556 }
7557 
7558 /*
7559  * copy timing checks
7560  */
copy_timchks(struct spfy_t * ospfyp,struct spfy_t * nspfyp)7561 static void copy_timchks(struct spfy_t *ospfyp, struct spfy_t *nspfyp)
7562 {
7563  struct tchk_t *ntcp, *otcp, *last_ntcp, *ntcp_hdr;
7564 
7565  last_ntcp = NULL;
7566  ntcp_hdr = NULL;
7567  for (otcp = ospfyp->tchks; otcp != NULL; otcp = otcp->tchknxt)
7568   {
7569    ntcp = copy1_tchk(otcp);
7570    /* finally, link on end */
7571    ntcp->tchknxt = NULL;
7572    if (last_ntcp == NULL) ntcp_hdr = ntcp; else last_ntcp->tchknxt = ntcp;
7573    last_ntcp = ntcp;
7574   }
7575  nspfyp->tchks = ntcp_hdr;
7576 }
7577 
7578 /*
7579  * copy 1 timing check
7580  * notice here hold half of setuphold not yet copied
7581  */
copy1_tchk(struct tchk_t * otcp)7582 static struct tchk_t *copy1_tchk(struct tchk_t *otcp)
7583 {
7584  struct tchk_t *ntcp;
7585  struct sy_t *syp;
7586 
7587  ntcp = (struct tchk_t *) __my_malloc(sizeof(struct tchk_t));
7588  /* this copies flags */
7589  *ntcp = *otcp;
7590  syp = (struct sy_t *) otcp->tcsym->spltsy;
7591  ntcp->tcsym = syp;
7592  syp->el.etcp = ntcp;
7593 
7594  if (otcp->startxp != NULL) ntcp->startxp = __copy_expr(otcp->startxp);
7595  if (otcp->startcondx != NULL)
7596   ntcp->startcondx = __copy_expr(otcp->startcondx);
7597  if (otcp->chkxp != NULL) ntcp->chkxp = __copy_expr(otcp->chkxp);
7598  if (otcp->chkcondx != NULL) ntcp->chkcondx = __copy_expr(otcp->chkcondx);
7599 
7600  /* know 1st delay limit always required - always CMPLST here */
7601  ntcp->tclim_du.pdels = __copy_dellst(otcp->tclim_du.pdels);
7602  if (otcp->tc_haslim2)
7603   ntcp->tclim2_du.pdels = __copy_dellst(otcp->tclim2_du.pdels);
7604  else ntcp->tclim2_du.pdels = NULL;
7605 
7606  /* at this point, if present, ntfy_np is a sy_t */
7607  if (otcp->ntfy_np == NULL) ntcp->ntfy_np = NULL;
7608  else
7609   {
7610    syp = (struct sy_t *) otcp->ntfy_np;
7611    /* old symbols always have splt sym link to new */
7612    syp = syp->spltsy;
7613    ntcp->ntfy_np = (struct net_t *) syp;
7614   }
7615  return(ntcp);
7616 }
7617 
7618 /*
7619  * ROUTINES TO BUILD AS IF FLATTENED INSTANCE TREE
7620  */
7621 
7622 /*
7623  * build a linked tree as if flattened instance structure
7624  * needed in simulation and for tracing xmrs
7625  * try to set fields at as high a place in tree as possible
7626  */
__bld_flat_itree(void)7627 extern void __bld_flat_itree(void)
7628 {
7629  register int32 ii;
7630 
7631  for (ii = 0; ii < __numtopm; ii++) bld2_flat_itree(__it_roots[ii]);
7632  /* DBG remove ---
7633  if (__debug_flg)
7634   { for (ii = 0; ii < __numtopm; ii++) __dmp_itree(__it_roots[ii]); }
7635  --- */
7636 }
7637 
7638 /*
7639  * non top level built itree for inst. of one module
7640  *
7641  * know up instance pointers point to allocated but not set itree nodes
7642  * for each inst. in module one up
7643  * try to make as breadth first as possible
7644  */
bld2_flat_itree(struct itree_t * new_itp)7645 static void bld2_flat_itree(struct itree_t *new_itp)
7646 {
7647  register int32 ii;
7648  struct inst_t *ip;
7649  struct itree_t *itp;
7650  struct mod_t *up_imdp, *imdp;
7651 
7652  up_imdp = new_itp->itip->imsym->el.emdp;
7653  /* if mod has no insts empty minsts ptr tab and empty up_itp ptr table */
7654  if (up_imdp->minum == 0) return;
7655 
7656  /* allocate pointer to contained itree instances */
7657  new_itp->in_its = (struct itree_t *)
7658   __my_malloc(up_imdp->minum*sizeof(struct itree_t));
7659 
7660  /* fill contained itree instance contents */
7661  for (ii = 0; ii < up_imdp->minum; ii++)
7662   {
7663    /* alloc sets inst_t value */
7664    itp = &(new_itp->in_its[ii]);
7665    __init_itree_node(itp);
7666    ip = &(up_imdp->minsts[ii]);
7667    imdp = ip->imsym->el.emdp;
7668    itp->itip = ip;
7669    itp->up_it = new_itp;
7670    /* assign instance number */
7671    itp->itinum = imdp->lastinum;
7672    imdp->lastinum += 1;
7673    /* DBG remove ---
7674    if (__debug_flg)
7675     {
7676      __dbg_msg("==> building flat itree for instance %s of type %s\n",
7677       ip->isym->synam, ip->imsym->synam);
7678     }
7679    --- */
7680   }
7681  /* finally down 1 level */
7682  for (ii = 0; ii < up_imdp->minum; ii++)
7683   bld2_flat_itree(&(new_itp->in_its[ii]));
7684 }
7685 
7686 /*
7687  * dump a instance tree
7688  */
__dmp_itree(struct itree_t * itp)7689 extern void __dmp_itree(struct itree_t *itp)
7690 {
7691  register int32 i;
7692 
7693  __dbg_msg("--- dumping instance tree ---.\n");
7694  /* dump top */
7695  do_dmp(itp, 0);
7696  for (i = 1;; i++) { if (!dmp_down_itree(itp, i, i)) return; }
7697 }
7698 
7699 /*
7700  * dump a down level of a tree
7701  */
dmp_down_itree(struct itree_t * itp,int32 lev,int32 more_down)7702 static int32 dmp_down_itree(struct itree_t *itp, int32 lev, int32 more_down)
7703 {
7704  register int32 i;
7705  int32 ofsnum, retval;
7706 
7707  if (more_down == 0) { do_dmp(itp, lev); return(TRUE); }
7708  if ((ofsnum = itp->itip->imsym->el.emdp->minum) == 0) return(FALSE);
7709  for (retval= FALSE, i = 0; i < ofsnum; i++)
7710   {
7711    if (dmp_down_itree(&(itp->in_its[i]), lev, more_down - 1))
7712     retval = TRUE;
7713   }
7714  return(retval);
7715 }
7716 
7717 /*
7718  * do actual dump for level of 1 itp at level lev
7719  */
do_dmp(struct itree_t * itp,int32 lev)7720 static void do_dmp(struct itree_t *itp, int32 lev)
7721 {
7722  int32 ofsnum;
7723  char *chp, s1[RECLEN];
7724 
7725  /* DBG remove --- */
7726  if (itp->itip == 0) __misc_terr(__FILE__, __LINE__);
7727  /* --- */
7728  if (itp->up_it == NULL) { strcpy(s1, "(top module)"); chp = s1; }
7729  else chp = itp->up_it->itip->isym->synam;
7730  ofsnum = itp->itip->imsym->el.emdp->minum;
7731  __dbg_msg("-- level %d: inst. %s(%s) itinum %d, up %s %d offspring\n",
7732   __dagmaxdist - lev, itp->itip->isym->synam, itp->itip->imsym->synam,
7733   itp->itinum, chp, ofsnum);
7734 }
7735 
7736 /*
7737  * free under root (top level) itree
7738  */
__free_flat_itree(void)7739 extern void __free_flat_itree(void)
7740 {
7741  register int32 ii;
7742  register struct mod_t *mdp;
7743 
7744  for (ii = 0; ii < __numtopm; ii++) free2_flat_itree(__it_roots[ii]);
7745 
7746  /* final step requires resetting last inum field in every module */
7747  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt) mdp->lastinum = 0;
7748 }
7749 
7750 /*
7751  * free itree in_its tables bottom up
7752  */
free2_flat_itree(struct itree_t * cur_itp)7753 static void free2_flat_itree(struct itree_t *cur_itp)
7754 {
7755  register int32 ii;
7756  struct mod_t *cur_imdp;
7757 
7758  cur_imdp = cur_itp->itip->imsym->el.emdp;
7759 
7760  /* if mod has no insts, nothing to do, if not top up frees */
7761  if (cur_imdp->minum == 0) return;
7762 
7763  /* otherwise free all under first */
7764  for (ii = 0; ii < cur_imdp->minum; ii++)
7765   free2_flat_itree(&(cur_itp->in_its[ii]));
7766 
7767  /* all under freed but in its table not yet freed */
7768  __my_free ((char *) cur_itp->in_its, cur_imdp->minum*sizeof(struct itree_t));
7769  cur_itp->in_its = NULL;
7770 }
7771 
7772 /*
7773  * ROUTINES TO BUILD INSTANCE NUMBER TO ITREE TABLES
7774  */
7775 
7776 /*
7777  * build mod itp tabs for all modules
7778  *
7779  * look to improve this - either build only when needed or remove unneeded
7780  * before run time
7781  */
bld_moditps(void)7782 static void bld_moditps(void)
7783 {
7784  register struct mod_t *mdp;
7785  register int32 ii;
7786  struct itree_t *itp, *itp2;
7787 
7788  /* first allocate the inst num to itree location tables */
7789  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
7790   {
7791    mdp->moditps = (struct itree_t **)
7792    __my_malloc(mdp->flatinum*sizeof(struct itree_t *));
7793    memset(mdp->moditps, 0, mdp->flatinum*sizeof(struct itree_t *));
7794   }
7795 
7796  for (ii = 0; ii < __numtopm; ii++)
7797   {
7798    itp = __it_roots[ii];
7799    mdp = itp->itip->imsym->el.emdp;
7800    mdp->moditps[itp->itinum] = itp;
7801    bld2_itnum_to_itp(itp);
7802   }
7803 
7804 
7805  if (__debug_flg)
7806   {
7807    for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
7808     {
7809      __dbg_msg("\n--- module %s instances:\n", mdp->msym->synam);
7810      for (ii = 0; ii < mdp->flatinum; ii++)
7811       {
7812        itp2 = mdp->moditps[ii];
7813        __dbg_msg("  instance %s type %s\n", __msg2_blditree(__xs, itp2),
7814         itp2->itip->imsym->synam);
7815       }
7816     }
7817    __dbg_msg("\n");
7818   }
7819 }
7820 
7821 /*
7822  * recusively build the table
7823  */
bld2_itnum_to_itp(struct itree_t * itp)7824 static void bld2_itnum_to_itp(struct itree_t *itp)
7825 {
7826  register int32 ii;
7827  struct mod_t *mdp;
7828 
7829  mdp = itp->itip->imsym->el.emdp;
7830  if (mdp->moditps != NULL) mdp->moditps[itp->itinum] = itp;
7831  for (ii = 0; ii < mdp->minum; ii++) bld2_itnum_to_itp(&(itp->in_its[ii]));
7832 }
7833 
7834