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