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  * Verilog simulation preparation routines
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #ifdef __DBMALLOC__
37 #include "../malloc.h"
38 #endif
39 
40 #include "v.h"
41 #include "cvmacros.h"
42 
43 #include "vpi_user.h"
44 
45 /* local prototypes */
46 static void rem_inc_dupes(void);
47 static void prep_udps(void);
48 static void prep1_udp(struct udp_t *);
49 static void prep_comb_udptab(struct udp_t *);
50 static void xpnd_1wcard(int32, word32);
51 static void init_utab(word32 *, int32);
52 static void chg_unfilled_tox(word32 *, int32);
53 static void bld_wcardtab(register char *, word32, word32);
54 static word32 bld_uinitndx(char *, word32, int32);
55 static void setchk_uval(word32);
56 static char *bld_udploc(char *, word32, word32, word32);
57 static char *udploc_to_line(char *, char *);
58 static void dmp_comb_udptab(struct udp_t *);
59 static void dmp_udp3v_tab(word32 *, word32);
60 static char *bld3vndx_str(char *, word32, word32);
61 static void dmp_udp2b_tab(word32 *, word32);
62 static int32 udmp_impossible_value(word32, word32);
63 static char *bldndx_str(char *, word32, word32);
64 static void dmp_edge_udptab(struct udp_t *);
65 static void dmp_udp3v_etab(word32 *, word32, int32, int32);
66 static void dmp_udp2b_etab(word32 *, word32, int32, int32);
67 static void prep_edge_udptab(struct udp_t *);
68 static void xpnd_edge_wcard(word32, int32, int32, word32);
69 static void free_udp_lines(struct udp_t *);
70 static void change_all_rngreps(void);
71 static void set_optim_nflds(struct net_t *);
72 static void free_ncablks(void);
73 static void emit_varunused_informs(struct net_t *, struct task_t *);
74 static void rt_change_rngrep(struct net_t *);
75 static void bld_gstate(void);
76 static void alloc_gstate(struct gate_t *, int32);
77 static word32 cmp_udpind(word32, word32);
78 static void prep_conta_dels(void);
79 static int32 rhs_cat_separable(struct expr_t *);
80 static int32 rhs_modpin_separable(struct expr_t *);
81 static void bld_pbsep_input_mpps(void);
82 static void bld_pbsep_output_mpps(void);
83 static int32 output_pb_separable(void);
84 static void bld_pb_mpps(struct mod_pin_t *);
85 static void bld_pb_contas(void);
86 static struct pbexpr_t *bld_pb_expr_map(struct expr_t *, int32);
87 static void init_pbexpr_el(struct pbexpr_t *);
88 static struct expr_t *bld_1sep_pbit_expr(struct pbexpr_t *, int32);
89 static struct expr_t *cnvt_to_bsel_expr(struct expr_t *, int32);
90 static void bld_nplist(void);
91 static void bld_lhsexpr_npins(struct expr_t *, int32);
92 static void bld2_lhsexpr_npins(struct expr_t *, int32);
93 static void bld_rhsexpr_npins(struct expr_t *, int32);
94 static void conn_rtxmr_npin(struct net_t *, int32, int32, int32, int32,
95  struct gref_t *, int32, char *);
96 static void conn_xmr_npin(struct net_t *, int32, int32, int32, int32,
97  struct gref_t *, int32, char *);
98 static struct net_pin_t *conn2_npin(struct net_t *, int32, int32, int32,
99  int32);
100 static void set_chgsubfld(struct net_pin_t *, int32, char *);
101 static void add_netdel_pnp(struct net_t *, struct paramlst_t *);
102 static void init_pnp(struct parmnet_pin_t *);
103 static void addto_parmnplst(struct expr_t *, struct parmnet_pin_t *);
104 static void add_gatedel_pnp(struct gate_t *, struct paramlst_t *);
105 static void add_contadel_pnp(struct conta_t *, struct paramlst_t *);
106 static void free_1parm_pnps(struct net_t *);
107 static void realloc_npplist_to_tab(void);
108 static void realloc_1net_npplist(struct net_t *);
109 static int32 cnt_npps(struct net_pin_t *);
110 static int32 cnt_dces(struct dcevnt_t *);
111 static void eat_gates(void);
112 static int32 has_muststay_npp(register struct net_pin_t *);
113 static void mark_muststay_wires(struct expr_t *);
114 static void eat_nets(int32);
115 static void rem_del_npps(void);
116 static void remove_all_npps(struct net_t *);
117 static void bld1vec_fifo(struct net_t *);
118 static void update_vec_fifo(struct net_t *, word32 *, int32 *, int32 *,
119  int32 *);
120 static int32 wire_implied_driver(struct net_t *);
121 static void eat_cells(int32 *);
122 static int32 conn_expr_gone(struct expr_t *);
123 static void mark_maybe_gone_nets(struct expr_t *);
124 static void getbit_fifo(struct net_t *, int32, int32 *, int32 *);
125 
126 /* extern prototypes (maybe defined in this module) */
127 extern void __prep_sim(void);
128 extern void __set_init_gstate(struct gate_t *, int32, int32);
129 extern void __set_init_udpstate(struct gate_t *, int32, int32);
130 extern void __conn_npin(struct net_t *, int32, int32, int32, int32,
131  struct gref_t *, int32, char *);
132 extern struct net_pin_t *__alloc_npin(int32, int32, int32);
133 extern struct npaux_t *__alloc_npaux(void);
134 extern void __add_dctldel_pnp(struct st_t *);
135 extern void __add_tchkdel_pnp(struct tchk_t *, int32);
136 extern void __add_pathdel_pnp(struct spcpth_t *);
137 extern void __free_design_pnps(void);
138 extern int32 __get_acc_class(struct gate_t *);
139 extern int32 __add_gate_pnd0del(struct gate_t *, struct mod_t *, char *);
140 extern int32 __add_conta_pnd0del(struct conta_t *, struct mod_t *, char *);
141 
142 extern void __prep_xmrs(void);
143 extern void __alloc_nchgaction_storage(void);
144 extern void __alloc_sim_storage(void);
145 extern void __bld_bidandtran_graph(void);
146 extern void __setchk_all_fifo(void);
147 extern void __prep_exprs_and_ports(void);
148 extern void __prep_contas(void);
149 extern void __prep_stmts(void);
150 extern void __set_nchgaction_bits(void);
151 extern void __set_optimtab_bits(void);
152 extern void __set_mpp_assign_routines(void);
153 extern void __set_pb_mpp_assign_routines(void);
154 extern void __set_mpp_aoff_routines(void);
155 extern void __dmpmod_nplst(struct mod_t *, int32);
156 extern void __do_decompile(void);
157 extern void __prep_specify(void);
158 extern void __show_allvars(void);
159 extern char *__my_malloc(int32);
160 extern void __my_free(char *, int32);
161 extern char *__to_uvvnam(char *, word32);
162 extern char *__to_wtnam(char *, struct net_t *);
163 extern char *__to_ptnam(char *, word32);
164 extern void __prep_delay(struct gate_t *, struct paramlst_t *, int32, int32,
165  char *, int32, struct sy_t *, int32);
166 extern void __free_xtree(struct expr_t *);
167 extern void __init_vec_var(register word32 *, int32, int32, int32, word32,
168  word32);
169 extern char *__to_mpnam(char *, char *);
170 extern int32 __isleaf(struct expr_t *);
171 extern char *__msgexpr_tostr(char *, struct expr_t *);
172 extern void __free_dellst(struct paramlst_t *);
173 extern void __free_del(union del_u, word32, int32);
174 extern void __bld_pb_fifo(struct net_t *, int32 *, int32 *, int32 *, int32);
175 extern int32 __gate_is_acc(struct gate_t *);
176 extern char *__bld_lineloc(char *, word32, int32);
177 extern void __allocinit_perival(union pck_u *, int32, int32, int32);
178 extern int32 __comp_ndx(register struct net_t *, register struct expr_t *);
179 extern void __rem_0path_dels(void);
180 extern int32 __chk_0del(word32, union del_u, struct mod_t *);
181 extern void __push_wrkitstk(struct mod_t *, int32);
182 extern void __pop_wrkitstk(void);
183 extern struct expr_t *__copy_expr(struct expr_t *);
184 extern int32 __cnt_cat_size(struct expr_t *);
185 extern struct expr_t *__alloc_newxnd(void);
186 extern struct expr_t *__bld_rng_numxpr(word32, word32, int32);
187 extern int32 __get_const_bselndx(register struct expr_t *);
188 extern void __getwir_range(struct net_t *, int32 *, int32 *);
189 extern int32 __is_const_expr(struct expr_t *);
190 
191 extern void __cv_msg(char *, ...);
192 extern void __dbg_msg(char *, ...);
193 extern void __pv_ferr(int32, char *, ...);
194 extern void __gfinform(int32, word32, int32, char *, ...);
195 extern void __gfwarn(int32, word32, int32, char *, ...);
196 extern void __gferr(int32, word32, int32, char *, ...);
197 extern void __sgferr(int32, char *, ...);
198 extern void __sgfinform(int32, char *, ...);
199 extern void __arg_terr(char *, int32);
200 extern void __case_terr(char *, int32);
201 extern void __misc_terr(char *, int32);
202 
203 extern void __vpi_err(int32, int32, char *, ...);
204 
205 extern word32 __masktab[];
206 
207 /*
208  * SIMULATION PREPARATION ROUTINES
209  */
210 
211 /*
212  * prepare for simulation
213  */
__prep_sim(void)214 extern void __prep_sim(void)
215 {
216  register struct mod_t *mdp;
217  int32 sav_declobj;
218 
219  /* because checking delay expressions need object type global set */
220  sav_declobj = __cur_declobj;
221  __cur_declobj = MODULE;
222 
223  /* done reading source files - remove all duplicates from inc dbg list */
224  if (__inclst_hdr != NULL) rem_inc_dupes();
225 
226  /* build per type udp tables - 1st since can free lots of storage */
227  prep_udps();
228 
229  /* first change all wire ranges to constant form - need to build np list */
230  change_all_rngreps();
231 
232  /* allocate and fill xmr table - used when building np list */
233  __prep_xmrs();
234 
235  /* SJM 09/18/02 - build the per bit decomposed ports and iconns */
236  bld_pbsep_input_mpps();
237  bld_pbsep_output_mpps();
238  bld_pb_contas();
239 
240  /* build the various net pin lists */
241  bld_nplist();
242 
243  /* if errors building np list can't check further */
244  if (__pv_err_cnt != 0) return;
245 
246  /* SJM 05/03/05 - now always allocate nchg action byte table separately */
247  __alloc_nchgaction_storage();
248 
249  /* allocate storage for wire and regs (variables) and gate states */
250  __alloc_sim_storage();
251 
252  bld_gstate();
253  prep_conta_dels();
254 
255  /* build inout tran and tran channel connection graphs */
256  __bld_bidandtran_graph();
257 
258  /* SJM 12/19/04 - after tran chans built, tran npps removed so can convert */
259  /* npp list to a table - but still set npnxt since add/rem during sim */
260  realloc_npplist_to_tab();
261 
262  if (__gateeater_on) eat_gates();
263 
264  /* mark each wire that has multi fan in for any bit */
265  __setchk_all_fifo();
266 
267  /* allocate inout port memory and mark expr. fi>1 */
268  __prep_exprs_and_ports();
269 
270  /* special preparation for contas (alloc drive values) and check getpats */
271  __prep_contas();
272 
273  /* modify statements where needed */
274  /* this also needs sim storage to be allocated */
275  __prep_stmts();
276 
277  /* new first step toward compiler optimization routines (this for ports) */
278  if (__accelerate)
279   {
280    __set_mpp_assign_routines();
281    __set_pb_mpp_assign_routines();
282   }
283  else __set_mpp_aoff_routines();
284 
285  /* SJM 07/19/02 - need to prep specify to add tchk and path loads */
286  /* before setting nchg action bits */
287 
288  /* all modules processed, object now only specify */
289  __cur_declobj = SPECIFY;
290  __prep_specify();
291  /* interactive must run in module declare object for expr. */
292  __cur_declobj = sav_declobj;
293 
294  /* SJM 08/08/03 - order was wrong, this is needed before setting chg bits */
295  /* LOOKATME - only setting optim fields for dmpvars so far */
296  __set_optimtab_bits();
297 
298  /* SJM 05/05/05 - since using new nchgbtab for per inst nchg bytes */
299  /* must always initialize the nchg action bits here */
300  /* notice all event control dces added by here */
301  __set_nchgaction_bits();
302 
303  if (__debug_flg)
304   {
305    for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
306     __dmpmod_nplst(mdp, FALSE);
307   }
308  if (__debug_flg && __decompile) __do_decompile();
309 
310  if (__debug_flg) __show_allvars();
311 }
312 
313 /*
314  * ROUTINES TO PREPARE SOURCE FOR DEBUGGER CAN BE DONE ANY TIME
315  */
316 
317 /*
318  * remove all duplicated (exactly same name) include files
319  */
rem_inc_dupes(void)320 static void rem_inc_dupes(void)
321 {
322  register struct incloc_t *ilp, *ilp2, *last_ilp2, *ilp3;
323 
324  for (ilp = __inclst_hdr; ilp != NULL; ilp = ilp->inclocnxt)
325   {
326    last_ilp2 = ilp;
327    for (ilp2 = ilp->inclocnxt; ilp2 != NULL;)
328     {
329      ilp3 = ilp2->inclocnxt;
330      /* notice if same file included with different path ref. just left */
331      if (strcmp(__in_fils[ilp->inc_fnind], __in_fils[ilp2->inc_fnind]) == 0)
332       {
333        /* if same leave first and link out next and keep looking */
334        last_ilp2->inclocnxt = ilp2->inclocnxt;
335        __my_free((char *) ilp2, sizeof(struct incloc_t));
336       }
337      else last_ilp2 = ilp2;
338      ilp2 = ilp3;
339     }
340   }
341 }
342 
343 /*
344  * ROUTINES TO BUILD UDP STATE CHANGE TABLES
345  */
346 
347 /*
348  * prepare all udp types - i.e. build the tables
349  */
prep_udps(void)350 static void prep_udps(void)
351 {
352  register struct udp_t *udpp;
353  struct udp_t *udpp2, *last_udpp;
354  long sav_mem_use;
355 
356  sav_mem_use = __mem_use;
357  for (last_udpp = NULL, udpp = __udphead; udpp != NULL;)
358   {
359    udpp2 = udpp->udpnxt;
360    if (udpp->u_used)
361     {
362      __mem_use = sav_mem_use;
363      prep1_udp(udpp);
364      __mem_udpuse += __mem_use - sav_mem_use;
365      __mem_use = sav_mem_use;
366 
367      /* cannot free lines since dumping source for debug after prep DBG */
368      /* free_udp_lines(udpp); */
369      last_udpp = udpp;
370     }
371    else
372     {
373      free_udp_lines(udpp);
374      __my_free((char *) udpp, sizeof(struct udp_t));
375      if (last_udpp == NULL) __udphead = udpp2;
376      else last_udpp->udpnxt = udpp2;
377      /* do not change last_udpp here */
378     }
379    udpp = udpp2;
380   }
381 }
382 
383 /*
384  * prepare one udp
385  */
prep1_udp(struct udp_t * udpp)386 static void prep1_udp(struct udp_t *udpp)
387 {
388  /* either combinatorial (no state) or level */
389  if (udpp->utyp != U_EDGE)
390   {
391    udpp->utab = (struct udptab_t *) __my_malloc(sizeof(struct udptab_t));
392    udpp->utab->eudptabs = NULL;
393    prep_comb_udptab(udpp);
394    /* array of pointers to tables is of size [number of edge tables-1] */
395    udpp->utab->ludptab = __cur_utab;
396    /* DBG remove --
397    if (__debug_flg) dmp_comb_udptab(udpp);
398    --- */
399    return;
400   }
401  /* build the edge table - for now always build even if no level entries */
402  prep_edge_udptab(udpp);
403  /* -- DBG remove
404  if (__debug_flg) dmp_edge_udptab(udpp);
405  --- */
406 }
407 
408 /* table of combinatorial table output sizes in bits (2 per entry) */
409 /* constant must be <= 7 since 7 inputs is 4k bytes per table */
410 static int32 combtabsiz[] = { 0, 8, 32, 128, 512, 2048, 8192, 32768 };
411 
412 /* table of slower encoding scheme sizes in bits (standard <= 10 ins) */
413 static int32 comb2tabsiz[] = { 0, 6, 18, 54, 162, 486, 1458, 4374, 13122,
414  39366, 118098, 354294, 1062882, 3188646, 9565938, 28697814 };
415 
416 /*
417  * build the combinatorial table
418  * also needed for sequential udps where levels override edges
419  * use 2 bit per input form for up to 6 inputs
420  *
421  * notice output can not be wild card since would means 1 input combination
422  * to multiple outputs
423  */
prep_comb_udptab(struct udp_t * udpp)424 static void prep_comb_udptab(struct udp_t *udpp)
425 {
426  register struct utline_t *utlp;
427  word32 nstates;
428  int32 blen, bytsiz;
429  word32 ndx;
430  char out_ch;
431 
432  /* for comb. errors must indicate no edge */
433  __cur_ueipnum = NO_VAL;
434  __cur_utabsel = NO_VAL;
435  /* udp number of states includes output for sequentials */
436  nstates = udpp->numstates;
437  /* set size of table */
438  if (udpp->u_wide) blen = comb2tabsiz[nstates];
439  else blen = combtabsiz[nstates];
440  /* notice Verilog assumes 8 bit bytes */
441  /* SJM 05/19/01 - since fill using word32 ptr need to round to wrd bytes */
442  bytsiz = WRDBYTES*wlen_(blen);
443  /* RELEASE remove --
444  if (__debug_flg)
445   __dbg_msg("## comb (part?) udp %s - %u states with table size %d bytes\n",
446    udpp->usym->synam, nstates, bytsiz);
447  --- */
448  __cur_utab = (word32 *) __my_malloc(bytsiz);
449  /* initialize to unfilled (3) - maps table x (2) to real 3 as last step */
450  init_utab(__cur_utab, blen);
451  __cur_udp = udpp;
452 
453  for (utlp = udpp->utlines; utlp != NULL; utlp = utlp->utlnxt)
454   {
455    /* if this is edge line, goes in edge not combinatorial table */
456    if (utlp->uledinum != NO_VAL) continue;
457 
458    __sfnam_ind = utlp->utlfnam_ind;
459    __slin_cnt = utlp->utlin_cnt;
460 
461    /* next output state can be wildcard */
462    if (utlp->ulhas_wcard) bld_wcardtab(utlp->tline, nstates, nstates + 1);
463 
464    /* build 2 bit form for narrow or signature for wide */
465    /* wildcards here always make 0 contribution */
466    ndx = bld_uinitndx(utlp->tline, nstates, -1);
467 
468    /* out ch gets the output value (as char here) */
469    out_ch = utlp->tline[udpp->numstates];
470    /* if output - (no change form) must set output (__cur_uoval) during */
471    /* wild card expansion */
472    if (out_ch == '-') __cur_unochange = TRUE;
473    else
474     {
475      /* else can set it immediately */
476      __cur_unochange = FALSE;
477      /* must be for checking so will match x */
478      __cur_uoval = (word32) ((out_ch == '0') ? 0 : ((out_ch == '1') ? 1 : 2));
479     }
480    /* this sets 1st to each and recursives call self to expand others */
481    if (utlp->ulhas_wcard) xpnd_1wcard(0, ndx);
482    /* if no wildcards, even if '-' output, will be 0/1/x (3 since out) */
483    /* this sets current output value */
484    else setchk_uval(ndx);
485   }
486  /* finally for all locations left unitialized changed to udp x (2) */
487  chg_unfilled_tox(__cur_utab, blen);
488 }
489 
490 extern word32 __pow3tab[];
491 
492 /*
493  * recursively expand 1 wild card
494  * if wildcard, must be used to set all o states (even 1st)
495  * notice recursion depends on fact that passed ndx is by value
496  */
xpnd_1wcard(int32 wci,word32 ndx)497 static void xpnd_1wcard(int32 wci, word32 ndx)
498 {
499  int32 wcvi, wchval, i;
500  word32 ndx2;
501 
502  wchval = (__wcardtab[wci].wcchar == '?') ? 2 : 1;
503  i = __wcardtab[wci].wcinum;
504  /* notice need to go through for 0 since table value not yet set */
505  for (wcvi = 0; wcvi <= wchval; wcvi++)
506   {
507    if (!__cur_udp->u_wide)
508     {
509      /* know i input 2 bits will always be 0 */
510      if (wcvi == 0) ndx2 = ndx;
511      else
512       {
513        /* needed because even though now sticking 2 in as x output */
514        /* index must be 3 which will be the value after table prepared */
515        /* for non wide table entry */
516        if (wcvi == 2) wcvi = 3;
517        ndx2 = ndx | (word32) (wcvi << (2*i));
518       }
519     }
520    else
521     {
522      /* know here contribution from i, is 0 in ndx */
523      if (wcvi != 0) ndx2 = ndx + wcvi*__pow3tab[i];
524      else ndx2 = ndx;
525      /* know if this is true, will always be rightmost wild card */
526      if (i == __cur_udp->numstates - 1) __cur_upstate = (word32) wcvi;
527      if (ndx2 >= __pow3tab[__cur_udp->numstates])
528       __misc_terr(__FILE__, __LINE__);
529     }
530    /* - (no change) output handled in level value setting */
531    if (wci == __last_wci) setchk_uval(ndx2);
532    else xpnd_1wcard(wci + 1, ndx2);
533   }
534 }
535 
536 /*
537  * init a udp table to 3 (not set) - later change 2 (x for now) to x (3)
538  * notice udp 2 is unused not z (no z in udp world)
539  * inputs always just 3 for normal rep, 2 add value for signature
540  *
541  * when done here all 2's changed to 3's (real x's stored in output gstate)
542  * radix form uses 3's in vector but changed to 2 in signature update
543  * notice any unused in high word32 just set to unfilled
544  */
init_utab(word32 * taddr,int32 blen)545 static void init_utab(word32 *taddr, int32 blen)
546 {
547  register int32 i;
548  register word32 *wp;
549  int32 wlen;
550 
551  wlen = wlen_(blen);
552  /* initialize to real x's - during table building x's are 2 that are then */
553  /* changed to 3's where needed */
554  /* since most of table is x's can check and change to x much faster */
555  for (wp = taddr, i = 0; i < wlen; i++) wp[i] = ALL1W;
556  wp[wlen - 1] &= __masktab[ubits_(blen)];
557 }
558 
559 /*
560  * convert 1 unfilled (defaults to x) from unfill 2 to x (3)
561  */
chg_unfilled_tox(word32 * taddr,int32 blen)562 static void chg_unfilled_tox(word32 *taddr, int32 blen)
563 {
564  register word32 tmp;
565  register int32 wi, bi;
566  int32 wlen, ubits;
567 
568  wlen = wlen_(blen);
569  for (wi = 0; wi < wlen - 1; wi++)
570   {
571    /* if all bits already literally set to x's continue */
572    if ((tmp = taddr[wi]) == ALL1W) continue;
573 
574    /* must change 2 (tmp. udp table build x) to 3 - real x */
575    for (bi = 0; bi < WBITS; bi += 2)
576     {
577      if (((tmp >> bi) & 0x3L) == 2L)
578       tmp |= (3L << bi);
579     }
580    taddr[wi] = tmp;
581   }
582  /* if by accident high word32 full and already all x's - done */
583  if ((tmp = taddr[wlen - 1]) == ALL1W) return;
584 
585  /* high word32 needs special handling */
586  if ((ubits = ubits_(blen)) == 0) ubits = WBITS;
587  for (bi = 0; bi < ubits; bi += 2)
588   {
589    if (((tmp >> bi) & 0x3L) == 2L) tmp |= (3L << bi);
590   }
591  taddr[wlen - 1] = tmp;
592 }
593 
594 /*
595  * build wild card table from input line
596  * for each wild card table contains input no. and wild card char
597  *
598  * even if edge (\?\?) form (really *) do not include in wild card table
599  * for combinatorial table pass one past last input
600  */
bld_wcardtab(register char * chp,word32 nstates,word32 einum)601 static void bld_wcardtab(register char *chp, word32 nstates, word32 einum)
602 {
603  register word32 i;
604  struct wcard_t *wcp;
605 
606  for (__last_wci = -1, i = 0; i < nstates; i++, chp++)
607   {
608    if (i == einum) continue;
609 
610    if (*chp == 'b' || *chp == '?')
611     {
612      wcp = &(__wcardtab[++__last_wci]);
613      wcp->wcinum = i;
614      wcp->wcchar = *chp;
615     }
616   }
617 }
618 
619 /*
620  * build the initial udp table index -
621  * either 2 bit per input with x as 3 or signature with x as 2 contribution
622  */
bld_uinitndx(char * tlp,word32 nstates,int32 einum)623 static word32 bld_uinitndx(char *tlp, word32 nstates, int32 einum)
624 {
625  register word32 i;
626  register char *chp;
627  word32 ndx;
628 
629  /* ? (01x) and b (01) are only that later require loops */
630  ndx = 0;
631  /* build initial state vector and set rep table start */
632  /* wild cards 0 for now */
633  /* notice cannot build incrementally, pins in initial signature backward*/
634  for (i = 0, chp = tlp; i < nstates; i++, chp++)
635   {
636    /* for edge tab, if wildcard table select do not include, added in xpnd */
637    if (i == (int32) einum) continue;
638    switch (*chp) {
639     /* make edge wildcards 0 here also - r/f just (01) and (10) by here */
640     case '0': case 'b': case '?': case '*': case 'n': case 'p':
641      if (__cur_udp->u_wide) __cur_upstate = 0L;
642      break;
643     case '1':
644      if (__cur_udp->u_wide) { ndx += __pow3tab[i]; __cur_upstate = 1L; }
645      else { ndx &= ~(3L << (2*i)); ndx |= (1L << (2*i)); }
646      break;
647     /* explicit x is always 2 here for normal udp (later changed to 3) */
648     case 'x':
649      if (__cur_udp->u_wide) { ndx += 2*__pow3tab[i]; __cur_upstate = 2L; }
650      else ndx |= (3L << (2*i));
651      break;
652     default: __case_terr(__FILE__, __LINE__);
653    }
654   }
655  return(ndx);
656 }
657 
658 /*
659  * set and check if already set a normal non signature udp table entry
660  * this is only place in udp preparation code that udp tables indexed
661  * this is passed input state in 2 bit form with x == 2
662  * uninitialized is 3 here that statys as real x (3) before exec
663  * set to x is 2 here that is changed to 3, real x
664  */
setchk_uval(word32 init_ndx)665 static void setchk_uval(word32 init_ndx)
666 {
667  register word32 tw, tw2;
668  word32 ndx;
669  int32 wi, bi;
670  char s1[RECLEN], s2[RECLEN];
671 
672  /* by here init_ndx is correct for this wildcard */
673  if (__cur_udp->u_wide) ndx = init_ndx;
674  else ndx = init_ndx & (int32) __masktab[2*__cur_udp->numstates];
675 
676  /* set 2: get old value */
677  wi = get_wofs_(2*ndx);
678  bi = get_bofs_(2*ndx);
679  /* notice for edge cur utab set to right table from edge pair */
680  tw = __cur_utab[wi];
681  tw2 = (tw >> bi) & 3L;
682 
683  /* step 2a: if - output form get output */
684  /* if output is '-' use last input that is state */
685  /* if not '-' form, know __cur_uoval not set */
686  if (__cur_unochange)
687   {
688    /* notice this can only happen for udp's with state */
689    if (__cur_udp->u_wide) __cur_uoval = __cur_upstate;
690    else
691     {
692      __cur_uoval = (init_ndx >> (2*(__cur_udp->numins))) & 0x3L;
693      /* must be 2 so if table set (old value == 2) will get warn if 2 */
694      if (__cur_uoval == 3L) __cur_uoval = 2L;
695     }
696   }
697  /* step3: if table value already set - check it */
698  if (tw2 != 3L)
699   {
700    if (__cur_uoval == tw2)
701     {
702      /* do not know previous line - could save but complicated */
703     __sgfinform(462, "udp %s selector %s repeated", __cur_udp->usym->synam,
704       bld_udploc(s1, ndx, __cur_uoval, __cur_udp->numstates));
705      goto done;
706     }
707   __sgferr(970, "udp %s selector %s conflicts with previous %s",
708    __cur_udp->usym->synam, bld_udploc(s1, ndx, __cur_uoval,
709    __cur_udp->numstates), bld_udploc(s2, ndx, tw2, __cur_udp->numstates));
710    /* fall thru here, even though error, use latest */
711   }
712 
713  /* step4: change output to new value, here x must be represented as 2 */
714  /* that gets changed later */
715  __cur_utab[wi] = (tw & ~(3L << bi)) | (__cur_uoval << bi);
716 
717 done:;
718  /* --- RELEASE ---
719  if (__debug_flg)
720   {
721    __dbg_msg("+++ udp set: %s, val=%x, bi=%d, wi=%d\n",
722     bld_udploc(s1, ndx, __cur_uoval, __cur_udp->numstates),
723     __cur_utab[wi], bi, wi);
724    __dbg_msg("+++ udp set: %s\n", bld_udploc(s1, ndx, __cur_uoval,
725     __cur_udp->numstates));
726   }
727  --- */
728 }
729 
730 /*
731  * build a udp location entry - for error messages
732  * notice for wide signature form index must be wp[1] actual table index
733  */
bld_udploc(char * s,word32 ndx,word32 val,word32 nstates)734 static char *bld_udploc(char *s, word32 ndx, word32 val, word32 nstates)
735 {
736  char s1[RECLEN], s2[RECLEN];
737 
738  if (__cur_udp->u_wide) bld3vndx_str(s1, ndx, nstates);
739  else bldndx_str(s1, ndx, nstates);
740  udploc_to_line(s2, s1);
741 
742  sprintf(s, "%s : %s", s2, __to_uvvnam(s1, (word32) val));
743  return(s);
744 }
745 
746 /*
747  * convert a simple edge char array to edge line
748  */
udploc_to_line(char * s,char * line)749 static char *udploc_to_line(char *s, char *line)
750 {
751  register int32 i;
752  int32 slen;
753  char *chp, *lchp;
754 
755  /* first add edge */
756  if (__cur_ueipnum != NO_VAL)
757   {
758    lchp = line;
759    chp = s;
760    for (i = 0; *lchp != '\0'; i++)
761     {
762      if (i == __cur_ueipnum)
763       {
764        *chp++ = '(';
765        *chp++ = (__cur_utabsel == 0) ? '0': (__cur_utabsel == 1) ? '1' : 'x';
766        *chp++ = *lchp++;
767        *chp++ = ')';
768       }
769      else *chp++ = *lchp++;
770     }
771    *chp = '\0';
772   }
773  else strcpy(s, line);
774  /* then add : if has state */
775  if (__cur_udp->numins != __cur_udp->numstates)
776   {
777    slen = strlen(s);
778    s[slen + 1] = '\0';
779    s[slen] = s[slen - 1];
780    s[slen - 1] = ':';
781   }
782  return(s);
783 }
784 
785 /*
786  * dump a non edge udp table only 6 states or less
787  */
dmp_comb_udptab(struct udp_t * udpp)788 static void dmp_comb_udptab(struct udp_t *udpp)
789 {
790  word32 *utabp;
791  word32 nstates;
792 
793  utabp = udpp->utab->ludptab;
794  nstates = udpp->numstates;
795  if (nstates > 6) return;
796 
797  __dbg_msg(".. dumping combinatorial udp %s with %d states\n",
798   udpp->usym->synam, nstates);
799  if (udpp->u_wide) dmp_udp3v_tab(utabp, nstates);
800  else dmp_udp2b_tab(utabp, nstates);
801  __dbg_msg("... end dump\n");
802 }
803 
804 /*
805  * dump a non superposition 2b per element form udp table
806  * input is array of words and number of inputs
807  * need more sophisticated version
808  */
dmp_udp3v_tab(word32 * tabp,word32 nstates)809 static void dmp_udp3v_tab(word32 *tabp, word32 nstates)
810 {
811  register word32 i;
812  int32 bi, wi;
813  word32 val, ndx;
814  char s1[RECLEN], s2[RECLEN];
815 
816  ndx = 0;
817  for (i = 0, bi = 0; i < __pow3tab[nstates]; i++)
818   {
819    ndx = i;
820    wi = get_wofs_(2*ndx);
821    bi = get_bofs_(2*ndx);
822    val = (tabp[wi] >> bi) & 0x3L;
823    /* RELEASE ---
824    __dbg_msg("%s: %s, val=%lx, bi=%d, wi=%d\n", bld3vndx_str(s1, ndx,
825     nstates), __to_uvvnam(s2, val), tabp[wi], bi, wi);
826    --- */
827    __dbg_msg("%s: %s\n", bld3vndx_str(s1, ndx, nstates),
828     __to_uvvnam(s2, val));
829   }
830 }
831 
832 /*
833  * build the input string with high value (rightmost on left)
834  */
bld3vndx_str(char * s,word32 ndx,word32 nstates)835 static char *bld3vndx_str(char *s, word32 ndx, word32 nstates)
836 {
837  register word32 i;
838  word32 val;
839  char s1[10];
840 
841  for (i = 0; i < nstates; i++)
842   { val = ndx % 3; ndx /= 3; __to_uvvnam(s1, val); s[i] = s1[0]; }
843  s[i] = '\0';
844  return(s);
845 }
846 
847 /*
848  * dump a non superposition 2b per element form udp table
849  * input is array of words and number of inputs
850  */
dmp_udp2b_tab(word32 * tabp,word32 nstates)851 static void dmp_udp2b_tab(word32 *tabp, word32 nstates)
852 {
853  register word32 i;
854  int32 bi, wi;
855  word32 val, ndx;
856  char s1[RECLEN], s2[RECLEN];
857 
858  ndx = 0;
859  for (i = 0; i < (1 << (2*nstates)); i++)
860   {
861    ndx = (word32) i;
862    /* for narrow case, z's in signature but never used */
863    if (udmp_impossible_value(ndx, nstates)) continue;
864 
865    wi = get_wofs_(2*ndx);
866    bi = get_bofs_(2*ndx);
867    val = (tabp[wi] >> bi) & 0x3L;
868    /* --- RELEASE
869    if (__debug_flg)
870     {
871      __dbg_msg("%s: %s, val=%lx, bi=%d, wi=%d\n", bldndx_str(s1, ndx,
872       nstates), __to_uvvnam(s2, val), tabp[wi], bi, wi);
873     }
874    -- */
875    __dbg_msg("%s: %s\n", bldndx_str(s1, ndx, nstates),
876     __to_uvvnam(s2, val));
877   }
878 }
879 
880 /*
881  * return T if somewhere there is a 2 bit 10 pattern in word
882  * since for narrow know 10 index never used just 00, 01, 11
883  */
udmp_impossible_value(word32 ndx,word32 nstates)884 static int32 udmp_impossible_value(word32 ndx, word32 nstates)
885 {
886  register word32 i;
887 
888  for (i = 0; i < nstates; i++)
889   { if (((ndx >> (2*i)) & 3L) == 2L) return(TRUE); }
890  return(FALSE);
891 }
892 
893 /*
894  * build the input string with high value (rightmost on left)
895  */
bldndx_str(char * s,word32 ndx,word32 nstates)896 static char *bldndx_str(char *s, word32 ndx, word32 nstates)
897 {
898  register word32 i;
899  word32 val;
900  char vs1[10];
901 
902  for (i = 0; i < nstates; i++)
903   { val = (ndx >> (2*i)) & 3L; __to_uvvnam(vs1, val); s[i] = vs1[0]; }
904  s[i] = '\0';
905  return(s);
906 }
907 
908 /*
909  * dump an combinatorial udp table if not more than 5 inputs
910  */
dmp_edge_udptab(struct udp_t * udpp)911 static void dmp_edge_udptab(struct udp_t *udpp)
912 {
913  word32 *utabp;
914  int32 nins, i, v;
915 
916  nins = udpp->numins;
917  if (nins > 5) return;
918 
919  __dbg_msg(".. dumping edge udp %s with %d inputs\n", udpp->usym->synam,
920   nins);
921  __dbg_msg(" - combinatorial table:\n");
922  dmp_comb_udptab(udpp);
923 
924  __dbg_msg(" - edge tables:\n");
925  /* notice, edge udp always sequential and no edge for state input */
926  for (i = 0; i < nins; i++)
927   {
928    for (v = 0; v < 3; v++)
929     {
930      __dbg_msg(
931       "--> input no. %d changed from %c\n", i, ((v > 1) ? 'x': '0' + v ));
932      utabp = udpp->utab->eudptabs[3*i + v];
933      if (udpp->u_wide) dmp_udp3v_etab(utabp, udpp->numstates, i, v);
934      else dmp_udp2b_etab(utabp, udpp->numstates, i, v);
935     }
936   }
937  __dbg_msg("... end dump\n");
938 }
939 
940 /*
941  * dump a superposition form edge udp table
942  * input is array of words and number of inputs
943  * leave out lines where edge input and edge new value are same
944  * know eipnum never state value
945  */
dmp_udp3v_etab(word32 * tabp,word32 nstates,int32 eipnum,int32 e1val)946 static void dmp_udp3v_etab(word32 *tabp, word32 nstates, int32 eipnum,
947  int32 e1val)
948 {
949  register word32 i;
950  int32 bi, wi, ndxev;
951  word32 val, ndx;
952  char s1[RECLEN], s2[RECLEN];
953 
954  ndx = 0;
955  for (i = 0, bi = 0; i < __pow3tab[nstates]; i++)
956   {
957    ndx = i;
958    bld3vndx_str(s1, ndx, nstates),
959    ndxev = (s1[eipnum] == 'x') ? 2 : (s1[eipnum] - '0');
960    if (e1val == ndxev) continue;
961 
962    wi = get_wofs_(2*ndx);
963    bi = get_bofs_(2*ndx);
964    val = (tabp[wi] >> bi) & 0x3L;
965    /* --- RELEASE remove
966    __dbg_msg("%s: %s, val=%lx, bi=%d, wi=%d\n", s1, __to_uvvnam(s2, val),
967     tabp[wi], bi, wi);
968    --- */
969    __dbg_msg("%s: %s\n", s1, __to_uvvnam(s2, val));
970   }
971 }
972 
973 /*
974  * dump a non superposition 2b per element form udp table
975  * input is array of words and number of inputs
976   * notice for 11 states size will be 1 million lines
977  */
dmp_udp2b_etab(word32 * tabp,word32 nstates,int32 eipnum,int32 e1val)978 static void dmp_udp2b_etab(word32 *tabp, word32 nstates, int32 eipnum,
979  int32 e1val)
980 {
981  register word32 i;
982  int32 bi, wi, ndxev;
983  word32 val, ndx;
984  char s1[RECLEN], s2[RECLEN];
985 
986  ndx = 0L;
987  for (i = 0; i < (1 << (2*nstates)); i++)
988   {
989    ndx = (word32) i;
990    /* for narrow case, z's in signature but never used */
991    if (udmp_impossible_value(ndx, nstates)) continue;
992 
993    bldndx_str(s1, ndx, nstates);
994    ndxev = (s1[eipnum] == 'x') ? 2 : (s1[eipnum] - '0');
995    if (e1val == ndxev) continue;
996 
997    wi = get_wofs_(2*ndx);
998    bi = get_bofs_(2*ndx);
999    val = (tabp[wi] >> bi) & 0x3L;
1000    /* RELEASE remove ---
1001    __dbg_msg("%s: %s, val=%lx, bi=%d, wi=%d\n", s1, __to_uvvnam(s2, val),
1002     tabp[wi], bi, wi);
1003    --- */
1004    __dbg_msg("%s: %s\n", s1, __to_uvvnam(s2, val));
1005   }
1006 }
1007 
1008 /*
1009  * allocate the edge index and all the edge tables and set values from lines
1010  * know level table already filled and edge tables pointer array allocated
1011  */
prep_edge_udptab(struct udp_t * udpp)1012 static void prep_edge_udptab(struct udp_t *udpp)
1013 {
1014  register int32 i;
1015  register struct utline_t *utlp;
1016  int32 nins, eutabels, blen, bytsiz, tabi, e1val, e2val;
1017  word32 nstates;
1018  word32 ustate;
1019  char ech, out_ch, ech2;
1020 
1021  nstates = udpp->numstates;
1022  nins = udpp->numins;
1023  /* these are size for 1 table in bits */
1024  if (udpp->u_wide) blen = comb2tabsiz[nstates];
1025  else blen = combtabsiz[nstates];
1026  /* SJM 05/19/01 - since fill using word32 ptr need to round to wrd bytes */
1027  bytsiz = WRDBYTES*wlen_(blen);
1028 
1029  /* idea is that old input value selects table, new is index in table */
1030  /* 1 input 3 table 0,1,x, 2 inputs 6, 3 for 1st and 3 for 2nd, ... */
1031  /* state input cannot have edge */
1032  eutabels = 3*nins;
1033  /* -- RELEASE remove
1034  if (__debug_flg)
1035   __dbg_msg("## edge udp %s - %d inputs %d tables of size %d bytes\n",
1036    udpp->usym->synam, nins, eutabels, bytsiz);
1037  -- */
1038 
1039  /* number of separate tables is 1 per 3*[non state ins (ins-1)] + 1 */
1040  /* 3 is possible values and extra 1 is for level lines without edges */
1041  udpp->utab = (struct udptab_t *) __my_malloc(sizeof(struct udptab_t));
1042  udpp->utab->ludptab = NULL;
1043  udpp->utab->eudptabs = (word32 **) __my_malloc(eutabels*4);
1044  /* build the level tab - for now always build even if no level entries */
1045  prep_comb_udptab(udpp);
1046  udpp->utab->ludptab = __cur_utab;
1047 
1048  /* initialize all edge tables to */
1049  for (i = 0; i < eutabels; i++)
1050   {
1051    __cur_utab = (word32 *) __my_malloc(bytsiz);
1052    init_utab(__cur_utab, blen);
1053    udpp->utab->eudptabs[i] = __cur_utab;
1054   }
1055 
1056  for (utlp = udpp->utlines; utlp != NULL; utlp = utlp->utlnxt)
1057   {
1058    __cur_utlp = utlp;
1059    /* if no edge, already used to set level table output */
1060    if (utlp->uledinum == NO_VAL) continue;
1061 
1062    __slin_cnt = utlp->utlin_cnt;
1063    __sfnam_ind = utlp->utlfnam_ind;
1064 
1065    /* notice 1 possible edge wild card not in wild card table */
1066    /* but state can be wild card */
1067    /* never add in edge 2nd value here, added in xpnd or const. case */
1068    if (utlp->ulhas_wcard) bld_wcardtab(utlp->tline, nstates, utlp->uledinum);
1069 
1070    /* sets any wild cards including edge 1st values will be 00 */
1071    /* gets converted if wide form */
1072    ustate = bld_uinitndx(utlp->tline, nstates, (int32) utlp->uledinum);
1073 
1074    /* use the previuos state - if wildcard just */
1075    if ((out_ch = utlp->tline[nstates]) == '-') __cur_unochange = TRUE;
1076    else
1077     {
1078      /* if no '-' current output value fixed for all iterations */
1079      __cur_unochange = FALSE;
1080      /* must be 2 so if output set will match x */
1081      __cur_uoval = (out_ch == '0') ? 0 : ((out_ch == '1') ? 1 : 2);
1082     }
1083    /* for edge wild cards, both values same so can use first tab index */
1084    switch ((byte) utlp->utabsel) {
1085     case '*':
1086 do_star:
1087      xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1088      xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1089      xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1090      xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1091      xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1092      xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1093      break;
1094     case 'p':
1095      /* potential rising edge */
1096      xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1097      xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1098      xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1099      break;
1100     case 'n':
1101      /* potential falling edge */
1102      xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1103      xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1104      xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1105      break;
1106     case '?':
1107      ech2 = utlp->tline[utlp->uledinum];
1108      /* notice (..) form can be value or b or ? but not edge abbreviation */
1109      /* also notice for edge only wildcard is possible '-' */
1110      switch (ech2) {
1111       case '?':
1112        /* (\?\?) is same as * */
1113        goto do_star;
1114       case 'b':
1115        /* (?b) */
1116        xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1117        xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1118        xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1119        xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1120        break;
1121       case '0':
1122        /* (?0) */
1123        xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1124        xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1125        break;
1126       case '1':
1127        /* (?1) */
1128        xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1129        xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1130        break;
1131       case 'x':
1132        /* (?x) */
1133        xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1134        xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1135        break;
1136       default: __case_terr(__FILE__, __LINE__);
1137      }
1138      break;
1139     case 'b':
1140      ech2 = utlp->tline[utlp->uledinum];
1141      switch (ech2) {
1142       case '?':
1143        /* (b?) */
1144        xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1145        xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1146        xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1147        xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1148        break;
1149       case 'b':
1150        /* (bb) */
1151        xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1152        xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1153        break;
1154       case '0':
1155        /* (b0) */
1156        xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1157        break;
1158       case '1':
1159        /* (b1) */
1160        xpnd_edge_wcard(ustate, 0, 0, utlp->uledinum);
1161        break;
1162       case 'x':
1163        /* (bx) */
1164        xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1165        xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1166        break;
1167       default: __case_terr(__FILE__, __LINE__);
1168      }
1169      break;
1170     case '0': case '1': case 'x':
1171      /* notice ech is case index for output tab too */
1172      ech = (char) utlp->utabsel;
1173      /* may have ([01x][?b]) style wild card form  */
1174      ech2 = utlp->tline[utlp->uledinum];
1175      if (ech2 == '?')
1176       {
1177        switch (ech) {
1178         case '0':
1179          xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum);
1180          xpnd_edge_wcard(ustate, 0, 2, utlp->uledinum);
1181          break;
1182         case '1':
1183          xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum);
1184          xpnd_edge_wcard(ustate, 1, 2, utlp->uledinum);
1185          break;
1186         case 'x':
1187          xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1188          xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1189          break;
1190         default: __case_terr(__FILE__, __LINE__);
1191        }
1192        break;
1193       }
1194      if (ech2 == 'b')
1195       {
1196        switch (ech) {
1197         case '0': xpnd_edge_wcard(ustate, 0, 1, utlp->uledinum); break;
1198         case '1': xpnd_edge_wcard(ustate, 1, 0, utlp->uledinum); break;
1199         case 'x':
1200          xpnd_edge_wcard(ustate, 2, 0, utlp->uledinum);
1201          xpnd_edge_wcard(ustate, 2, 1, utlp->uledinum);
1202          break;
1203         default: __case_terr(__FILE__, __LINE__);
1204        }
1205        break;
1206       }
1207 
1208      e1val = (ech == '0') ? 0 : ((ech == '1') ? 1 : 2);
1209      tabi = 3*utlp->uledinum + e1val;
1210 
1211      /* non edge wild card case - must add in 2nd edge part of state */
1212      /* know contribution before here 0 */
1213      e2val = (ech2 == '0') ? 0 : ((ech2 == '1') ? 1 : 2);
1214      if (udpp->u_wide) ustate += (e2val*__pow3tab[utlp->uledinum]);
1215      else ustate |= (e2val << (2*utlp->uledinum));
1216 
1217      /* RELEASE remove ---
1218      if (__debug_flg)
1219       __dbg_msg(
1220        "=== non wildcard input edge (%c%c) with from value %d - table %d\n",
1221        utlp->uledinum, ech, ech2, tabi);
1222      --- */
1223      /* once current table corresponding to edge is set, just like level */
1224      __cur_utab = udpp->utab->eudptabs[tabi];
1225      if (!utlp->ulhas_wcard) setchk_uval(ustate);
1226      else xpnd_1wcard(0, ustate);
1227      break;
1228     default: __case_terr(__FILE__, __LINE__);
1229    }
1230   }
1231  /* final step is conversion of x (set x) to 3 real x */
1232  for (i = 0; i < eutabels; i++)
1233   {
1234    __cur_utab = udpp->utab->eudptabs[i];
1235    chg_unfilled_tox(__cur_utab, blen);
1236   }
1237 }
1238 
1239 /*
1240  * process edge wildcard entry - passed fixed edge generated from iteration
1241  * e1 val selects table and e2 val is table value (changed to)
1242  */
xpnd_edge_wcard(word32 ustate,int32 e1val,int32 e2val,word32 einpnum)1243 static void xpnd_edge_wcard(word32 ustate, int32 e1val, int32 e2val,
1244  word32 einpnum)
1245 {
1246  int32 tabi;
1247 
1248  /* first select the table */
1249  tabi = 3*einpnum + e1val;
1250  /* --- RELEASE remove
1251  if (__debug_flg)
1252   __dbg_msg("=== expand wildcard input edge %d from value %d - table %d\n",
1253    einpnum, e1val, tabi);
1254  --- */
1255  /* once current table corresponding to edge is set, just like level */
1256  __cur_utab = __cur_udp->utab->eudptabs[tabi];
1257 
1258  /* must set ustate input no. einpnum to ech2 value - know 0 on input */
1259  /* know this can never be last previous state input or will not get here */
1260  /* ustate is 2 bit per element form */
1261  /* ustate is table index so for narrow form must be 3 */
1262  if (__cur_udp->u_wide) ustate += e2val*__pow3tab[einpnum];
1263  else
1264   {
1265    /* ustate is index which for narrow must be 3 - value is 2 */
1266    if (e2val == 2) e2val = 3;
1267    ustate |= (((word32) e2val) << (2*einpnum));
1268   }
1269 
1270  /* need some global to be set for errors */
1271  __cur_ueipnum = einpnum;
1272  __cur_utabsel = e1val;
1273 
1274  /* ulhas_wcard is only level wildcard */
1275  if (!__cur_utlp->ulhas_wcard) setchk_uval(ustate);
1276  else xpnd_1wcard(0, ustate);
1277 }
1278 
1279 /*
1280  * free udp lines
1281  * only called for uninstantiated udps since size small and needed for PLI
1282  */
free_udp_lines(struct udp_t * udpp)1283 static void free_udp_lines(struct udp_t *udpp)
1284 {
1285  register struct utline_t *utlp;
1286  struct utline_t *utlp2;
1287 
1288  for (utlp = udpp->utlines; utlp != NULL;)
1289   {
1290    utlp2 = utlp->utlnxt;
1291    /* notice this is not 0 terminated string */
1292    __my_free(utlp->tline, (int32) utlp->ullen);
1293    __my_free((char *) utlp, sizeof(struct utline_t));
1294    utlp = utlp2;
1295   }
1296  udpp->utlines = NULL;
1297 }
1298 
1299 /*
1300  * ROUTINES TO CHANGE ALL WIRE RANGE REPS
1301  */
1302 /*
1303  * change representation and allocate sim net struct for every net range
1304  * must do unused var. checking before change range rep since uses ncomp
1305  * range form bits
1306  *
1307  * BEWARE - for normal nets allocating nu.ct to large chunk area because
1308  * freeing too slow - but here for params (also specparams) since cannot
1309  * distinguish must copy since now can be annotated too
1310  *
1311  * AIV 01/19/07 - need to do local params here as well for mod and tasks
1312  * 09/27/06 - local params not used in delay annotation so not copied here
1313  */
change_all_rngreps(void)1314 static void change_all_rngreps(void)
1315 {
1316  register int32 ni;
1317  register struct net_t *np;
1318  register struct ncomp_t *oncomp, *nncomp;
1319  struct mod_t *mdp;
1320  int32 pi, sav_declobj;
1321  struct task_t *tskp;
1322 
1323  sav_declobj = __cur_declobj;
1324  __cur_declobj = MODULE;
1325  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1326   {
1327    __push_wrkitstk(mdp, 0);
1328    __cur_declobj = MODULE;
1329 
1330    if (__inst_mod->mnnum != 0)
1331     {
1332      for (ni = 0, np = &(__inst_mod->mnets[0]); ni < __inst_mod->mnnum;
1333       ni++, np++)
1334       {
1335 //SJM FIXME - why both { {
1336         {
1337          /* expect inout ports to be set but not used or used but not set */
1338          if (np->iotyp != IO_BID)
1339           emit_varunused_informs(np, (struct task_t *) NULL);
1340         }
1341        set_optim_nflds(np);
1342        rt_change_rngrep(np);
1343       }
1344     }
1345    /* copy ncomp that are still needed for delay annotation */
1346    /* needed because ncomps allocated and freed in blocks */
1347    for (pi = 0; pi < __inst_mod->mprmnum; pi++)
1348     {
1349      np = &(__inst_mod->mprms[pi]);
1350      oncomp = np->nu.ct;
1351      nncomp = (struct ncomp_t *) __my_malloc(sizeof(struct ncomp_t));
1352      /* expressions not freed and copied will point to right ones */
1353      memcpy(nncomp, oncomp, sizeof(struct ncomp_t));
1354      np->nu.ct = nncomp;
1355     }
1356 
1357    /* AIV 01/19/07 - need to do local params here as well */
1358    for (pi = 0; pi < __inst_mod->mlocprmnum; pi++)
1359     {
1360      np = &(__inst_mod->mlocprms[pi]);
1361      oncomp = np->nu.ct;
1362      nncomp = (struct ncomp_t *) __my_malloc(sizeof(struct ncomp_t));
1363      /* expressions not freed and copied will point to right ones */
1364      memcpy(nncomp, oncomp, sizeof(struct ncomp_t));
1365      np->nu.ct = nncomp;
1366     }
1367 
1368    /* AIV 09/27/06 - do not need copy for local params since */
1369    /* can't be set with SDF label annotate */
1370    __cur_declobj = TASK;
1371    for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
1372     {
1373      if (tskp->trnum == 0) continue;
1374 
1375      for (ni = 0, np = &(tskp->tsk_regs[0]); ni < tskp->trnum; ni++, np++)
1376       {
1377        emit_varunused_informs(np, tskp);
1378 
1379        set_optim_nflds(np);
1380        rt_change_rngrep(np);
1381       }
1382      /* copy ncomp that are still needed for delay annotation */
1383      /* needed because ncomps allocated and freed in blocks */
1384      for (pi = 0; pi < tskp->tprmnum; pi++)
1385       {
1386        np = &(tskp->tsk_prms[pi]);
1387        oncomp = np->nu.ct;
1388        nncomp = (struct ncomp_t *) __my_malloc(sizeof(struct ncomp_t));
1389        /* expressions not freed and copied will point to right ones */
1390        memcpy(nncomp, oncomp, sizeof(struct ncomp_t ));
1391        np->nu.ct = nncomp;
1392       }
1393      /* AIV 01/19/07 - need to do local params here as well */
1394      for (pi = 0; pi < tskp->tlocprmnum; pi++)
1395       {
1396        np = &(tskp->tsk_locprms[pi]);
1397        oncomp = np->nu.ct;
1398        nncomp = (struct ncomp_t *) __my_malloc(sizeof(struct ncomp_t));
1399        /* expressions not freed and copied will point to right ones */
1400        memcpy(nncomp, oncomp, sizeof(struct ncomp_t ));
1401        np->nu.ct = nncomp;
1402       }
1403     }
1404    if (__inst_mod->mspfy != NULL)
1405     {
1406      __cur_declobj = SPECIFY;
1407      for (pi = 0; pi < __inst_mod->mspfy->sprmnum; pi++)
1408       {
1409        np = &(__inst_mod->mspfy->msprms[pi]);
1410        oncomp = np->nu.ct;
1411        nncomp = (struct ncomp_t *) __my_malloc(sizeof(struct ncomp_t));
1412        /* expressions not freed and copied will point to right ones */
1413        memcpy(nncomp, oncomp, sizeof(struct ncomp_t ));
1414        np->nu.ct = nncomp;
1415       }
1416     }
1417    __pop_wrkitstk();
1418   }
1419 
1420  __cur_declobj = sav_declobj;
1421  free_ncablks();
1422 }
1423 
1424 
1425 /*
1426  * copy fields form ncomp into run time net fields
1427  *
1428  * LOOAKTME - think no longer need 2 step setting of optim fields
1429  */
set_optim_nflds(struct net_t * np)1430 static void set_optim_nflds(struct net_t *np)
1431 {
1432  np->frc_assgn_allocated = FALSE;
1433  np->dmpv_in_src = FALSE;
1434  np->monit_in_src = FALSE;
1435  np->n_onrhs = FALSE;
1436  np->n_onlhs = FALSE;
1437 
1438  if (np->nu.ct->frc_assgn_in_src) np->frc_assgn_allocated = TRUE;
1439  if (np->nu.ct->dmpv_in_src) np->dmpv_in_src = TRUE;
1440  if (np->nu.ct->monit_in_src) np->monit_in_src = TRUE;
1441  if (np->nu.ct->n_onrhs) np->n_onrhs = TRUE;
1442  if (np->nu.ct->n_onlhs) np->n_onlhs = TRUE;
1443 }
1444 
1445 
1446 /*
1447  * routine to free all allocated ncmp blks when no longed used at all
1448  *
1449  * this frees all ncomps but param comp previously copied because needed
1450  * for delay annotation
1451  */
free_ncablks(void)1452 static void free_ncablks(void)
1453 {
1454  register struct ncablk_t *ncabp, *ncabp2;
1455 
1456  /* free all ncomp ablks since ncomp form now gone */
1457  for (ncabp = __hdr_ncablks; ncabp != NULL;)
1458   {
1459    ncabp2 = ncabp->ncablknxt;
1460    __my_free((char *) ncabp->ancmps, BIG_ALLOC_SIZE);
1461    __my_free((char *) ncabp, sizeof(struct ncablk_t));
1462    ncabp = ncabp2;
1463   }
1464 }
1465 
1466 /*
1467  * emit any unused inform
1468  * notice this is called just before change to non comp representation
1469  */
emit_varunused_informs(struct net_t * np,struct task_t * tskp)1470 static void emit_varunused_informs(struct net_t *np, struct task_t *tskp)
1471 {
1472  struct ncomp_t *ncmp;
1473  int32 infnum;
1474  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[RECLEN];
1475 
1476  ncmp = np->nu.ct;
1477  if (ncmp->n_onrhs && ncmp->n_onlhs) return;
1478 
1479  if (tskp != NULL)
1480   {
1481    switch ((byte) tskp->tsktyp) {
1482     case Begin: strcpy(s2, "in begin block"); break;
1483     case FORK: strcpy(s2, "in fork block"); break;
1484     case FUNCTION: strcpy(s2, "in function"); break;
1485     case TASK: strcpy(s2, "in task"); break;
1486     default: __case_terr(__FILE__, __LINE__);
1487    }
1488    sprintf(s1, "%s %s in %s", s2, tskp->tsksyp->synam,
1489     __inst_mod->msym->synam);
1490   }
1491  else sprintf(s1, "in module %s", __inst_mod->msym->synam);
1492 
1493  if (np->n_isarr) strcpy(s2, "array"); else __to_wtnam(s2, np);
1494 
1495  if (np->ntyp == N_EVENT)
1496   {
1497    if (!ncmp->n_onrhs && !ncmp->n_onlhs)
1498     { strcpy(s3, "unused"); infnum = 436; }
1499    else if (!ncmp->n_onrhs && ncmp->n_onlhs)
1500     { strcpy(s3, "caused but used in no event control"); infnum = 437; }
1501    else { strcpy(s3, "used in event control but not caused"); infnum = 438; }
1502   }
1503  else
1504   {
1505    if (!ncmp->n_onrhs && !ncmp->n_onlhs) { strcpy(s3, "unused");
1506     infnum = 436; }
1507    else if (!ncmp->n_onrhs && ncmp->n_onlhs)
1508     { strcpy(s3, "set but not accessed"); infnum = 437; }
1509    else { strcpy(s3, "accessed but not set"); infnum = 438; }
1510   }
1511 
1512  /* if completely unreferenced normal inform */
1513  if (np->iotyp == NON_IO || infnum == 436)
1514   {
1515    __gfinform(infnum, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1516     "%s: %s %s %s", s1, s2, np->nsym->synam, s3);
1517   }
1518  else
1519   {
1520    if (infnum == 437) infnum = 467;
1521    else if (infnum == 438) infnum = 468;
1522    else __case_terr(__FILE__, __LINE__);
1523 
1524    __gfinform(infnum, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1525     "%s: %s %s %s %s", s1, __to_ptnam(s4, np->iotyp), s2, np->nsym->synam,
1526     s3);
1527   }
1528 }
1529 
1530 /*
1531  * change auxiliary nx from compile to run time (numbers) form
1532  * only for wires (and regs)
1533  *
1534  * notice this is place nwid set
1535  * also after here ncomps gone
1536  */
rt_change_rngrep(struct net_t * np)1537 static void rt_change_rngrep(struct net_t *np)
1538 {
1539  register int32 bi;
1540  int32 nni1, nni2, nai1, nai2, bits;
1541  struct ncomp_t *ncmp;
1542  struct rngarr_t *rap;
1543  struct rngdwir_t *rdwp;
1544  struct gate_t gwrk;
1545  struct rngwir_t *rwp;
1546 
1547  /* in XL parameters can be regs at run time */
1548  /* not legal in standard so must catch before here */
1549  /* DBG remove --- */
1550  if (np->n_isaparam || np->nrngrep != NX_CT)
1551   __arg_terr(__FILE__, __LINE__);
1552  /* -- */
1553 
1554  ncmp = np->nu.ct;
1555 
1556 
1557  /* know this is number since range */
1558  if (np->n_isavec)
1559   {
1560    nni1 = (int32) __contab[ncmp->nx1->ru.xvi];
1561    nni2 = (int32) __contab[ncmp->nx2->ru.xvi];
1562 
1563    if (nni1 == -1 || nni2 == -2) __arg_terr(__FILE__, __LINE__);
1564    np->nwid = ((nni1 >= nni2) ? (nni1 - nni2 + 1) : (nni2 - nni1 + 1));
1565    /* need to handle options that set default splitting state */
1566    switch (ncmp->n_spltstate) {
1567     case SPLT_DFLT:
1568      np->vec_scalared = (__no_expand) ? FALSE : TRUE;
1569      break;
1570     case SPLT_SCAL: np->vec_scalared = TRUE; break;
1571     case SPLT_VECT: np->vec_scalared = FALSE; break;
1572     default: __case_terr(__FILE__, __LINE__);
1573    }
1574   }
1575  /* scalar wire has vec scalared off since 1 bit treated as entity */
1576  else { np->vec_scalared = FALSE; np->nwid = 1; nni1 = nni2 = 0; }
1577 
1578  /* registers and arrays always vectored (non split into bits) */
1579  if (np->ntyp >= NONWIRE_ST) np->vec_scalared = FALSE;
1580  else
1581   {
1582    if (np->n_stren && np->n_isavec && !np->vec_scalared)
1583     {
1584      __gferr(982, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1585       "non scalar strength wire %s cannot be vectored", np->nsym->synam);
1586     }
1587   }
1588 
1589  if (np->n_isarr)
1590   {
1591    nai1 = (int32) __contab[ncmp->ax1->ru.xvi];
1592    nai2 = (int32) __contab[ncmp->ax2->ru.xvi];
1593 
1594    rap = (struct rngarr_t *) __my_malloc(sizeof(struct rngarr_t));
1595    rap->ni1 = nni1;
1596    rap->ni2 = nni2;
1597    rap->ai1 = nai1;
1598    rap->ai2 = nai2;
1599    np->nu.rngarr = rap;
1600    np->nrngrep = NX_ARR;
1601   }
1602  else if (ncmp->n_dels_u.pdels != NULL || np->n_isapthdst)
1603   {
1604    /* path dest. can not have delays */
1605    /* if has delay and path dest., turn off dst. to cause later error */
1606    if (ncmp->n_dels_u.pdels != NULL)
1607     { if (np->n_isapthdst) np->n_isapthdst = FALSE; }
1608 
1609    rdwp = (struct rngdwir_t *) __my_malloc(sizeof(struct rngdwir_t));
1610    rdwp->ni1 = nni1;
1611    rdwp->ni2 = nni2;
1612 
1613    if (!np->n_isapthdst)
1614     {
1615      /* add any defparams (or spec but impossible) to param np list */
1616      add_netdel_pnp(np, np->nu.ct->n_dels_u.pdels);
1617      /* preprocess wire delays into indexable array or value */
1618      __prep_delay(&gwrk, np->nu.ct->n_dels_u.pdels, FALSE,
1619       (np->ntyp == N_TRIREG), "path delay", TRUE, np->nsym, FALSE);
1620 
1621      if (__nd_neg_del_warn)
1622       {
1623        __gferr(971, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
1624         "wire %s delay negative (0 used)", np->nsym->synam);
1625        __nd_neg_del_warn = FALSE;
1626       }
1627 
1628      rdwp->n_delrep = gwrk.g_delrep;
1629      /* is union assign portable */
1630      rdwp->n_du = gwrk.g_du;
1631     }
1632    /* this is allocated and filled later */
1633    else { rdwp->n_delrep = DT_PTHDST; rdwp->n_du.pb_pthdst = NULL; }
1634 
1635    /* must allocate the per bit pending scheduled value */
1636    bits = __inst_mod->flatinum*np->nwid;
1637    rdwp->wschd_pbtevs = (i_tev_ndx *) __my_malloc(bits*sizeof(i_tev_ndx));
1638    for (bi = 0; bi < bits; bi++) rdwp->wschd_pbtevs[bi] = -1;
1639    np->nu.rngdwir = rdwp;
1640    np->nrngrep = NX_DWIR;
1641   }
1642  else
1643   {
1644    /* finally any other wire */
1645    if (np->n_isavec)
1646     {
1647      rwp = (struct rngwir_t *) __my_malloc(sizeof(struct rngwir_t));
1648      rwp->ni1 = nni1;
1649      rwp->ni2 = nni2;
1650      np->nu.rngwir = rwp;
1651      np->nrngrep = NX_WIR;
1652     }
1653    else { np->nu.rngwir = NULL; np->nrngrep = NX_SCALWIR; }
1654   }
1655  /* just free the expressions since if arg. nil does nothing */
1656  __free_xtree(ncmp->nx1);
1657  __free_xtree(ncmp->nx2);
1658  __free_xtree(ncmp->ax1);
1659  __free_xtree(ncmp->ax2);
1660 }
1661 
1662 /*
1663  * ROUTINES TO ALLOCATE AND INITIALIZE GATE INTERNAL STATE
1664  */
1665 
1666 /*
1667  *
1668  * build the schedule array and gate state value for each gate
1669  * also prepares delays
1670  */
bld_gstate(void)1671 static void bld_gstate(void)
1672 {
1673  register int32 gi;
1674  struct mod_t *mdp;
1675  struct gate_t *gp;
1676 
1677  /* for each module in design */
1678  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1679   {
1680    __push_wrkitstk(mdp, 0);
1681 
1682    for (gi = 0; gi < mdp->mgnum; gi++)
1683     {
1684      gp = &(mdp->mgates[gi]);
1685 
1686      /* pull gate (really source) has no state or scheduled events */
1687      /* no state for trans */
1688      if (gp->g_class == GC_PULL || gp->g_class == GC_TRAN) continue;
1689 
1690      /* if output unc. (OPEMPTY), changes are not seen (do not propagate) */
1691      if (gp->g_class != GC_TRANIF && gp->gpins[0]->optyp == OPEMPTY)
1692       continue;
1693 
1694      if (gp->g_du.pdels == NULL)
1695       { gp->g_du.d1v = NULL; gp->g_delrep = DT_NONE; }
1696      else
1697       {
1698        add_gatedel_pnp(gp, gp->g_du.pdels);
1699        __prep_delay(gp, gp->g_du.pdels, FALSE, FALSE, "primitive delay",
1700         FALSE, gp->gsym, FALSE);
1701        if (__nd_neg_del_warn)
1702         {
1703          __gferr(972, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
1704           "gate %s delay negative (0 used)", gp->gsym->synam);
1705          __nd_neg_del_warn = FALSE;
1706         }
1707       }
1708      /* remove #0 if special option on - annotation may put back */
1709      if (__rm_gate_pnd0s)
1710       {
1711        if (__chk_0del(gp->g_delrep, gp->g_du, mdp) == DBAD_0)
1712         {
1713          __num_rem_gate_pnd0s++;
1714          __num_flat_rem_gate_pnd0s += mdp->flatinum;
1715          __free_del(gp->g_du, gp->g_delrep, mdp->flatinum);
1716          gp->g_du.d1v = NULL;
1717          gp->g_delrep = DT_NONE;
1718         }
1719       }
1720      /* only gates have gstate, eval. for conta (can be func. on rhs) */
1721      alloc_gstate(gp, mdp->flatinum);
1722     }
1723    __pop_wrkitstk();
1724   }
1725 }
1726 
1727 /*
1728  * allocate per instance gstate or usate and intialize to x
1729  */
alloc_gstate(struct gate_t * gp,int32 insts)1730 static void alloc_gstate(struct gate_t *gp, int32 insts)
1731 {
1732  register int32 gsi;
1733  int32 nbytes;
1734 
1735  /* first allocate and NULL per instantiating module schedule event ptrs */
1736  /* only allocate inertial schedule array if has delay (includes #0) */
1737  if (gp->g_delrep != DT_NONE)
1738   {
1739    nbytes = insts*sizeof(i_tev_ndx);
1740    gp->schd_tevs = (i_tev_ndx *) __my_malloc(nbytes);
1741    for (gsi = 0; gsi < insts; gsi++) gp->schd_tevs[gsi] = -1;
1742   }
1743 
1744  /* no state for continuous assign */
1745  if (gp->g_class != GC_UDP) __set_init_gstate(gp, insts, TRUE);
1746  else __set_init_udpstate(gp, insts, TRUE);
1747 }
1748 
1749 /* SJM 12/16/99 - notices packing only into words does not change this */
1750 /* mask table for <= 16 bit wide pck elements (1,z,x) - 0 just all 0's */
1751 /* 0 width impossible and never used for scalar */
1752 /* SJM 07/15/00- only for gates since variables no longer packed */
1753 word32 __pack_imaskx[17] = {
1754  0L, 0x3L, 0xfL, 0x3fL, 0xffL, 0x03ff, 0x0fffL, 0x3fffL, 0xffffL,
1755  0x3ffffL, 0xfffffL, 0x3fffffL, 0xffffffL, 0x3ffffffL, 0xfffffffL,
1756  0x3fffffffL, ALL1W
1757 };
1758 
1759 /* what is this value of 16 bit should 1 not 8 1's ? */
1760 word32 __pack_imask1[17] = {
1761  0L, 0x1L, 0x3L, 0x07L, 0x0fL, 0x001fL, 0x003fL, 0x007fL, 0x00ffL,
1762  0x01ffL, 0x03ffL, 0x07ffL, 0x0fffL, 0x1fffL, 0x03fffL, 0x7fffL, 0xffffL
1763 };
1764 
1765 word32 __pack_imaskz[17] = {
1766  0L, 0x2L, 0xcL, 0x38L, 0xf0L, 0x03e0L, 0x0fc0L ,0x3f80L, 0xff00L,
1767  0x3fe00L, 0xffc00L, 0x3ff800L, 0xfff000L, 0x3ffe000L, 0xfffc000L,
1768  0x3fff8000L, 0xffff0000L
1769 };
1770 
1771 /*
1772  * set initial state for builtin gate
1773  *
1774  * LOOKATME - SJM 12/19/99 maybe should also only pck into word32 here but
1775  * wastes lotsof storage for 4 state gates
1776  */
__set_init_gstate(struct gate_t * gp,int32 insts,int32 nd_alloc)1777 extern void __set_init_gstate(struct gate_t *gp, int32 insts, int32 nd_alloc)
1778 {
1779  register int32 i;
1780  register word32 *wp;
1781  register hword *hwp;
1782  register byte *bp;
1783  int32 pnum, wlen;
1784  word32 maska;
1785 
1786  switch ((byte) gp->g_class) {
1787   case GC_LOGIC:
1788    pnum = gp->gpnum;
1789    if (pnum > 16)
1790     {
1791      wlen = wlen_(pnum);
1792      if (nd_alloc)
1793       gp->gstate.wp = (word32 *) __my_malloc(2*WRDBYTES*insts*wlen);
1794      __init_vec_var(gp->gstate.wp, insts, wlen, pnum, ALL1W, ALL1W);
1795      break;
1796     }
1797    /* case 1, fits in 8 bits */
1798    maska = __pack_imaskx[pnum];
1799    if (pnum <= 4)
1800     {
1801      if (nd_alloc) gp->gstate.bp = (byte *) __my_malloc(insts);
1802      bp = gp->gstate.bp;
1803      for (i = 0; i < insts; i++) bp[i] = (byte) maska;
1804     }
1805    else if (pnum <= 8)
1806     {
1807      if (nd_alloc) gp->gstate.hwp = (hword *) __my_malloc(2*insts);
1808      hwp = gp->gstate.hwp;
1809      for (i = 0; i < insts; i++) hwp[i] = (hword) maska;
1810     }
1811    else
1812     {
1813      if (nd_alloc) gp->gstate.wp = (word32 *) __my_malloc(WRDBYTES*insts);
1814      wp = gp->gstate.wp;
1815      for (i = 0; i < insts; i++) wp[i] = maska;
1816     }
1817    break;
1818   case GC_BUFIF:
1819    if (nd_alloc) gp->gstate.hwp = (hword *) __my_malloc(2*insts);
1820    /* this starts by driving given strength x (if no expl. <st1:st0>= x) */
1821    hwp = gp->gstate.hwp;
1822    for (i = 0; i < insts; i++) hwp[i] = (hword) (0x3f | (gp->g_stval << 6));
1823    break;
1824   case GC_MOS:
1825    if (nd_alloc) gp->gstate.wp = (word32 *) __my_malloc(WRDBYTES*insts);
1826    wp = gp->gstate.wp;
1827    /* pattern here in highz in, control x, and high z out */
1828    for (i = 0; i < insts; i++) wp[i] = 0x00020302L;
1829    break;
1830   case GC_CMOS:
1831    if (nd_alloc) gp->gstate.wp = (word32 *) __my_malloc(WRDBYTES*insts);
1832    /* pattern here in highz in, controls both x, and high z out */
1833    wp = gp->gstate.wp;
1834    for (i = 0; i < insts; i++) wp[i] = 0x02030302L;
1835    return;
1836   case GC_TRANIF:
1837    /* tranif states are 2 bit - 1 conducting, 0 no conducting, 3 unknown */
1838    /* notice for delay case, schedule in tev */
1839    wlen = wlen_(2*insts);
1840    if (nd_alloc) gp->gstate.wp = (word32 *) __my_malloc(WRDBYTES*wlen);
1841    wp = gp->gstate.wp;
1842    /* start with tranif gates in unknown conducting state */
1843    for (i = 0; i < wlen; i++) wp[i] = 0xffffffffL;
1844    wp[wlen - 1] &= __masktab[ubits_(2*insts)];
1845    return;
1846   default: __case_terr(__FILE__, __LINE__);
1847  }
1848 }
1849 
1850 /*
1851  * set initial state for udp
1852  * for udps >6 also need 1 word32 per inst. for current table index value
1853  *
1854  * notice value is stored as x (3) - but indexing uses 2 for nins > 6
1855  * conversions from normal 4 value to 3 value made when indexing
1856  *
1857  * ustate values are stored as n 2 bit scalars not separate a and b parts
1858  * since no need for reduction word32 evaluation operations
1859  */
__set_init_udpstate(struct gate_t * gp,int32 insts,int32 nd_alloc)1860 extern void __set_init_udpstate(struct gate_t *gp, int32 insts,
1861  int32 nd_alloc)
1862 {
1863  register int32 gsi;
1864  register word32 *wp;
1865  register hword *hwp;
1866  int32 nins;
1867  word32 iwval, indval;
1868  struct udp_t *udpp;
1869 
1870  udpp = gp->gmsym->el.eudpp;
1871  /* notice nins is total number of input pins: (state not included) */
1872  nins = udpp->numins;
1873  /* assume initial value x - notice inputs plus 1 output no pending  */
1874  iwval = __masktab[2*nins + 2];
1875  /* initialize to x here - if initial value assign instead of normal eval */
1876  if (udpp->u_wide)
1877   {
1878    /* 2 words for each superposition form udp */
1879    if (nd_alloc) gp->gstate.wp = (word32 *) __my_malloc(2*WRDBYTES*insts);
1880    wp = gp->gstate.wp;
1881    for (gsi = 0; gsi < insts; gsi++)
1882     {
1883      wp[2*gsi] = iwval;
1884      indval = cmp_udpind(iwval, udpp->numstates);
1885      wp[2*gsi + 1] = indval;
1886      /* --- RELEASE remove
1887      if (__debug_flg)
1888       __dbg_msg("++ wide udp init (inst %d): w0=%lx, w1=%lx\n",
1889        gsi, wp[2*gsi], wp[2*gsi + 1]);
1890      --- */
1891     }
1892   }
1893  else
1894   {
1895    /* also store signature form udp in half word32 - 2 bit udp pointless */
1896    if (nd_alloc) gp->gstate.hwp = (hword *) __my_malloc(2*insts);
1897    hwp = gp->gstate.hwp;
1898    /* -- RELEASE remove
1899    if (__debug_flg)
1900     __dbg_msg("-- narrow udp init: initial state h=%x\n", (hword) iwval);
1901    -- */
1902    for (gsi = 0; gsi < insts; gsi++) hwp[gsi] = (hword) iwval;
1903   }
1904 }
1905 
1906 /*
1907  * eval input state (including possible previous state) to get table index
1908  * for initialization only since normally must use transition to select tab
1909  *
1910  * assuming here that 30 bit and 2 bit shifts take same time
1911  */
cmp_udpind(word32 ustate,word32 nstates)1912 static word32 cmp_udpind(word32 ustate, word32 nstates)
1913 {
1914  register word32 ui;
1915 
1916  word32 ind;
1917  word32 ival;
1918 
1919  /* know ustate has proper initialized state */
1920  /* notice here need to use state that may have been initialized */
1921  for (ind = 0, ui = 0; ui < nstates; ui++)
1922   {
1923    ival = (ustate >> ui) & 3L;
1924    /* input x converted to udp x (2) to index - z is x and left as is */
1925    if (ival == 3) ival = 2;
1926    ind += ival*__pow3tab[ui];
1927   }
1928  return(ind);
1929 }
1930 /*
1931  * prep conta delays
1932  *
1933  * SJM 09/28/02 - even for rhs concat PB separated, delay in master
1934  */
prep_conta_dels(void)1935 static void prep_conta_dels(void)
1936 {
1937  register struct mod_t *mdp;
1938  register struct conta_t *cap;
1939  int32 cai;
1940  struct gate_t gwrk;
1941 
1942  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1943   {
1944    __push_wrkitstk(mdp, 0);
1945 
1946    for (cap = &(mdp->mcas[0]), cai = 0; cai < mdp->mcanum; cai++, cap++)
1947     {
1948      /* 1 bit lhs conta delays like gate delays - 3rd arg determines */
1949      if (cap->ca_du.pdels == NULL)
1950       { cap->ca_du.d1v = NULL; cap->ca_delrep = DT_NONE; }
1951      else
1952       {
1953        add_contadel_pnp(cap, cap->ca_du.pdels);
1954        __prep_delay(&gwrk, cap->ca_du.pdels, FALSE, FALSE,
1955         "continuous assignment delay", FALSE, cap->casym, FALSE);
1956        if (__nd_neg_del_warn)
1957         {
1958          __gferr(973, cap->casym->syfnam_ind, cap->casym->sylin_cnt,
1959           "continuous assign delay negative (0 used)");
1960          __nd_neg_del_warn = FALSE;
1961         }
1962        cap->ca_du = gwrk.g_du;
1963        cap->ca_delrep = gwrk.g_delrep;
1964        /* SJM 09/28/02 - now set ca 4v del during fixup */
1965       }
1966     }
1967    __pop_wrkitstk();
1968   }
1969 }
1970 
1971 /*
1972  * ROUTINES TO BUILD PER BIT INPUT PORT ICONN PINS, MOD PORTS, and CONCATS
1973  */
1974 
1975 /*
1976  * bld the separated per bit iconn rhs net pins for one iconn
1977  *
1978  * notice building one PB for every down mod port bit - if highconn inst
1979  * conn wider nothing to change if and mod port wider unc. no value
1980  * since pb not used for initialization
1981  */
bld_pbsep_input_mpps(void)1982 static void bld_pbsep_input_mpps(void)
1983 {
1984  register int32 pi, bi;
1985  register struct mod_t *mdp;
1986  int32 ii, pi2, numpins, ptyp;
1987  struct mod_t *imdp;
1988  struct mod_pin_t *mpp;
1989  struct inst_t *ip;
1990  struct expr_t *xp, *xp2;
1991  struct pbexpr_t *pbexpr;
1992 
1993  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
1994   {
1995    __push_wrkitstk(mdp, 0);
1996 
1997    /* first process all instances in module */
1998    for (ii = 0; ii < mdp->minum; ii++)
1999     {
2000      ip = &(mdp->minsts[ii]);
2001      imdp = ip->imsym->el.emdp;
2002      if ((numpins = imdp->mpnum) == 0) continue;
2003 
2004      for (pi = 0; pi < numpins; pi++)
2005       {
2006        mpp = &(imdp->mpins[pi]);
2007        xp = ip->ipins[pi];
2008        ptyp = mpp->mptyp;
2009        if (ptyp != IO_IN) continue;
2010        /* notice decl lhs always separable but no separate unless hconn cat */
2011        if (!rhs_cat_separable(xp)) continue;
2012 
2013        if (ip->pb_ipins_tab == NULL)
2014         {
2015          ip->pb_ipins_tab = (struct expr_t ***)
2016           __my_malloc(numpins*sizeof(struct expr_t **));
2017          for (pi2 = 0; pi2 < numpins; pi2++) ip->pb_ipins_tab[pi2] = NULL;
2018         }
2019        /* all bits filled below */
2020        ip->pb_ipins_tab[pi] = (struct expr_t **)
2021         __my_malloc(mpp->mpwide*sizeof(struct expr_t *));
2022 
2023        pbexpr = bld_pb_expr_map(xp, mpp->mpwide);
2024        for (bi = 0; bi < mpp->mpwide; bi++)
2025         {
2026          /* for unc. (lhs wider) builds the constant rhs 0/z */
2027          xp2 = bld_1sep_pbit_expr(&(pbexpr[bi]), xp->x_stren);
2028          ip->pb_ipins_tab[pi][bi] = xp2;
2029         }
2030        __my_free((char *) pbexpr, numpins*sizeof(struct pbexpr_t));
2031 
2032        /* T means at least one highconn iconn is per bit concat */
2033        mpp->has_scalar_mpps = TRUE;
2034       }
2035     }
2036    __pop_wrkitstk();
2037   }
2038 
2039  /* always build separated per bit mpps if any hconn separable concat */
2040  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2041   {
2042    __push_wrkitstk(mdp, 0);
2043 
2044    numpins = mdp->mpnum;
2045    for (pi = 0; pi < numpins; pi++)
2046     {
2047      mpp = &(mdp->mpins[pi]);
2048      ptyp = mpp->mptyp;
2049      if (ptyp != IO_IN) continue;
2050      if (!mpp->has_scalar_mpps) continue;
2051      bld_pb_mpps(mpp);
2052     }
2053    __pop_wrkitstk();
2054   }
2055 }
2056 
2057 /*
2058  * bld the separated per bit output mod port lhs net pins for one iconn
2059  *
2060  * this is symmetric case to bld per bit separable mpps and and iconn
2061  * pb ipins tabs for output but here as long as all highconns for port
2062  * can be separated into bits will separate if any low conn or high concats
2063  *
2064  * can only build PB records for output ports if all iconn widths exactly
2065  * same as mod port width
2066  */
bld_pbsep_output_mpps(void)2067 static void bld_pbsep_output_mpps(void)
2068 {
2069  register int32 pi, bi;
2070  register struct mod_t *mdp;
2071  int32 ii, pi2, numpins, ptyp;
2072  struct mod_t *imdp;
2073  struct mod_pin_t *mpp;
2074  struct inst_t *ip;
2075  struct expr_t *xp, *xp2;
2076  struct pbexpr_t *pbexpr;
2077 
2078  if (!output_pb_separable()) return;
2079 
2080  /* first bld per bit ipins tab for output port lhs separable highconns */
2081  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2082   {
2083    __push_wrkitstk(mdp, 0);
2084 
2085    /* process all instances in module */
2086    for (ii = 0; ii < mdp->minum; ii++)
2087     {
2088      ip = &(mdp->minsts[ii]);
2089      imdp = ip->imsym->el.emdp;
2090      if ((numpins = imdp->mpnum) == 0) continue;
2091 
2092      for (pi = 0; pi < numpins; pi++)
2093       {
2094        mpp = &(imdp->mpins[pi]);
2095        ptyp = mpp->mptyp;
2096        if (ptyp != IO_OUT) continue;
2097        if (!mpp->has_scalar_mpps) continue;
2098        xp = ip->ipins[pi];
2099 
2100        if (ip->pb_ipins_tab == NULL)
2101         {
2102          ip->pb_ipins_tab = (struct expr_t ***)
2103           __my_malloc(numpins*sizeof(struct expr_t **));
2104          for (pi2 = 0; pi2 < numpins; pi2++) ip->pb_ipins_tab[pi2] = NULL;
2105         }
2106        /* all bits filled below - know lhs iconn and rhs mpp same width */
2107        ip->pb_ipins_tab[pi] = (struct expr_t **)
2108         __my_malloc(mpp->mpwide*sizeof(struct expr_t *));
2109 
2110        pbexpr = bld_pb_expr_map(xp, mpp->mpwide);
2111        for (bi = 0; bi < mpp->mpwide; bi++)
2112         {
2113          xp2 = bld_1sep_pbit_expr(&(pbexpr[bi]), xp->x_stren);
2114          ip->pb_ipins_tab[pi][bi] = xp2;
2115         }
2116        __my_free((char *) pbexpr, numpins*sizeof(struct pbexpr_t));
2117       }
2118     }
2119    __pop_wrkitstk();
2120   }
2121 
2122  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2123   {
2124    __push_wrkitstk(mdp, 0);
2125 
2126    numpins = mdp->mpnum;
2127    for (pi = 0; pi < numpins; pi++)
2128     {
2129      mpp = &(mdp->mpins[pi]);
2130      ptyp = mpp->mptyp;
2131      if (ptyp != IO_IN) continue;
2132      if (!mpp->has_scalar_mpps) continue;
2133      bld_pb_mpps(mpp);
2134     }
2135    __pop_wrkitstk();
2136   }
2137 }
2138 
2139 /*
2140  * mark each mod output port that can be and gains from separate into PB form
2141  * return T if some ports can be separated into PB form
2142  *
2143  * separable only if more than half total highconn inst connections separble
2144  * and concats not too narrow only counted
2145  */
output_pb_separable(void)2146 static int32 output_pb_separable(void)
2147 {
2148  register int32 pi, ii;
2149  register struct mod_t *mdp;
2150  register struct mod_pin_t *mpp;
2151  int32 numpins, nels, num_cat_insts, not_pbsep, some_pbsep;
2152  struct itree_t *down_itp;
2153  struct expr_t *up_lhsx;
2154 
2155  /* first go through and make sure all high conns can be separated into pb */
2156  some_pbsep = FALSE;
2157  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2158   {
2159    /* SJM 11/19/02 - if top level mod, never separable since no highconn */
2160    if (mdp->minstnum == 0) continue;
2161 
2162    if ((numpins = mdp->mpnum) == 0) continue;
2163    __push_wrkitstk(mdp, 0);
2164    for (pi = 0; pi < numpins; pi++)
2165     {
2166      mpp = &(mdp->mpins[pi]);
2167      if (mpp->mptyp != IO_OUT) continue;
2168 
2169 
2170      /* if down rhs lowconn mod port not separable, can't PB separate any */
2171      if (!rhs_modpin_separable(mpp->mpref)) continue;
2172 
2173      num_cat_insts = 0;
2174      not_pbsep = FALSE;
2175      for (ii = 0; ii < mdp->flatinum; ii++)
2176       {
2177        down_itp = mdp->moditps[ii];
2178        /* LOOKATME - is nil here possible? */
2179        up_lhsx = down_itp->itip->ipins[pi];
2180        if (up_lhsx->optyp != LCB) continue;
2181 
2182        /* if any width differences, can't separate */
2183        /* LOOKATME - is this really required? */
2184        if (mpp->mpref->szu.xclen != up_lhsx->szu.xclen)
2185         { not_pbsep = TRUE; break; }
2186 
2187        nels = __cnt_cat_size(up_lhsx);
2188        /* only gain from separate if 4 or more els and wider than 4 bits */
2189        /* LOOKATME - if many wide per bit maybe not better */
2190        if (nels < 4 || up_lhsx->szu.xclen < 4) continue;
2191        num_cat_insts++;
2192       }
2193      if (num_cat_insts/2 < mdp->flatinum) not_pbsep = TRUE;
2194      if (!not_pbsep)
2195       {
2196        some_pbsep = TRUE;
2197        mpp->has_scalar_mpps = TRUE;
2198       }
2199     }
2200    __pop_wrkitstk();
2201   }
2202  return(some_pbsep);
2203 }
2204 
2205 /*
2206  * build per bit mpps for simulation
2207  */
bld_pb_mpps(struct mod_pin_t * mpp)2208 static void bld_pb_mpps(struct mod_pin_t *mpp)
2209 {
2210  register int32 bi;
2211  register struct mod_pin_t *mpp2;
2212  struct expr_t *xp;
2213  struct pbexpr_t *pbexpr;
2214 
2215  xp = mpp->mpref;
2216  pbexpr = bld_pb_expr_map(xp, mpp->mpwide);
2217  mpp->pbmpps = (struct mod_pin_t *)
2218   __my_malloc(mpp->mpwide*sizeof(struct mod_pin_t));
2219  for (bi = 0; bi < mpp->mpwide; bi++)
2220   {
2221    /* fields except for per bit same */
2222    mpp->pbmpps[bi] = *mpp;
2223    mpp2 = &(mpp->pbmpps[bi]);
2224    /* since expr copied for ID/XMR part, stren and other bits set right */
2225    xp = bld_1sep_pbit_expr(&(pbexpr[bi]), mpp2->mpref->x_stren);
2226    mpp2->mpref = xp;
2227    mpp2->mpwide = 1;
2228    mpp2->pbmpps = NULL;
2229    mpp2->has_scalar_mpps = FALSE;
2230   }
2231  __my_free((char *) pbexpr, mpp->mpwide*sizeof(struct pbexpr_t));
2232 }
2233 
2234 /*
2235  * bld the separated per bit rhs concat - stored in non pb concat
2236  */
bld_pb_contas(void)2237 static void bld_pb_contas(void)
2238 {
2239  register int32 bi;
2240  register struct mod_t *mdp;
2241  int32 cawid, cai;
2242  struct conta_t *cap, *pbcap;
2243  struct expr_t *lhsx, *xp2, *xp3;
2244  struct pbexpr_t *rhs_pbexpr, *lhs_pbexpr;
2245 
2246  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2247   {
2248    __push_wrkitstk(mdp, 0);
2249 
2250    for (cap = &(mdp->mcas[0]), cai = 0; cai < mdp->mcanum; cai++, cap++)
2251     {
2252      /* if not concat expr, should not separate so this returns F */
2253      if (!rhs_cat_separable(cap->rhsx)) continue;
2254 
2255      /* SJM 09/28/02 - now always use per bit for rhs concat */
2256      /* fi>1 works and may allow per bit driver load and 4v delay works */
2257      /* because evaluates all bits of rhs during sim */
2258      lhsx = cap->lhsx;
2259      cawid = lhsx->szu.xclen;
2260      cap->ca_pb_sim = TRUE;
2261      cap->pbcau.pbcaps = (struct conta_t *)
2262       __my_malloc(cawid*sizeof(struct conta_t));
2263      for (bi = 0; bi < cawid; bi++)
2264       {
2265        cap->pbcau.pbcaps[bi] = *cap;
2266        pbcap = &(cap->pbcau.pbcaps[bi]);
2267        /* SJM 08/28/02 - sym and delays in mast not per bit */
2268        pbcap->casym = NULL;
2269        pbcap->ca_du.pdels = NULL;
2270        pbcap->ca_pb_sim = FALSE;
2271        pbcap->ca_pb_el = TRUE;
2272        pbcap->pbcau.mast_cap = cap;
2273       }
2274 
2275      rhs_pbexpr = bld_pb_expr_map(cap->rhsx, cawid);
2276      lhs_pbexpr = bld_pb_expr_map(lhsx, cawid);
2277      for (bi = 0; bi < cawid; bi++)
2278       {
2279        pbcap = &(cap->pbcau.pbcaps[bi]);
2280        /* if lhs too narrow, 0/z determened by whether lhs stren */
2281        xp2 = bld_1sep_pbit_expr(&(rhs_pbexpr[bi]), lhsx->x_stren);
2282        pbcap->rhsx = xp2;
2283 
2284        xp3 = bld_1sep_pbit_expr(&(lhs_pbexpr[bi]), lhsx->x_stren);
2285        pbcap->lhsx = xp3;
2286        if (cap->lhsx->x_multfi) pbcap->lhsx->x_multfi = TRUE;
2287       }
2288      __my_free((char *) rhs_pbexpr, cawid*sizeof(struct pbexpr_t));
2289      __my_free((char *) lhs_pbexpr, cawid*sizeof(struct pbexpr_t));
2290     }
2291    __pop_wrkitstk();
2292   }
2293 }
2294 
2295 /*
2296  * return T if separable into per bit rhs concat
2297  * now called with any expr
2298  *
2299  * all elements must be simple
2300  * think width self determined exps legal in cats but can't per bit separate
2301  */
rhs_cat_separable(struct expr_t * rhsx)2302 static int32 rhs_cat_separable(struct expr_t *rhsx)
2303 {
2304  register struct expr_t *catndp;
2305  struct net_t *np;
2306 
2307  if (rhsx->optyp != LCB) return(FALSE);
2308  /* if only one element in rhs concat - no optimize */
2309  if (rhsx->ru.x->ru.x == NULL) return(FALSE);
2310 
2311  for (catndp = rhsx->ru.x; catndp != NULL; catndp = catndp->ru.x)
2312   {
2313    switch (catndp->lu.x->optyp) {
2314     case ID: case GLBREF:
2315      np = catndp->lu.x->lu.sy->el.enp;
2316      if (!np->vec_scalared) return(FALSE);
2317      break;
2318     case PARTSEL:
2319      np = catndp->lu.x->lu.x->lu.sy->el.enp;
2320      if (!np->vec_scalared) return(FALSE);
2321      break;
2322     case LSB:
2323      /* SJM 12/17/02 - old vectored keyword also prevents pb separation */
2324      np = catndp->lu.x->lu.x->lu.sy->el.enp;
2325      if (np->n_isarr || !np->vec_scalared)
2326       return(FALSE);
2327      /* SJM 03/03/07 - bit select inside concat must be constant bsel */
2328      if (!__is_const_expr(catndp->lu.x->ru.x)) return(FALSE);
2329      break;
2330     case NUMBER:
2331      break;
2332     default: return(FALSE);
2333    }
2334   }
2335  return(TRUE);
2336 }
2337 
2338 /*
2339  * return T if rhs mod pin separable (can be cat or not)
2340  */
rhs_modpin_separable(struct expr_t * rhsx)2341 static int32 rhs_modpin_separable(struct expr_t *rhsx)
2342 {
2343  struct expr_t *catndp;
2344 
2345  /* 1 bit ports never separable */
2346  switch (rhsx->optyp) {
2347   case ID: case GLBREF:
2348    /* evan regs always separable */
2349    break;
2350   case PARTSEL:
2351    break;
2352   case LSB:
2353    /* bsel not separable if array select */
2354    if (rhsx->lu.x->lu.sy->el.enp->n_isarr) return(FALSE);
2355    break;
2356   case NUMBER:
2357    break;
2358   case LCB:
2359    for (catndp = rhsx->ru.x; catndp != NULL; catndp = catndp->ru.x)
2360     {
2361      if (!rhs_modpin_separable(catndp->lu.x)) return(FALSE);
2362     }
2363   default: return(FALSE);
2364  }
2365  return(TRUE);
2366 }
2367 
2368 /*
2369  * decompose expr into per bit expr record
2370  */
bld_pb_expr_map(struct expr_t * xp,int32 xwid)2371 static struct pbexpr_t *bld_pb_expr_map(struct expr_t *xp, int32 xwid)
2372 {
2373  register int32 bi, bi2;
2374  register struct expr_t *catndp;
2375  int32 nels, xi, xofs, biti, bitj, wi, wlen;
2376  word32 av, bv;
2377  struct expr_t **xtab, *cur_xp, *idndp;
2378  struct pbexpr_t *pbexpr, *pbxp;
2379  struct net_t *np;
2380 
2381  /* make sure both rhs and lhs in low to high order tables */
2382  /* needed because for concat, first in list is high order part */
2383  if (xp->optyp == LCB)
2384   {
2385    nels = __cnt_cat_size(xp);
2386    xtab = (struct expr_t **) __my_malloc(nels*sizeof(struct expr_t *));
2387    xi = nels - 1;
2388    /* fill expr tab in reverse order */
2389    catndp = xp->ru.x;
2390    for (; catndp != NULL; catndp = catndp->ru.x, xi--)
2391     { xtab[xi] = catndp->lu.x; }
2392   }
2393  else
2394   {
2395    xtab = (struct expr_t **) __my_malloc(sizeof(struct expr_t *));
2396    xtab[0] = xp;
2397    nels = 1;
2398   }
2399 
2400  /* size determined by lhs expr */
2401  pbexpr = (struct pbexpr_t *) __my_malloc(xwid*sizeof(struct pbexpr_t));
2402  for (bi = 0; bi < xwid; bi++) init_pbexpr_el(&(pbexpr[bi]));
2403 
2404  /* first fill lhs, then another loop to fill rhs matching */
2405  /* process one lhs expr element every time through */
2406  for (xofs = 0, xi = 0; xi < nels; xi++)
2407   {
2408    cur_xp = xtab[xi];
2409    pbxp = &(pbexpr[xofs]);
2410    /* fill lhs */
2411    switch ((byte) cur_xp->optyp) {
2412     case GLBREF: case ID:
2413      idndp = cur_xp;
2414      np = idndp->lu.sy->el.enp;
2415      /* scalar */
2416      /* lhs bi is offset in object, -1 is entire object such as out of rng */
2417      if (!np->n_isavec)
2418       {
2419        pbxp = &(pbexpr[xofs]);
2420        pbxp->xp = idndp;
2421        pbxp->bi = -1;
2422        /* SJM 05/25/05 - need gt-eq since must stop at xwid not 1 past */
2423        if (++xofs >= xwid) goto done;
2424        break;
2425       }
2426      /* vector */
2427      for (bi2 = 0; bi2 < np->nwid; bi2++)
2428       {
2429        pbxp = &(pbexpr[xofs]);
2430        pbxp->xp = idndp;
2431        /* this is offset in expr */
2432        pbxp->bi = bi2;
2433        if (++xofs >= xwid) goto done;
2434       }
2435      break;
2436     case LSB:
2437      idndp = cur_xp->lu.x;
2438      np = idndp->lu.sy->el.enp;
2439      pbxp->xp = cur_xp;
2440      /* DBG remove */
2441      if (np->n_isarr) __misc_terr(__FILE__, __LINE__);
2442      /* --- */
2443      /* SJM 09/03/02 - IS number legal since scalar decl assigns allow it */
2444      if (cur_xp->ru.x->optyp == ISNUMBER) biti = -2;
2445      else biti = __get_const_bselndx(cur_xp);
2446      /* LOOKATME - think out of rng for const index not possible */
2447      if (biti == -1) pbxp->ndx_outofrng = TRUE;
2448      /* offset is offset in ID/XMR object */
2449      pbxp->bi = biti;
2450      if (++xofs >= xwid) goto done;
2451      break;
2452     case PARTSEL:
2453      idndp = cur_xp->lu.x;
2454      np = idndp->lu.sy->el.enp;
2455      /* know part select never IS */
2456      biti = __contab[cur_xp->ru.x->lu.x->ru.xvi];
2457      bitj = __contab[cur_xp->ru.x->ru.x->ru.xvi];
2458      for (bi2 = bitj; bi2 <= biti; bi2++)
2459       {
2460        pbxp = &(pbexpr[xofs]);
2461        pbxp->xp = idndp;
2462        /* this is offset in expr */
2463        pbxp->bi = bi2;
2464        /* this is offset from low end of concat element */
2465        if (++xofs >= xwid) goto done;
2466       }
2467      break;
2468     case NUMBER:
2469      /* LOOKATME - could include ISNUMBER here if always has inst context */
2470      for (bi = 0; bi < cur_xp->szu.xclen; bi++)
2471       {
2472        pbxp = &(pbexpr[xofs]);
2473        pbxp->xp = cur_xp;
2474        pbxp->rhs_const = TRUE;
2475        /* this is offset in expr */
2476        pbxp->bi = -1;
2477        wlen = wlen_(cur_xp->szu.xclen);
2478        wi = get_wofs_(bi);
2479        bi2 = get_bofs_(bi);
2480        av = (__contab[cur_xp->ru.xvi + wi] >> bi) & 1;
2481        bv = (__contab[cur_xp->ru.xvi + wlen + wi] >> bi) & 1;
2482        pbxp->aval = av;
2483        pbxp->bval = bv;
2484        /* SJM 05/25/05 - if out of lhs - remaining rhs unused so ignore */
2485        if (++xofs >= xwid) goto done;
2486       }
2487      break;
2488     default: __case_terr(__FILE__, __LINE__);
2489    }
2490   }
2491  /* if still more lhs elements - rhs too narrow - this is bit by bit */
2492  for (; xofs < xwid; xofs++)
2493   {
2494    pbxp = &(pbexpr[xofs]);
2495    /* for extra lhs, need z assign if stren else 0 assign */
2496    pbxp->no_rhs_expr = TRUE;
2497    /* LOOKATME - just leaving rhs fields empty for now */
2498   }
2499 
2500 done:
2501  if (xtab != NULL) __my_free((char *) xtab, nels*sizeof(struct expr_t *));
2502  return(pbexpr);
2503 }
2504 
2505 /*
2506  * initialize decomposed into per bit expr 1 bit table entry
2507  */
init_pbexpr_el(struct pbexpr_t * pbxp)2508 static void init_pbexpr_el(struct pbexpr_t *pbxp)
2509 {
2510  pbxp->ndx_outofrng = FALSE;
2511  pbxp->rhs_const = FALSE;
2512  pbxp->no_rhs_expr = FALSE;
2513  pbxp->xp = NULL;
2514  pbxp->bi = -1;
2515  /* initialize to x */
2516  pbxp->aval = 1;
2517  pbxp->bval = 1;
2518 }
2519 
2520 /*
2521  * fill separated per bit assign expr pair table
2522  */
bld_1sep_pbit_expr(struct pbexpr_t * pbxp,int32 is_stren)2523 static struct expr_t *bld_1sep_pbit_expr(struct pbexpr_t *pbxp,
2524  int32 is_stren)
2525 {
2526  struct expr_t *xp;
2527 
2528  /* some special cases */
2529  if (pbxp->ndx_outofrng)
2530   {
2531    xp = __bld_rng_numxpr(1, 1, 1);
2532    xp->ibase = BHEX;
2533    return(xp);
2534   }
2535  if (pbxp->no_rhs_expr)
2536   {
2537    if (is_stren)
2538     {
2539      xp = __bld_rng_numxpr(0, 0, 1);
2540      xp->ibase = BDEC;
2541     }
2542    else
2543     {
2544      /* SJM 06/27/05 - rhs widening - always widen with 0's */
2545      xp = __bld_rng_numxpr(0, 0, 1);
2546      xp->ibase = BHEX;
2547     }
2548    return(xp);
2549   }
2550 
2551  /* lhs bsel or ID/XMR scalar - copy the expr  */
2552  if (pbxp->xp->optyp == LSB ||
2553   ((pbxp->xp->optyp == ID || pbxp->xp->optyp == GLBREF)
2554   && !pbxp->xp->lu.sy->el.enp->n_isavec))
2555   { xp = __copy_expr(pbxp->xp); }
2556  /* rhs number - can never be IS number */
2557  else if (pbxp->xp->optyp == NUMBER)
2558   {
2559    xp = __bld_rng_numxpr(pbxp->aval, pbxp->bval, 1);
2560    xp->ibase = BDEC;
2561   }
2562  /* ID/XMR vector or psel, build bsel expr */
2563  else xp = cnvt_to_bsel_expr(pbxp->xp, pbxp->bi);
2564  return(xp);
2565 }
2566 
2567 /*
2568  * convert id or psel to constant bsel
2569  * passed index must be normalized to h:0 form
2570  *
2571  * LOOKATME - for bsel just copying expression - ignoring various IS
2572  * and out of range conditions - could get rid of flags
2573  */
cnvt_to_bsel_expr(struct expr_t * xp,int32 i1)2574 static struct expr_t *cnvt_to_bsel_expr(struct expr_t *xp, int32 i1)
2575 {
2576  int32 ri1, ri2;
2577  struct expr_t *new_xp, *new_xp2, *idndp, *selxp;
2578  struct net_t *np;
2579 
2580  if (xp->optyp == PARTSEL) idndp = xp->lu.x; else idndp = xp;
2581  new_xp = __copy_expr(idndp);
2582  np = idndp->lu.sy->el.enp;
2583 
2584  /* root expr of bit select */
2585  new_xp2 = __alloc_newxnd();
2586  new_xp2->optyp = LSB;
2587  new_xp2->szu.xclen = 1;
2588  new_xp2->lu.x = new_xp;
2589  selxp = __bld_rng_numxpr((word32) i1, 0L, WBITS);
2590  selxp->ibase = BDEC;
2591 
2592  __getwir_range(np, &ri1, &ri2);
2593  if (ri2 != 0 || ri1 < ri2) selxp->ind_noth0 = TRUE;
2594  new_xp2->ru.x = selxp;
2595  return(new_xp2);
2596 }
2597 
2598 /*
2599  * compute number of elements in concat (passed LSB expr node)
2600  */
__cnt_cat_size(struct expr_t * xp)2601 extern int32 __cnt_cat_size(struct expr_t *xp)
2602 {
2603  register struct expr_t *catndp;
2604  int32 nels;
2605 
2606  for (nels = 0, catndp = xp->ru.x; catndp != NULL; catndp = catndp->ru.x)
2607   nels++;
2608  return(nels);
2609 }
2610 
2611 /*
2612  * ROUTINES TO BUILD SYMETRIC NET PIN LIST
2613  */
2614 
2615 /*
2616  * build the net pin list and gate state and set port expr. storarge ptrs.
2617  *
2618  * this will automatically include xmr's
2619  * net ranges must have been changed from NX_CT
2620  * also short circuits expression node id's to point to storage
2621  *
2622  * know will not see def or spec params since frozed before here
2623  * and different code for special param np lists disjoint
2624  */
bld_nplist(void)2625 static void bld_nplist(void)
2626 {
2627  register int32 pi, pbi, cai;
2628  register struct mod_pin_t *mpp;
2629  int32 ii, gi, ptyp, pnum;
2630  struct inst_t *ip;
2631  struct mod_t *mdp, *imdp;
2632  struct gate_t *gp;
2633  struct conta_t *cap, *pb_cap;
2634  struct expr_t *xp, *pb_xp;
2635  struct tfrec_t *tfrp;
2636  struct tfarg_t *tfap;
2637  struct mod_pin_t *pb_mpp;
2638 
2639  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
2640   {
2641    __push_wrkitstk(mdp, 0);
2642 
2643    /* first process all instances in module */
2644    for (ii = 0; ii < mdp->minum; ii++)
2645     {
2646      __cur_npii = ii;
2647      ip = &(mdp->minsts[ii]);
2648      imdp = ip->imsym->el.emdp;
2649      if ((pnum = imdp->mpnum) == 0) continue;
2650 
2651      for (pi = 0; pi < pnum; pi++)
2652       {
2653        mpp = &(imdp->mpins[pi]);
2654        xp = ip->ipins[pi];
2655        ptyp = mpp->mptyp;
2656 
2657        __cur_npnum = pi;
2658        __cur_pbi = -1;
2659        /* inst. input port rhs is driver that propagates down into module */
2660        if (ptyp == IO_IN)
2661         {
2662          /* SJM 09/18/02 - scalarize if separable concat hconn */
2663          if (mpp->has_scalar_mpps && rhs_cat_separable(xp))
2664           {
2665            /* lhs width is mpp width since input port down assign */
2666            for (pbi = 0; pbi < mpp->mpwide; pbi++)
2667             {
2668              pb_xp = ip->pb_ipins_tab[pi][pbi];
2669              __cur_pbi = pbi;
2670              bld_rhsexpr_npins(pb_xp, NP_PB_ICONN);
2671             }
2672           }
2673          else bld_rhsexpr_npins(xp, NP_ICONN);
2674         }
2675 
2676        /* inst output port lhs is load propagated up from down module */
2677        /* whether in load or driver list determines interpretation */
2678        else if (ptyp == IO_OUT)
2679         {
2680          if (mpp->has_scalar_mpps)
2681           {
2682            for (pbi = 0; pbi < mpp->mpwide; pbi++)
2683             {
2684              pb_xp = ip->pb_ipins_tab[pi][pbi];
2685              __cur_pbi = pbi;
2686              bld_lhsexpr_npins(pb_xp, NP_PB_ICONN);
2687             }
2688           }
2689          else bld_lhsexpr_npins(xp, NP_ICONN);
2690         }
2691        /* SJM 08/23/00 - for empty port IO type unknown and no npins */
2692        else if (ptyp == IO_UNKN) ;
2693        else
2694         {
2695          /* SJM - 08/25/00 - now allowing concat inouts */
2696          /* FIXME - SJM - 08/27/00 - still but when concat on both sides */
2697          if (xp->optyp == LCB && mpp->mpref->optyp == LCB)
2698           {
2699            __gferr(711, ip->isym->syfnam_ind, ip->isym->sylin_cnt,
2700             "instance %s of type %s inout port %s (pos. %d) concatenate on both sides unsupported",
2701             ip->isym->synam, ip->imsym->synam, __to_mpnam(__xs, mpp->mpsnam),
2702             pi + 1);
2703           }
2704          else bld_lhsexpr_npins(xp, NP_BIDICONN);
2705 	}
2706       }
2707     }
2708 
2709    /* next gates including udps */
2710    /* need for rhs select for lhs concat never possible for gates */
2711    __cur_pbi = -1;
2712    __cur_lhscati1 = __cur_lhscati2 = -1;
2713    for (gi = 0; gi < mdp->mgnum; gi++)
2714     {
2715      gp = &(mdp->mgates[gi]);
2716      __cur_npgp = gp;
2717      switch ((byte) gp->g_class) {
2718       case GC_PULL:
2719        /* one gate all drivers can have multiple pins */
2720        for (pi = 0; pi < (int32) gp->gpnum; pi++)
2721         {
2722          xp = gp->gpins[pi];
2723          __cur_npnum = pi;
2724          bld_lhsexpr_npins(xp, NP_PULL);
2725         }
2726        continue;
2727       /* trans in separate switch channels, drvs needed here for building */
2728       /* and to store tran graph edge, but removed from ndrvs */
2729       case GC_TRAN:
2730        /* SJM 04/26/01 - if both terminals same, no effect - omit from nl */
2731        if (gp->g_gone) continue;
2732 
2733        /* build for directional tran to first lhs port */
2734        /* first driver for forward to port 0 lhs tran */
2735 bld_tran_ports:
2736        __cur_npnum = 0;
2737        xp = gp->gpins[0];
2738        if (xp->optyp != OPEMPTY) bld_lhsexpr_npins(xp, NP_TRAN);
2739        /* then driver for backwards port 1 lhs tran */
2740        __cur_npnum = 1;
2741        xp = gp->gpins[1];
2742        if (xp->optyp != OPEMPTY) bld_lhsexpr_npins(xp, NP_TRAN);
2743        continue;
2744       case GC_TRANIF:
2745        /* SJM 04/26/01 - if both terminals same, no effect - omit from nl */
2746        if (gp->g_gone) continue;
2747 
2748        /* build rhs load for 3rd port enable input */
2749        /* 3rd input port is only a load - never assigned to */
2750        __cur_npnum = 2;
2751        bld_rhsexpr_npins(gp->gpins[2], NP_TRANIF);
2752        goto bld_tran_ports;
2753       default:
2754        /* if output unc. (OPEMPTY), chges are not seen (do not propagate) */
2755        if (gp->gpins[0]->optyp == OPEMPTY) continue;
2756        __cur_npnum = 0;
2757        bld_lhsexpr_npins(gp->gpins[0], NP_GATE);
2758        /* notice pnum is only input pins */
2759        for (pi = 1; pi < (int32) gp->gpnum; pi++)
2760         {
2761          xp = gp->gpins[pi];
2762          __cur_npnum = pi;
2763          bld_rhsexpr_npins(xp, NP_GATE);
2764         }
2765      }
2766     }
2767    __cur_npnum = 0;
2768    for (cap = &(mdp->mcas[0]), cai = 0; cai < mdp->mcanum; cai++, cap++)
2769     {
2770      if (cap->ca_pb_sim)
2771       {
2772        /* for rhs cat without 4v delay, simulator as per bit */
2773        for (pbi = 0; pbi < cap->lhsx->szu.xclen; pbi++)
2774         {
2775          pb_cap = &(cap->pbcau.pbcaps[pbi]);
2776         /* notice for PB cap still need actual cap - will index during sim */
2777          __cur_npcap = cap;
2778          __cur_pbi = pbi;
2779          bld_lhsexpr_npins(pb_cap->lhsx, NP_CONTA);
2780          bld_rhsexpr_npins(pb_cap->rhsx, NP_CONTA);
2781         }
2782       }
2783      else
2784       {
2785        __cur_npcap = cap;
2786        __cur_pbi = -1;
2787        /* for conta expression determines width */
2788        bld_lhsexpr_npins(cap->lhsx, NP_CONTA);
2789        bld_rhsexpr_npins(cap->rhsx, NP_CONTA);
2790       }
2791     }
2792 
2793    /* SJM - 04/30/99 - no longer removing ports but still no npps */
2794    /* for top level modules that have ports still - no npps */
2795    if (mdp->minstnum == 0) goto nxt_mod;
2796 
2797    /* module ports */
2798    pnum = mdp->mpnum;
2799    for (pi = 0; pi < pnum; pi++)
2800     {
2801      mpp = &(mdp->mpins[pi]);
2802      xp = mpp->mpref;
2803      ptyp = mpp->mptyp;
2804      __cur_npmdp = mdp;
2805      __cur_npnum = pi;
2806      __cur_pbi = -1;
2807 
2808      /* module inputs are lvalues (opposite cells) */
2809      if (ptyp == IO_IN)
2810       {
2811        /* SJM 09/18/02 - scalarize if any concat hconn */
2812        /* LOOKATME ??? - what if some high conns not pb seperable concats? */
2813        /* since only for inputs only drivers here, think for non sep */
2814        /* does not hurt to use per bit drivers */
2815        if (mpp->has_scalar_mpps)
2816         {
2817          /* lhs width is mpp width since input port down assign */
2818          for (pbi = 0; pbi < mpp->mpwide; pbi++)
2819           {
2820            pb_mpp = &(mpp->pbmpps[pbi]);
2821            pb_xp = pb_mpp->mpref;
2822            __cur_pbi = pbi;
2823            bld_lhsexpr_npins(pb_xp, NP_PB_MDPRT);
2824           }
2825         }
2826        else bld_lhsexpr_npins(xp, NP_MDPRT);
2827       }
2828      else if (ptyp == IO_OUT)
2829       {
2830        if (mpp->has_scalar_mpps)
2831         {
2832          for (pbi = 0; pbi < mpp->mpwide; pbi++)
2833           {
2834            pb_mpp = &(mpp->pbmpps[pbi]);
2835            pb_xp = pb_mpp->mpref;
2836            __cur_pbi = pbi;
2837            bld_rhsexpr_npins(pb_xp, NP_PB_MDPRT);
2838           }
2839         }
2840        else bld_rhsexpr_npins(xp, NP_MDPRT);
2841       }
2842      /* inouts have no loads or drivers since tran channel eval instead */
2843      /* but for PLI nlds and ndrvs set but never used for simulation */
2844      else if (ptyp == IO_BID)
2845       {
2846        /* SJM - 08/25/00 - now allowing concat connected inout port defs */
2847        bld_lhsexpr_npins(xp, NP_BIDMDPRT);
2848       }
2849      /* SJM 08/23/00 - for empty port IO type unknown and no npins */
2850      else if (ptyp == IO_UNKN) ;
2851      else __case_terr(__FILE__, __LINE__);
2852     }
2853 nxt_mod:
2854    __pop_wrkitstk();
2855   }
2856 
2857  /* keeping one module wide tf rec list */
2858  __cur_pbi = -1;
2859  for (tfrp = __tfrec_hdr; tfrp != NULL; tfrp = tfrp->tfrnxt)
2860   {
2861    for (pi = 1; pi < tfrp->tfanump1; pi++)
2862     {
2863      tfap = &(tfrp->tfargs[pi]);
2864      xp = tfap->arg.axp;
2865      if (!xp->tf_isrw) continue;
2866 
2867      /* DBG remove --- */
2868      if (tfap->anp == NULL) __misc_terr(__FILE__, __LINE__);
2869      /* --- */
2870 
2871      if (tfap->anp->ntyp >= NONWIRE_ST) continue;
2872      __cur_nptfrp = tfrp;
2873      __cur_npnum = pi;
2874      bld_lhsexpr_npins(xp, NP_TFRWARG);
2875     }
2876   }
2877 }
2878 
2879 /*
2880  * build net_pin elements for wire only (lhs) output or inout port
2881  * or gate or conta output port
2882  * know bit/part select not declared with vectored attribute or prev. error
2883  * know concatenates must be exactly 1 level
2884  *
2885  * this also sets has delay bit in top level noded if any element has delay
2886  */
bld_lhsexpr_npins(struct expr_t * xp,int32 npctyp)2887 static void bld_lhsexpr_npins(struct expr_t *xp, int32 npctyp)
2888 {
2889  __cur_lhscati1 = __cur_lhscati2 = -1;
2890  __lhsxpr_has_ndel = FALSE;
2891  bld2_lhsexpr_npins(xp, npctyp);
2892  if (__lhsxpr_has_ndel) xp->lhsx_ndel = TRUE;
2893 }
2894 
2895 /*
2896  * notice lhs xmr's automatically work on lhs no cross module propagation
2897  * either assign to wires where gref info used to find storage and propagate
2898  * in target inst. or eval. drivers using target inst. where needed
2899  * propagation after assignment in cur. itp of destination is wire by wire
2900  */
bld2_lhsexpr_npins(struct expr_t * xp,int32 npctyp)2901 static void bld2_lhsexpr_npins(struct expr_t *xp, int32 npctyp)
2902 {
2903  int32 biti, bitj;
2904  struct expr_t *idndp;
2905  struct net_t *np;
2906  struct expr_t *catxp;
2907  struct gref_t *grp;
2908 
2909  grp = NULL;
2910  switch ((byte) xp->optyp) {
2911   /* this can happen for unc. */
2912   case GLBREF:
2913    idndp = xp;
2914    np = xp->lu.sy->el.enp;
2915    grp = idndp->ru.grp;
2916    if (np->nrngrep == NX_DWIR) __lhsxpr_has_ndel = TRUE;
2917    __conn_npin(np, -1, -1, TRUE, npctyp, grp, NPCHG_NONE, (char *) NULL);
2918    break;
2919   case ID:
2920    np = xp->lu.sy->el.enp;
2921    if (np->nrngrep == NX_DWIR) __lhsxpr_has_ndel = TRUE;
2922    /* by here anything that must be scalared has been or error */
2923    __conn_npin(np, -1, -1, TRUE, npctyp, grp, NPCHG_NONE, (char *) NULL);
2924    break;
2925   case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: case OPEMPTY:
2926    return;
2927   case LSB:
2928    idndp = xp->lu.x;
2929    np = idndp->lu.sy->el.enp;
2930    if (np->nrngrep == NX_DWIR) __lhsxpr_has_ndel = TRUE;
2931    /* know will be constant or will not be on decl. lhs */
2932    /* DBG remove --- */
2933    if (!np->vec_scalared) __misc_terr(__FILE__, __LINE__);
2934    /* --- */
2935    if (idndp->optyp == GLBREF) grp = idndp->ru.grp;
2936    if (xp->ru.x->optyp == ISNUMBER)
2937     {
2938      /* SJM 10/12/04 - IS const must be contab ndx since contab realloced */
2939      __isform_bi_xvi = xp->ru.x->ru.xvi;
2940      __conn_npin(np, -2, 0, TRUE, npctyp, grp, NPCHG_NONE, (char *) NULL);
2941     }
2942    else
2943     {
2944      biti = (int32 ) __contab[xp->ru.x->ru.xvi];
2945      __conn_npin(np, biti, biti, TRUE, npctyp, grp, NPCHG_NONE,
2946       (char *) NULL);
2947     }
2948    break;
2949   case PARTSEL:
2950    idndp = xp->lu.x;
2951    np = idndp->lu.sy->el.enp;
2952 
2953    /* DBG remove --- */
2954    if (!np->vec_scalared) __misc_terr(__FILE__, __LINE__);
2955    /* --- */
2956    if (idndp->optyp == GLBREF) grp = idndp->ru.grp;
2957 
2958    /* for path dest. this is on */
2959    if (np->nrngrep == NX_DWIR) __lhsxpr_has_ndel = TRUE;
2960    /* array stored from 0 to size even though bits go high to 0 */
2961    /* never IS form */
2962    biti = (int32) (__contab[xp->ru.x->lu.x->ru.xvi]);
2963    bitj = (int32) (__contab[xp->ru.x->ru.x->ru.xvi]);
2964 
2965    __conn_npin(np, biti, bitj, TRUE, npctyp, grp, NPCHG_NONE, (char *) NULL);
2966    break;
2967   case LCB:
2968    for (catxp = xp->ru.x; catxp != NULL; catxp = catxp->ru.x)
2969     {
2970      /* catxp length is distance from high bit to rhs end (0) */
2971      __cur_lhscati1 = catxp->szu.xclen - 1;
2972      __cur_lhscati2 = __cur_lhscati1 - catxp->lu.x->szu.xclen + 1;
2973      bld2_lhsexpr_npins(catxp->lu.x, npctyp);
2974     }
2975    break;
2976   default: __case_terr(__FILE__, __LINE__);
2977  }
2978 }
2979 
2980 /*
2981  * build net_pin elements for rhs reg or wire
2982  * these are things that when wire changes (is assigned to) are traced to
2983  * propagate change by evaluating rhs these are in
2984  *
2985  * idea here is too build as normal, then add special itp stuff if needed
2986  * for any global needed because when wire changes in target (eval itp),
2987  * must propagate cross module to place used
2988  */
bld_rhsexpr_npins(struct expr_t * xp,int32 npctyp)2989 static void bld_rhsexpr_npins(struct expr_t *xp, int32 npctyp)
2990 {
2991  int32 biti, bitj;
2992  struct net_t *np;
2993  struct expr_t *idndp, *selxp;
2994  struct gref_t *grp;
2995 
2996  grp = NULL;
2997  switch ((byte) xp->optyp) {
2998   case NUMBER: case ISNUMBER: case REALNUM: case ISREALNUM: return;
2999   case OPEMPTY:
3000    /* could handle `unconndrive by adding some kind of driver here ? */
3001    return;
3002   case GLBREF:
3003    idndp = xp;
3004    np = xp->lu.sy->el.enp;
3005    grp = idndp->ru.grp;
3006    __conn_npin(np, -1, -1, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3007    break;
3008   case ID:
3009    np = xp->lu.sy->el.enp;
3010    __conn_npin(np, -1, -1, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3011    break;
3012   case LSB:
3013    idndp = xp->lu.x;
3014    np = idndp->lu.sy->el.enp;
3015    if (idndp->optyp == GLBREF) grp = idndp->ru.grp;
3016    selxp = xp->ru.x;
3017    /* for registers or arrays, never split, change must always propagate */
3018    /* this means no per array cell tab, if any cell changes, reevaluate */
3019    /* if reg (not wire) or vectored and not arr, any chg causes propagation */
3020    if (!np->vec_scalared && !np->n_isarr)
3021     {
3022      /* if this constant just does nothing */
3023      bld_rhsexpr_npins(selxp, npctyp);
3024      __conn_npin(np, -1, -1, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3025     }
3026    else if (selxp->optyp == NUMBER)
3027     {
3028      biti = (int32) (__contab[selxp->ru.xvi]);
3029      __conn_npin(np, biti, biti, FALSE, npctyp, grp, NPCHG_NONE,
3030       (char *) NULL);
3031     }
3032    else if (selxp->optyp == ISNUMBER)
3033     {
3034      /* SJM 10/12/04 - IS const must be contab ndx since contab realloced */
3035      __isform_bi_xvi = selxp->ru.xvi;
3036      __conn_npin(np, -2, 0, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3037     }
3038    else
3039     {
3040      __conn_npin(np, -1, -1, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3041      bld_rhsexpr_npins(selxp, npctyp);
3042     }
3043    break;
3044   case PARTSEL:
3045    idndp = xp->lu.x;
3046    np = idndp->lu.sy->el.enp;
3047    if (idndp->optyp == GLBREF) grp = idndp->ru.grp;
3048    /* for part select of reg - still need to match all bits */
3049    /* know here both range will be constants */
3050    if (!np->vec_scalared)
3051     __conn_npin(np, -1, -1, FALSE, npctyp, grp, NPCHG_NONE, (char *) NULL);
3052    else
3053     {
3054      /* array stored from 0 to size even though bits go high to 0 */
3055      selxp = xp->ru.x;
3056      /* never IS form */
3057      biti = (int32) (__contab[selxp->lu.x->ru.xvi]);
3058      bitj = (int32) (__contab[selxp->ru.x->ru.xvi]);
3059      __conn_npin(np, biti, bitj, FALSE, npctyp, grp, NPCHG_NONE,
3060       (char *) NULL);
3061     }
3062    break;
3063   case FCALL:
3064    {
3065     register struct expr_t *fax;
3066 
3067     /* if any args of system or user functions change, monitor triggers */
3068     for (fax = xp->ru.x; fax != NULL; fax = fax->ru.x)
3069      bld_rhsexpr_npins(fax->lu.x, npctyp);
3070    }
3071    return;
3072   case LCB:
3073    {
3074     register struct expr_t *catxp;
3075 
3076     for (catxp = xp->ru.x; catxp != NULL; catxp = catxp->ru.x)
3077      bld_rhsexpr_npins(catxp->lu.x, npctyp);
3078    }
3079    return;
3080   default:
3081    if (xp->lu.x != NULL) bld_rhsexpr_npins(xp->lu.x, npctyp);
3082    if (xp->ru.x != NULL) bld_rhsexpr_npins(xp->ru.x, npctyp);
3083    return;
3084  }
3085 }
3086 
3087 /*
3088  * scheme for various types of xmr npps
3089  *
3090  * not xmr (0)          - simple no bits set, no move to ref, no filter
3091  * xmr (not root)   (1) - xmrtyp, npu gref, no filter
3092  * any rooted xmr   (2) - xmrtyp/1inst, npu filtitp to ref, npaux npdownitp
3093  */
3094 
3095 /*
3096  * routine to build 1 net pin connection per static location
3097  *
3098  * LOOKATME - here do matching to find identical static tree upward inst_t
3099  * path but have static tree so maybe could traverse to not need to match?
3100  */
__conn_npin(struct net_t * np,int32 ni1,int32 ni2,int32 islhs,int32 npctyp,struct gref_t * grp,int32 chgtyp,char * chgp)3101 extern void __conn_npin(struct net_t *np, int32 ni1, int32 ni2, int32 islhs,
3102  int32 npctyp, struct gref_t *grp, int32 chgtyp, char *chgp)
3103 {
3104  struct net_pin_t *npp;
3105 
3106  /* case: non xmr */
3107  if (grp == NULL)
3108   {
3109    npp = conn2_npin(np, ni1, ni2, islhs, npctyp);
3110    if (chgtyp != NPCHG_NONE) set_chgsubfld(npp, chgtyp, chgp);
3111    return;
3112   }
3113  /* case 2: rooted xmr */
3114  if (grp->is_rooted)
3115   conn_rtxmr_npin(np, ni1, ni2, islhs, npctyp, grp, chgtyp, chgp);
3116  /* case 3: non rooted xmr */
3117  else conn_xmr_npin(np, ni1, ni2, islhs, npctyp, grp, chgtyp, chgp);
3118 }
3119 
3120 /*
3121  * connect any rooted xmr net pin
3122  *
3123  * idea here is that there will be one npp for each module containing
3124  * reference the one driver or load (rooted xmr) drivers or is a load
3125  * of all instances
3126  *
3127  * for rooted:
3128  *  when wire changes must match npauxp npdownitp inst or not load or driver
3129  *  to move from target (wire that changes) to ref. one loc. is npdownitp
3130  */
conn_rtxmr_npin(struct net_t * np,int32 ni1,int32 ni2,int32 islhs,int32 npctyp,struct gref_t * grp,int32 chgtyp,char * chgp)3131 static void conn_rtxmr_npin(struct net_t *np, int32 ni1, int32 ni2,
3132  int32 islhs, int32 npctyp, struct gref_t *grp, int32 chgtyp, char *chgp)
3133 {
3134  register int32 ii;
3135  struct net_pin_t *npp;
3136  struct itree_t *targitp;
3137 
3138  targitp = grp->targu.targitp;
3139  /* here npp is not instance specific */
3140  for (ii = 0; ii < grp->gin_mdp->flatinum; ii++)
3141   {
3142    npp = conn2_npin(np, ni1, ni2, islhs, npctyp);
3143    if (chgtyp != NPCHG_NONE) set_chgsubfld(npp, chgtyp, chgp);
3144    if (npp->npaux == NULL) npp->npaux = __alloc_npaux();
3145    /* this is place npp referenced from */
3146    npp->npaux->npdownitp = (struct itree_t *) grp->gin_mdp->moditps[ii];
3147 
3148    /* for rooted, target (place wire in) must be the one changed wire in */
3149    /* itree location - need to filter */
3150    npp->npaux->npu.filtitp = targitp;
3151 
3152    npp->np_xmrtyp = XNP_RTXMR;
3153    npp->npproctyp = NP_PROC_FILT;
3154   }
3155 }
3156 
3157 /*
3158  * connect an xmr that is not rooted
3159  * for upwards or downwards relative search using normal routines
3160  * no filtering since one npp where all refs have different target
3161  */
conn_xmr_npin(struct net_t * np,int32 ni1,int32 ni2,int32 islhs,int32 npctyp,struct gref_t * grp,int32 chgtyp,char * chgp)3162 static void conn_xmr_npin(struct net_t *np, int32 ni1, int32 ni2, int32 islhs,
3163  int32 npctyp, struct gref_t *grp, int32 chgtyp, char *chgp)
3164 {
3165  struct net_pin_t *npp;
3166 
3167  npp = conn2_npin(np, ni1, ni2, islhs, npctyp);
3168  if (chgtyp != NPCHG_NONE) set_chgsubfld(npp, chgtyp, chgp);
3169  if (npp->npaux == NULL) npp->npaux = __alloc_npaux();
3170  /* use gref to move from target (npp on wire/inst) to ref. */
3171  npp->npaux->npu.npgrp = grp;
3172  if (grp->upwards_rel) npp->np_xmrtyp = XNP_UPXMR;
3173  else npp->np_xmrtyp = XNP_DOWNXMR;
3174  npp->npproctyp = NP_PROC_GREF;
3175 }
3176 
3177 /*
3178  * connect a range of net bits
3179  * not for register output or trigger net pin list building
3180  * all allocation and connecting of net pins done through here
3181  *
3182  * the xmr fields must be set by caller if needed
3183  */
conn2_npin(struct net_t * np,int32 ni1,int32 ni2,int32 islhs,int32 npctyp)3184 static struct net_pin_t *conn2_npin(struct net_t *np, int32 ni1, int32 ni2,
3185  int32 islhs, int32 npctyp)
3186 {
3187  struct net_pin_t *npp;
3188 
3189  /* if load of vectored vector - always just mark change of entire wire */
3190  if (!islhs && !np->n_isarr && np->n_isavec && !np->vec_scalared)
3191   ni1 = ni2 = -1;
3192 
3193  npp = __alloc_npin(npctyp, ni1, ni2);
3194  /* notice 32 bit dependent since assumes ptr and int32 both 4 bytes */
3195  /* also __isform_bi xvi is contab index so can just use it */
3196  if (ni1 == -2)
3197   npp->npaux->nbi2.xvi = __isform_bi_xvi;
3198 
3199  /* link on front */
3200  if (islhs)
3201   {
3202    if (__cur_lhscati1 != -1)
3203     {
3204      if (npp->npaux == NULL) npp->npaux = __alloc_npaux();
3205      npp->npaux->lcbi1 = __cur_lhscati1;
3206      npp->npaux->lcbi2 = __cur_lhscati2;
3207     }
3208    npp->npnxt = np->ndrvs;
3209    np->ndrvs = npp;
3210   }
3211  else
3212   {
3213    /* never insert mipd nchg using this routine */
3214    /* DBG remove -- */
3215    if (npp->npntyp == NP_MIPD_NCHG) __misc_terr(__FILE__, __LINE__);
3216    /* --- */
3217 
3218    /* SJM 07/10/01 - MIPD load must always be first on list */
3219    /* SJM 07/24/01 - logic was wrong - now if front mipd nchg insert after */
3220    if (np->nlds != NULL && np->nlds->npntyp == NP_MIPD_NCHG)
3221     { npp->npnxt = np->nlds->npnxt; np->nlds->npnxt = npp; }
3222    else { npp->npnxt = np->nlds; np->nlds = npp; }
3223   }
3224  /* DBG remove ---
3225  if (__debug_flg)
3226   {
3227    struct npaux_t *npauxp;
3228 
3229    __dbg_msg(".. mod %s adding net %s pin type %d to front",
3230     __inst_mod->msym->synam, np->nsym->synam, npp->npntyp);
3231    if ((npauxp = npp->npaux) != NULL && npauxp->lcbi1 != -1)
3232     __dbg_msg("([%d:%d])\n", npauxp->lcbi1, npauxp->lcbi2);
3233    else __dbg_msg("\n");
3234   }
3235  --- */
3236  /* just put on front */
3237  return(npp);
3238 }
3239 
3240 /*
3241  * allocate a net pin element
3242  * net pin form converted to table for all net pins in current module
3243  *
3244  * notice [i1:i2] are corrected to h:0 form by here
3245  * also notice some globals such as obnum (port) must be set before calling
3246  */
__alloc_npin(int32 nptyp,int32 i1,int32 i2)3247 extern struct net_pin_t *__alloc_npin(int32 nptyp, int32 i1, int32 i2)
3248 {
3249  struct net_pin_t *npp;
3250  struct primtab_t *ptp;
3251 
3252  npp = (struct net_pin_t *) __my_malloc(sizeof(struct net_pin_t));
3253  npp->npntyp = (word32) nptyp;
3254  npp->npproctyp = NP_PROC_INMOD;
3255  /* value explicitly set if needed */
3256  npp->chgsubtyp = 0;
3257 
3258  npp->np_xmrtyp = XNP_LOC;
3259  npp->pullval = 0;
3260  /* assume more common load */
3261  npp->obnum = __cur_npnum;
3262  npp->pbi = -1;
3263  npp->npaux = NULL;
3264  switch ((byte) nptyp) {
3265   case NP_ICONN: case NP_BIDICONN:
3266    npp->elnpp.eii = __cur_npii;
3267    break;
3268   case NP_PB_ICONN:
3269    npp->elnpp.eii = __cur_npii;
3270    npp->pbi = __cur_pbi;
3271    break;
3272   case NP_GATE: case NP_TRAN: case NP_TRANIF:
3273    npp->elnpp.egp = __cur_npgp;
3274    break;
3275   case NP_CONTA:
3276    npp->elnpp.ecap = __cur_npcap;
3277    npp->pbi = __cur_pbi;
3278    break;
3279   case NP_MDPRT: case NP_BIDMDPRT:
3280    npp->elnpp.emdp = __cur_npmdp;
3281    break;
3282   case NP_PB_MDPRT:
3283    npp->elnpp.emdp = __cur_npmdp;
3284    npp->pbi = __cur_pbi;
3285    break;
3286   /* set later */
3287   case NP_TCHG: npp->elnpp.etchgp = NULL; break;
3288   case NP_PULL:
3289    npp->elnpp.egp = __cur_npgp;
3290    ptp = __cur_npgp->gmsym->el.eprimp;
3291    npp->pullval = (ptp->gateid == G_PULLUP) ? 1 : 0;
3292    break;
3293   case NP_TFRWARG:
3294    npp->elnpp.etfrp = __cur_nptfrp;
3295    npp->obnum = __cur_npnum;
3296    break;
3297   case NP_VPIPUTV:
3298    npp->elnpp.enp = __cur_npnp;
3299    /* caller sets to index number of this driver */
3300    npp->obnum = 0;
3301    break;
3302   case NP_MIPD_NCHG:
3303    npp->elnpp.enp = __cur_npnp;
3304    npp->obnum = 0;
3305    break;
3306   default: __case_terr(__FILE__, __LINE__);
3307  }
3308  npp->npnxt = NULL;
3309 
3310  if (i1 != -1)
3311   {
3312    npp->npaux = __alloc_npaux();
3313    npp->npaux->nbi1 = i1;
3314    npp->npaux->nbi2.i = i2;
3315   }
3316  return(npp);
3317 }
3318 
3319 /*
3320  * allocate and initialize the aux. net pin record
3321  */
__alloc_npaux(void)3322 extern struct npaux_t *__alloc_npaux(void)
3323 {
3324  struct npaux_t *npauxp;
3325 
3326  npauxp = (struct npaux_t *) __my_malloc(sizeof(struct npaux_t));
3327  npauxp->nbi1 = -1;
3328  npauxp->nbi2.i = -1;
3329  npauxp->npu.npgrp = NULL;
3330  npauxp->npdownitp = NULL;
3331  npauxp->lcbi1 = npauxp->lcbi2 = -1;
3332  return(npauxp);
3333 }
3334 
3335 /*
3336  * set change subtype fields for a npp
3337  */
set_chgsubfld(struct net_pin_t * npp,int32 chgtyp,char * chgp)3338 static void set_chgsubfld(struct net_pin_t *npp, int32 chgtyp, char *chgp)
3339 {
3340  npp->chgsubtyp = chgtyp;
3341  switch (chgtyp) {
3342   case NPCHG_TCSTART: npp->elnpp.etchgp = (struct tchg_t *) chgp; break;
3343   case NPCHG_TCCHK: npp->elnpp.echktchgp = (struct chktchg_t *) chgp; break;
3344   case NPCHG_PTHSRC: npp->elnpp.etchgp = (struct tchg_t *) chgp; break;
3345   default: __case_terr(__FILE__, __LINE__);
3346  }
3347 }
3348 
3349 /*
3350  * ROUTINES TO BUILD DEFPARAM AND SPECPARAM CONTAINING EXPR LIST
3351  */
3352 
3353 /*
3354  * add delay list parameters to param parm nplst for a net
3355  */
add_netdel_pnp(struct net_t * np,struct paramlst_t * pdels)3356 static void add_netdel_pnp(struct net_t *np, struct paramlst_t *pdels)
3357 {
3358  register struct paramlst_t *pmp;
3359  int32 sav_fnam_ind, sav_slin_cnt;
3360  struct expr_t *dxp;
3361  struct parmnet_pin_t tmpl_pnp;
3362 
3363  init_pnp(&tmpl_pnp);
3364  tmpl_pnp.pnptyp = PNP_NETDEL;
3365  /* object delay for */
3366  tmpl_pnp.elpnp.enp = np;
3367  /* not copied but moved from previous pdels whose field is overwritten */
3368  tmpl_pnp.pnplp = pdels;
3369 
3370  sav_fnam_ind = __sfnam_ind;
3371  sav_slin_cnt = __slin_cnt;
3372  __sfnam_ind = (int32) np->nsym->syfnam_ind;
3373  __slin_cnt = np->nsym->sylin_cnt;
3374 
3375  /* only free first one */
3376  __nd_parmpnp_free = TRUE;
3377  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3378   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3379 
3380  __sfnam_ind = sav_fnam_ind;
3381  __slin_cnt = sav_slin_cnt;
3382 }
3383 
3384 /*
3385  * initialize a param net pin elemnt
3386  */
init_pnp(struct parmnet_pin_t * pnp)3387 static void init_pnp(struct parmnet_pin_t *pnp)
3388 {
3389  pnp->pnp_free = FALSE;
3390  pnp->elpnp.enp = NULL;
3391  pnp->pnplp = NULL;
3392  pnp->pnpnxt = NULL;
3393 }
3394 
3395 /*
3396  * build a param nplst element from a param in an expression
3397  */
addto_parmnplst(struct expr_t * xp,struct parmnet_pin_t * tmplate_pnp)3398 static void addto_parmnplst(struct expr_t *xp,
3399  struct parmnet_pin_t *tmplate_pnp)
3400 {
3401  struct net_t *np;
3402  struct parmnet_pin_t *pnp;
3403 
3404  if (__isleaf(xp))
3405   {
3406    if (xp->optyp == GLBREF)
3407     {
3408      np = xp->lu.sy->el.enp;
3409       __sgfinform(457,
3410        "hierarchical parameter %s used in delay expression can not be annotated to",
3411        __msgexpr_tostr(__xs, xp));
3412      return;
3413     }
3414    if (xp->optyp != ID || xp->lu.sy->sytyp != SYM_N) return;
3415 
3416    np = xp->lu.sy->el.enp;
3417    if (!np->n_isaparam) return;
3418 
3419    pnp = (struct parmnet_pin_t *) __my_malloc(sizeof(struct parmnet_pin_t));
3420    *pnp = *tmplate_pnp;
3421    if (__nd_parmpnp_free)
3422     { pnp->pnp_free = TRUE; __nd_parmpnp_free = FALSE; }
3423    else pnp->pnp_free = FALSE;
3424    /* reverse order, put on front */
3425    if (np->nlds == NULL) np->nlds = (struct net_pin_t *) pnp;
3426    else
3427     {
3428      pnp->pnpnxt = (struct parmnet_pin_t *) np->nlds;
3429      np->nlds = (struct net_pin_t *) pnp;
3430     }
3431    return;
3432   }
3433  if (xp->lu.x != NULL) addto_parmnplst(xp->lu.x, tmplate_pnp);
3434  if (xp->ru.x != NULL) addto_parmnplst(xp->ru.x, tmplate_pnp);
3435 }
3436 
3437 /*
3438  * add delay list parameters to param parm nplst for a gate
3439  */
add_gatedel_pnp(struct gate_t * gp,struct paramlst_t * pdels)3440 static void add_gatedel_pnp(struct gate_t *gp, struct paramlst_t *pdels)
3441 {
3442  register struct paramlst_t *pmp;
3443  int32 sav_fnam_ind, sav_slin_cnt;
3444  struct expr_t *dxp;
3445  struct parmnet_pin_t tmpl_pnp;
3446 
3447  init_pnp(&tmpl_pnp);
3448  tmpl_pnp.pnptyp = PNP_GATEDEL;
3449  /* object delay for */
3450  tmpl_pnp.elpnp.egp = gp;
3451  /* not copied but moved from previous pdels whose field is overwritten */
3452  tmpl_pnp.pnplp = pdels;
3453 
3454  sav_fnam_ind = __sfnam_ind;
3455  sav_slin_cnt = __slin_cnt;
3456  __sfnam_ind = (int32) gp->gsym->syfnam_ind;
3457  __slin_cnt = gp->gsym->sylin_cnt;
3458 
3459  /* only free first use - all other uses point to same parm npp */
3460  __nd_parmpnp_free = TRUE;
3461  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3462   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3463 
3464  __sfnam_ind = sav_fnam_ind;
3465  __slin_cnt = sav_slin_cnt;
3466 }
3467 
3468 /*
3469  * add delay list parameters to param parm nplst for a conta
3470  */
add_contadel_pnp(struct conta_t * cap,struct paramlst_t * pdels)3471 static void add_contadel_pnp(struct conta_t *cap, struct paramlst_t *pdels)
3472 {
3473  register struct paramlst_t *pmp;
3474  int32 sav_fnam_ind, sav_slin_cnt;
3475  struct expr_t *dxp;
3476  struct parmnet_pin_t tmpl_pnp;
3477 
3478  init_pnp(&tmpl_pnp);
3479  tmpl_pnp.pnptyp = PNP_CONTADEL;
3480  /* object delay for */
3481  tmpl_pnp.elpnp.ecap = cap;
3482  /* not copied but moved from previous pdels whose field is overwritten */
3483  tmpl_pnp.pnplp = pdels;
3484 
3485  sav_fnam_ind = __sfnam_ind;
3486  sav_slin_cnt = __slin_cnt;
3487  __sfnam_ind = (int32) cap->casym->syfnam_ind;
3488  __slin_cnt = cap->casym->sylin_cnt;
3489 
3490  /* only free first one */
3491  __nd_parmpnp_free = TRUE;
3492  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3493   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3494 
3495  __sfnam_ind = sav_fnam_ind;
3496  __slin_cnt = sav_slin_cnt;
3497 }
3498 
3499 /*
3500  * add delay list parameters to param parm nplst for a procedural delay ctrl
3501  *
3502  * know will only be one delay
3503  */
__add_dctldel_pnp(struct st_t * stp)3504 extern void __add_dctldel_pnp(struct st_t *stp)
3505 {
3506  register struct paramlst_t *pmp;
3507  int32 sav_fnam_ind, sav_slin_cnt;
3508  struct delctrl_t *dctp;
3509  struct paramlst_t *pdels;
3510  struct expr_t *dxp;
3511  struct parmnet_pin_t tmpl_pnp;
3512 
3513  init_pnp(&tmpl_pnp);
3514  tmpl_pnp.pnptyp = PNP_PROCDCTRL;
3515  /* object delay for */
3516  dctp = stp->st.sdc;
3517  tmpl_pnp.elpnp.edctp = dctp;
3518  pdels = dctp->dc_du.pdels;
3519  /* not copied but moved from previous pdels whose field is overwritten */
3520  tmpl_pnp.pnplp = pdels;
3521 
3522  sav_fnam_ind = __sfnam_ind;
3523  sav_slin_cnt = __slin_cnt;
3524  __sfnam_ind = (int32) stp->stfnam_ind;
3525  __slin_cnt = stp->stlin_cnt;
3526 
3527  /* only free first one */
3528  __nd_parmpnp_free = TRUE;
3529  /* DBG remove -- */
3530  if (pdels->pmlnxt != NULL) __misc_terr(__FILE__, __LINE__);
3531  /* --- */
3532  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3533   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3534 
3535  __sfnam_ind = sav_fnam_ind;
3536  __slin_cnt = sav_slin_cnt;
3537 }
3538 
3539 /*
3540  * add delay list parameters to param parm nplst for a timing check
3541  *
3542  * know will only be one delay
3543  */
__add_tchkdel_pnp(struct tchk_t * tcp,int32 is_1st)3544 extern void __add_tchkdel_pnp(struct tchk_t *tcp, int32 is_1st)
3545 {
3546  register struct paramlst_t *pmp;
3547  int32 sav_fnam_ind, sav_slin_cnt;
3548  struct paramlst_t *pdels;
3549  struct expr_t *dxp;
3550  struct parmnet_pin_t tmpl_pnp;
3551 
3552  init_pnp(&tmpl_pnp);
3553  tmpl_pnp.elpnp.etcp = tcp;
3554  if (is_1st)
3555   { tmpl_pnp.pnptyp = PNP_TCHKP1; pdels = tcp->tclim_du.pdels; }
3556  else { tmpl_pnp.pnptyp = PNP_TCHKP2; pdels = tcp->tclim2_du.pdels; }
3557  /* not copied but moved from previous pdels whose field is overwritten */
3558  tmpl_pnp.pnplp = pdels;
3559 
3560  sav_fnam_ind = __sfnam_ind;
3561  sav_slin_cnt = __slin_cnt;
3562  __sfnam_ind = (int32) tcp->tcsym->syfnam_ind;
3563  __slin_cnt = tcp->tcsym->sylin_cnt;
3564 
3565  /* only free first one */
3566  __nd_parmpnp_free = TRUE;
3567  /* DBG remove -- */
3568  if (pdels->pmlnxt != NULL) __misc_terr(__FILE__, __LINE__);
3569  /* --- */
3570  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3571   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3572 
3573  __sfnam_ind = sav_fnam_ind;
3574  __slin_cnt = sav_slin_cnt;
3575 }
3576 
3577 /*
3578  * add delay list parameters to param parm nplst for a timing check
3579  */
__add_pathdel_pnp(struct spcpth_t * pthp)3580 extern void __add_pathdel_pnp(struct spcpth_t *pthp)
3581 {
3582  register struct paramlst_t *pmp;
3583  int32 sav_fnam_ind, sav_slin_cnt;
3584  struct paramlst_t *pdels;
3585  struct expr_t *dxp;
3586  struct parmnet_pin_t tmpl_pnp;
3587 
3588  init_pnp(&tmpl_pnp);
3589  tmpl_pnp.elpnp.epthp = pthp;
3590  tmpl_pnp.pnptyp = PNP_PATHDEL;
3591  pdels = pthp->pth_du.pdels;
3592  /* not copied but moved from previous pdels whose field is overwritten */
3593  tmpl_pnp.pnplp = pdels;
3594 
3595  sav_fnam_ind = __sfnam_ind;
3596  sav_slin_cnt = __slin_cnt;
3597  __sfnam_ind = (int32) pthp->pthsym->syfnam_ind;
3598  __slin_cnt = pthp->pthsym->sylin_cnt;
3599 
3600  /* only free first one */
3601  __nd_parmpnp_free = TRUE;
3602  for (pmp = pdels; pmp != NULL; pmp = pmp->pmlnxt)
3603   { dxp = pmp->plxndp; addto_parmnplst(dxp, &tmpl_pnp); }
3604 
3605  __sfnam_ind = sav_fnam_ind;
3606  __slin_cnt = sav_slin_cnt;
3607 }
3608 
3609 /*
3610  * free all parm net pin in design
3611  *
3612  * after this is called information required to annotate delays from
3613  * params (labels) gone
3614  */
__free_design_pnps(void)3615 extern void __free_design_pnps(void)
3616 {
3617  register int32 ni;
3618  register struct net_t *prmp;
3619  struct mod_t *mdp;
3620  struct task_t *tskp;
3621 
3622  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3623   {
3624    __push_wrkitstk(mdp, 0);
3625 
3626    if (__inst_mod->mprmnum != 0)
3627     {
3628      for (ni = 0, prmp = &(__inst_mod->mprms[0]); ni < __inst_mod->mprmnum;
3629       ni++, prmp++)
3630       {
3631        /* DBG remove -- */
3632        if (!prmp->n_isaparam) __misc_terr(__FILE__, __LINE__);
3633        /* --- */
3634 
3635        if (prmp->nlds == NULL) continue;
3636        free_1parm_pnps(prmp);
3637       }
3638     }
3639    for (tskp = __inst_mod->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3640     {
3641      if (tskp->tprmnum == 0) continue;
3642      prmp = &(tskp->tsk_prms[0]);
3643      for (ni = 0; ni < tskp->tprmnum; ni++, prmp++)
3644       {
3645        if (!prmp->n_isaparam) continue;
3646        if (prmp->nlds == NULL) continue;
3647        free_1parm_pnps(prmp);
3648       }
3649     }
3650    __pop_wrkitstk();
3651   }
3652 }
3653 
3654 /*
3655  * free the pnp parm net list for one parameter
3656  *
3657  * called after SDF and vpi_ cbEndOfCompile call back since from then
3658  * on assign to parameters in delay expressions (by vpi_, SDF annotate done)
3659  * has no effect since delays elaborated (or frozen)
3660  */
free_1parm_pnps(struct net_t * prmp)3661 static void free_1parm_pnps(struct net_t *prmp)
3662 {
3663  register struct parmnet_pin_t *pnp, *pnp2;
3664 
3665  for (pnp = (struct parmnet_pin_t *) prmp->nlds; pnp != NULL;)
3666   {
3667    pnp2 = pnp->pnpnxt;
3668    if (pnp->pnp_free) __free_dellst(pnp->pnplp);
3669    __my_free((char *) pnp, sizeof(struct parmnet_pin_t));
3670    pnp = pnp2;
3671   }
3672 }
3673 
3674 /*
3675  * ROUTINES TO CONVERT KNOWN AT COMPILE TIME NPPS TO TABLE (ARRAY)
3676  */
3677 
3678 /*
3679  * re allocate npp list into indexable table
3680  *
3681  * only for the in src (non bid/tran npps that are in tran channels
3682  * edges so removed) - keep as linked list since during sim will add
3683  * and remove - table allows generation of .s that does not change
3684  * from malloc differences - MIPD and vpi added npps can't be accessed
3685  * by index
3686  *
3687  * since bid tran npps pointed to by edges, can't realloc to table
3688  * but know that all tran channel npps (BID and TRAN) removed so
3689  * list can be converted to indexable table but only for in src npps
3690  */
realloc_npplist_to_tab(void)3691 static void realloc_npplist_to_tab(void)
3692 {
3693  register struct mod_t *mdp;
3694  register struct net_t *np;
3695  int32 ni;
3696  struct task_t *tskp;
3697 
3698  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3699   {
3700    for (ni = 0, np = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, np++)
3701     {
3702      realloc_1net_npplist(np);
3703     }
3704    for (tskp = mdp->mtasks; tskp != NULL; tskp = tskp->tsknxt)
3705     {
3706      for (ni = 0, np = &(tskp->tsk_regs[0]); ni < tskp->trnum; ni++, np++)
3707       {
3708        realloc_1net_npplist(np);
3709       }
3710     }
3711   }
3712 }
3713 
3714 /*
3715  * realloc npp list into table (only for npps and dces in src)
3716  *
3717  * nothing points at dce and the tran channel edges that point to npps
3718  * linked out by here
3719  *
3720  * fields pointed to from npps and dces can just be copied
3721  */
realloc_1net_npplist(struct net_t * np)3722 static void realloc_1net_npplist(struct net_t *np)
3723 {
3724  register int32 i;
3725  int32 num_dces, num_npps;
3726  struct dcevnt_t *dcetab, *dcep, *dcep2;
3727  struct net_pin_t *npptab, *npp, *npp2;
3728 
3729  if (np->dcelst != NULL)
3730   {
3731    num_dces = cnt_dces(np->dcelst);
3732    dcetab = (struct dcevnt_t *) __my_malloc(num_dces*sizeof(struct dcevnt_t));
3733    for (i = 0, dcep = np->dcelst; i < num_dces; i++)
3734     {
3735      dcep2 = dcep->dcenxt;
3736 
3737      dcetab[i] = *dcep;
3738      if (i > 0) dcetab[i - 1].dcenxt = &(dcetab[i]);
3739 
3740      __my_free((char *) dcep, sizeof(struct dcevnt_t));
3741      dcep = dcep2;
3742     }
3743    /* last one's nil, copied right */
3744    np->dcelst = dcetab;
3745   }
3746  if (np->nlds != NULL)
3747   {
3748    num_npps = cnt_npps(np->nlds);
3749    npptab = (struct net_pin_t *)
3750     __my_malloc(num_npps*sizeof(struct net_pin_t));
3751    for (i = 0, npp = np->nlds; i < num_npps; i++)
3752     {
3753      npp2 = npp->npnxt;
3754 
3755      npptab[i] = *npp;
3756      if (i > 0) npptab[i - 1].npnxt = &(npptab[i]);
3757 
3758      __my_free((char *) npp, sizeof(struct net_pin_t));
3759      npp = npp2;
3760     }
3761    /* last one's nil, copied right */
3762    np->nlds = npptab;
3763   }
3764  if (np->ndrvs != NULL)
3765   {
3766    num_npps = cnt_npps(np->ndrvs);
3767    npptab = (struct net_pin_t *)
3768     __my_malloc(num_npps*sizeof(struct net_pin_t));
3769    for (i = 0, npp = np->ndrvs; i < num_npps; i++)
3770     {
3771      npp2 = npp->npnxt;
3772 
3773      npptab[i] = *npp;
3774      if (i > 0) npptab[i - 1].npnxt = &(npptab[i]);
3775 
3776      __my_free((char *) npp, sizeof(struct net_pin_t));
3777      npp = npp2;
3778     }
3779    /* last one's nil, copied right */
3780    np->ndrvs = npptab;
3781   }
3782 }
3783 
3784 /*
3785  * count number of npps
3786  */
cnt_npps(struct net_pin_t * npp)3787 static int32 cnt_npps(struct net_pin_t *npp)
3788 {
3789  int32 num_npps;
3790 
3791  for (num_npps = 0; npp != NULL; npp = npp->npnxt) num_npps++;
3792  return(num_npps);
3793 }
3794 
3795 /*
3796  * count number of dces
3797  */
cnt_dces(struct dcevnt_t * dcep)3798 static int32 cnt_dces(struct dcevnt_t *dcep)
3799 {
3800  int32 num_dces;
3801 
3802  for (num_dces = 0; dcep != NULL; dcep = dcep->dcenxt) num_dces++;
3803  return(num_dces);
3804 }
3805 
3806 /*
3807  * ROUTINES TO IMPLEMENT GATE EATER
3808  */
3809 
3810 /*
3811  * remove all gates and nets that are not driver or drive nothing
3812  *
3813  * if wire connects to I/O port never removed
3814  * if instance source or destination of xmr never removed
3815  *
3816  * this uses n_ispthsrc flag since deletable wires never I/O ports
3817  * also only I/O ports can be deleted so since I/O ports not deletable
3818  * will never see here
3819  * this builds nqc_u (nu2) for keepping track of fan-in/fan-out but always
3820  * freed when done
3821  */
eat_gates(void)3822 static void eat_gates(void)
3823 {
3824  register struct net_t *np;
3825  register int32 pi, ni;
3826  register struct tfrec_t *tfrp;
3827  int32 some_eaten, first_time, wlen;
3828  word32 *wp;
3829  struct mod_t *mdp;
3830  struct tfarg_t *tfap;
3831 
3832  /* first mark all wires in design that are undeletable */
3833  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3834   {
3835    if (mdp->mnnum == 0) continue;
3836 
3837    __push_wrkitstk(mdp, 0);
3838    /* this sets n_mark for all nets not candidates for deletion */
3839    for (ni = 0, np = &(__inst_mod->mnets[0]); ni < __inst_mod->mnnum;
3840     ni++, np++)
3841     {
3842      np->n_mark = FALSE;
3843 
3844      /* cannot delete i/o ports or arrays and must be wire to delete */
3845      /* temporary n_mark indicates not deletable */
3846      /* never delete wire in tran channel really has drivers and loads */
3847 
3848      if (np->ntyp >= NONWIRE_ST || np->iotyp != NON_IO || np->ntraux != NULL)
3849       { np->n_mark = TRUE; continue; }
3850 
3851      /* if only drivers or loads but has must stay npp's cannot delete */
3852      /* cannot delete if xmr or IS form */
3853      if (np->ndrvs != NULL && has_muststay_npp(np->ndrvs))
3854       { np->n_mark = TRUE; continue; }
3855      if (np->nlds != NULL && has_muststay_npp(np->nlds))
3856       { np->n_mark = TRUE; continue; }
3857     }
3858    __pop_wrkitstk();
3859   }
3860  /* also mark all wires that connect to tf_ args - list is design wide */
3861  /* even if only used in rhs connection */
3862  for (tfrp = __tfrec_hdr; tfrp != NULL; tfrp = tfrp->tfrnxt)
3863   {
3864    for (pi = 1; pi < tfrp->tfanump1; pi++)
3865     {
3866      tfap = &(tfrp->tfargs[pi]);
3867      mark_muststay_wires(tfap->arg.axp);
3868     }
3869   }
3870 
3871  /* next do deleting module by module */
3872  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
3873   {
3874    __push_wrkitstk(mdp, 0);
3875 
3876    some_eaten = TRUE;
3877    first_time = TRUE;
3878    while (some_eaten)
3879     {
3880      /* notice only deleted cells can allow new net deletions */
3881      eat_nets(first_time);
3882      first_time = FALSE;
3883      eat_cells(&some_eaten);
3884     }
3885    /* this module done free any qcval fields */
3886    /* if any qc forms, will be rebuilt and used for different purpose */
3887    if (__inst_mod->mnnum != 0)
3888     {
3889      for (ni = 0, np = &(__inst_mod->mnets[0]); ni < __inst_mod->mnnum;
3890       ni++, np++)
3891       {
3892        /* turn mark off */
3893        np->n_mark = FALSE;
3894        if (np->nu2.wp != NULL)
3895         {
3896          wlen = 2*wlen_(np->nwid);
3897          wp = np->nu2.wp;
3898          __my_free((char *) wp, wlen*WRDBYTES);
3899          np->nu2.wp = NULL;
3900         }
3901       }
3902     }
3903    __pop_wrkitstk();
3904   }
3905 }
3906 
3907 /*
3908  * return T if has some kind of net pin that cannot be deleted
3909  * 1) if IS form undeletable
3910  * 2) if net pin is xmr then net it is on cannot be deleted
3911  *
3912  * also) if has I/O port connection, but should never see here
3913  */
has_muststay_npp(register struct net_pin_t * npp)3914 static int32 has_muststay_npp(register struct net_pin_t *npp)
3915 {
3916  struct npaux_t *npauxp;
3917 
3918  for (; npp != NULL; npp = npp->npnxt)
3919   {
3920    if (npp->np_xmrtyp != XNP_LOC) return(TRUE);
3921    if ((npauxp = npp->npaux) != NULL && npauxp->nbi1 == -2) return(TRUE);
3922    /* --- DBG remove */
3923    if (npp->npntyp == NP_MDPRT || npp->npntyp == NP_PB_MDPRT)
3924     __misc_terr(__FILE__, __LINE__);
3925   }
3926  return(FALSE);
3927 }
3928 
3929 /*
3930  * mark wires that must remain uneaten because connect to tf_ arg
3931  */
mark_muststay_wires(struct expr_t * xp)3932 static void mark_muststay_wires(struct expr_t *xp)
3933 {
3934  struct net_t *np;
3935 
3936  if (__isleaf(xp))
3937   {
3938    if (xp->optyp == ID || xp->optyp == GLBREF)
3939     {
3940      np = xp->lu.sy->el.enp;
3941      if (np->ntyp < NONWIRE_ST) np->n_mark = TRUE;
3942     }
3943    return;
3944   }
3945  if (xp->lu.x != NULL) mark_muststay_wires(xp->lu.x);
3946  if (xp->ru.x != NULL) mark_muststay_wires(xp->ru.x);
3947 }
3948 
3949 /*
3950  * remove net and npp's for unc. bits
3951  * know only nets marked n_ispthsrc (tmp. flag)
3952  * tri0/tri1 implied driver nets always have fi = 1
3953  *
3954  */
eat_nets(int32 first_time)3955 static void eat_nets(int32 first_time)
3956 {
3957  register int32 ni, wi;
3958  register struct net_t *np;
3959  int32 nfi, nfo, impl_drv, wlen;
3960  word32 *wpfi, *wpfo;
3961 
3962  if (__inst_mod->mnnum == 0) return;
3963  if (!first_time) rem_del_npps();
3964  for (ni = 0, np = &(__inst_mod->mnets[0]); ni < __inst_mod->mnnum; ni++, np++)
3965   {
3966    if (np->n_mark || np->n_gone) continue;
3967 
3968    impl_drv = wire_implied_driver(np);
3969    /* assume has fi and fan out */
3970    nfi = nfo = 1;
3971    if (!np->n_isavec)
3972     {
3973      /* any type of driver including tri0/1 implied prevents deletion */
3974      /* wire used in any rhs (i.e. procedural) has loads even if no wire */
3975      /* loads that require event propagation */
3976      if (np->nlds == NULL && !np->n_onprocrhs) nfo = 0;
3977      if (np->ndrvs == NULL && !impl_drv) nfi = 0;
3978      if (nfo != 0 && nfi != 0) continue;
3979 
3980 do_delete:
3981      if (nfo == 0 && nfi == 0)
3982       __gfinform(447, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3983        "net %s in %s disconnected: no drivers, no loads and no procedural connections",
3984        np->nsym->synam, __inst_mod->msym->synam);
3985      else if (nfi == 0)
3986       __gfinform(447, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3987        "net %s in %s disconnected: no drivers", np->nsym->synam,
3988        __inst_mod->msym->synam);
3989      else
3990       __gfinform(447, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
3991        "net %s in %s disconnected: no loads and no procedural connections",
3992        np->nsym->synam, __inst_mod->msym->synam);
3993 del_done:
3994      np->n_gone = TRUE;
3995      remove_all_npps(np);
3996      __flnets_removable += __inst_mod->flatinum;
3997      __nets_removable++;
3998      continue;
3999     }
4000    /* if vector no loads (or proc rhs conns) or drivers can just delete */
4001    if (np->nlds == NULL && !np->n_onprocrhs) nfo = 0;
4002    if (np->ndrvs == NULL && !impl_drv) nfi = 0;
4003    if (nfi == 0 || nfo == 0)
4004     {
4005      /* in case last npp removed, mark processed */
4006      /* here know non i/o that can be deleted is never path source so use */
4007      /* as temporary need to delete this time flag */
4008      np->n_isapthsrc = FALSE;
4009      goto do_delete;
4010     }
4011 
4012    /* if npp list changed or not yet built, must build */
4013    if ((wpfi = np->nu2.wp) == NULL || np->n_isapthsrc)
4014     {
4015      bld1vec_fifo(np);
4016      np->n_isapthsrc = FALSE;
4017      /* make sure wpfi set from nu2 wp union member */
4018      wpfi = (word32 *) np->nu2.wp;
4019     }
4020 
4021    /* if at least one driver and used on rhs cannot delete */
4022    /* but still need per bit fifo vec since if gate connecting bit */
4023    /* has no fi and no fo even though has proc. connection gate del. gate */
4024    if (np->ndrvs != NULL && np->n_onprocrhs) goto nxt_net;
4025 
4026    /* must check bit by bit - possible for some bits have fi others fo */
4027    wlen = wlen_(np->nwid);
4028    wpfo = &(wpfi[wlen]);
4029    for (wi = 0; wi < wlen; wi++)
4030     {
4031      /* if even 1 bit fi/fo cannot delete net - but maybe still cells */
4032      if ((wpfi[wi] & wpfo[wi]) != 0) goto nxt_net;
4033     }
4034    __gfinform(447, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
4035     "net %s disconnected: no procedural connections and no bit has both drivers and loads",
4036     np->nsym->synam);
4037    goto del_done;
4038 
4039 nxt_net:;
4040   }
4041 }
4042 
4043 /*
4044  * routine to remove all marked (n_isapthsrc is tmp flag)
4045  * this routine is called only after eat cells (not first time)
4046  * error if at least one not deleted
4047  * only called if has nets
4048  */
rem_del_npps(void)4049 static void rem_del_npps(void)
4050 {
4051  register int32 ni;
4052  register struct net_t *np;
4053  register struct net_pin_t *npp;
4054  struct net_pin_t *npp2, *last_npp;
4055  int32 net_chged;
4056 
4057  for (ni = 0, np = &(__inst_mod->mnets[0]); ni < __inst_mod->mnnum; ni++, np++)
4058   {
4059    if (np->n_mark || !np->n_isapthsrc || np->n_gone) continue;
4060 
4061    /* first remove net pin elements connected to removed cells */
4062    for (net_chged = FALSE, last_npp = NULL, npp = np->ndrvs; npp != NULL;)
4063     {
4064      switch ((byte) npp->npntyp) {
4065       case NP_GATE:
4066        /* know this is at most 1 wire and net pin element no xmr field */
4067        if (!npp->elnpp.egp->g_gone) break;
4068 do_gate_npp_del:
4069        if (last_npp == NULL) np->ndrvs = npp->npnxt;
4070        else last_npp->npnxt = npp->npnxt;
4071        npp2 = npp->npnxt;
4072        __my_free((char *) npp, sizeof(struct net_pin_t));
4073        npp = npp2;
4074        net_chged = TRUE;
4075        continue;
4076       case NP_CONTA:
4077        if (npp->elnpp.ecap->ca_gone) goto do_gate_npp_del;
4078        break;
4079      }
4080      last_npp = npp;
4081      npp = npp->npnxt;
4082     }
4083    for (last_npp = NULL, npp = np->nlds; npp != NULL;)
4084     {
4085      switch ((byte) npp->npntyp) {
4086       case NP_GATE:
4087        /* know this is at most 1 wire and net pin element no xmr field */
4088        if (!npp->elnpp.egp->g_gone) break;
4089 do_npp_del:
4090        if (last_npp == NULL) np->nlds = npp->npnxt;
4091        else last_npp->npnxt = npp->npnxt;
4092        npp2 = npp->npnxt;
4093        __my_free((char *) npp, sizeof(struct net_pin_t));
4094        npp = npp2;
4095        net_chged = TRUE;
4096        continue;
4097       case NP_CONTA:
4098        if (npp->elnpp.ecap->ca_gone) goto do_npp_del;
4099        break;
4100        /* tf form should only be driver */
4101      }
4102      last_npp = npp;
4103      npp = npp->npnxt;
4104     }
4105    /* no net pin list change - do not rebuild the per bit table */
4106    if (!net_chged) np->n_isapthsrc = FALSE;
4107   }
4108 }
4109 
4110 /*
4111  * when net deleted, remove all npps
4112  */
remove_all_npps(struct net_t * np)4113 static void remove_all_npps(struct net_t *np)
4114 {
4115  register struct net_pin_t *npp;
4116  struct net_pin_t *npp2;
4117 
4118  for (npp = np->ndrvs; npp != NULL;)
4119   {
4120    npp2 = npp->npnxt;
4121    __my_free((char *) npp, sizeof(struct net_pin_t));
4122    npp = npp2;
4123   }
4124  np->ndrvs = NULL;
4125  for (npp = np->nlds; npp != NULL;)
4126   {
4127    npp2 = npp->npnxt;
4128    __my_free((char *) npp, sizeof(struct net_pin_t));
4129    npp = npp2;
4130   }
4131  np->nlds = NULL;
4132 }
4133 
4134 /*
4135  * build (rebuild) the per bit fi/fo table
4136  * sets nfi/nfo to 0 if entire wire unc. and 1 if at least one bit has conn.
4137  * for implied driver nets, set to 1 even if no "real" drivers
4138  */
bld1vec_fifo(struct net_t * np)4139 static void bld1vec_fifo(struct net_t *np)
4140 {
4141  int32 *pbfi, *pbfo, *pbtcfo, wlen;
4142  word32 *wp;
4143 
4144  /* first try simple case */
4145  pbfi = (int32 *) __my_malloc(sizeof(int32)*np->nwid);
4146  pbfo = (int32 *) __my_malloc(sizeof(int32)*np->nwid);
4147  pbtcfo = (int32 *) __my_malloc(sizeof(int32)*np->nwid);
4148  /* inst. number not used here since never remove net iwth IS form */
4149  __bld_pb_fifo(np, pbfi, pbfo, pbtcfo, 0);
4150  wp = np->nu2.wp;
4151  if (wp == NULL)
4152   {
4153    wlen = 2*wlen_(np->nwid);
4154    wp = (word32 *) __my_malloc(wlen*WRDBYTES);
4155    memset(wp, 0, wlen*WRDBYTES);
4156    np->nu2.wp = wp;
4157   }
4158  update_vec_fifo(np, wp, pbfi, pbfo, pbtcfo);
4159  __my_free((char *) pbfi, sizeof(int32)*np->nwid);
4160  __my_free((char *) pbfo, sizeof(int32)*np->nwid);
4161  __my_free((char *) pbtcfo, sizeof(int32)*np->nwid);
4162 }
4163 
4164 /*
4165  * set per bit fi/fo values in net working fi/fo ares
4166  * tri0/tri1 implied driver net has has fi 1
4167  * if wire bit drivers timing check then still has driver and must stay
4168  */
update_vec_fifo(struct net_t * np,word32 * wpfi,int32 * pbfi,int32 * pbfo,int32 * pbtcfo)4169 static void update_vec_fifo(struct net_t *np, word32 *wpfi, int32 *pbfi,
4170  int32 *pbfo, int32 *pbtcfo)
4171 {
4172  register int32 bi;
4173  register int32 wi, biti;
4174  int32 wlen, implied_drv;
4175  word32 *wpfo;
4176 
4177  wlen = wlen_(np->nwid);
4178  wpfo = &(wpfi[wlen]);
4179  implied_drv = wire_implied_driver(np);
4180  for (bi = 0; bi < np->nwid; bi++)
4181   {
4182    wi = get_wofs_(bi);
4183    biti = get_bofs_(bi);
4184    if (pbfi[bi] == 0 && !implied_drv) wpfi[wi] &= ~(1L << biti);
4185    else wpfi[wi] |= (1L << biti);
4186    /* know 2 bits never cross word32 boundary */
4187    if (pbfo[bi] == 0 && pbtcfo[bi] == 0) wpfo[wi] &= ~(1L << biti);
4188    else wpfo[wi] |= (1L << biti);
4189   }
4190 }
4191 
4192 /*
4193  * return T if wire is implied driver type
4194  */
wire_implied_driver(struct net_t * np)4195 static int32 wire_implied_driver(struct net_t *np)
4196 {
4197  switch ((byte) np->ntyp) {
4198   case N_TRI0: case N_TRI1: case N_TRIREG: case N_SUPPLY0: case N_SUPPLY1:
4199    return(TRUE);
4200  }
4201  return(FALSE);
4202 }
4203 
4204 /*
4205  * delete cells (gate and non xmr source/destination module instances
4206  * only gate and continuous assignments are removed
4207  */
eat_cells(int32 * some_eaten)4208 static void eat_cells(int32 *some_eaten)
4209 {
4210  register int32 i, gi;
4211  register struct gate_t *gp;
4212  register struct conta_t *cap;
4213  int32 cai, out_unconn, ins_unconn;
4214 
4215  /* go through module gates tryng to remove (disconnect) */
4216  *some_eaten = FALSE;
4217  for (gi = 0; gi < __inst_mod->mgnum; gi++)
4218   {
4219    gp = &(__inst_mod->mgates[gi]);
4220    if (gp->g_gone) continue;
4221 
4222    /* can never delete pullup or pulldown */
4223    out_unconn = ins_unconn = FALSE;
4224    if (gp->g_class == GC_PULL) continue;
4225    /* for trans, in tran channels so do not process here */
4226    if (gp->g_class == GC_TRAN || gp->g_class == GC_TRANIF) continue;
4227 
4228    /* if output not gone, see if all inputs gone */
4229    if (conn_expr_gone(gp->gpins[0])) out_unconn = TRUE;
4230    for (i = 1; i < (int32) gp->gpnum; i++)
4231     { if (!conn_expr_gone(gp->gpins[i])) goto try_delete; }
4232    ins_unconn = TRUE;
4233    /* mark the gate deleted */
4234 try_delete:
4235    if (ins_unconn || out_unconn)
4236     {
4237      if (ins_unconn && out_unconn)
4238       __gfinform(448, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
4239        "%s gate %s deleteable because all ports unconnected",
4240        gp->gmsym->synam, gp->gsym->synam);
4241      else if (out_unconn)
4242       __gfinform(448, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
4243        "%s gate %s deleteable because output unconnected",
4244        gp->gmsym->synam, gp->gsym->synam);
4245      else
4246       __gfinform(448, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
4247        "%s gate %s deleteable because all inputs unconnected",
4248        gp->gmsym->synam, gp->gsym->synam);
4249      gp->g_gone = TRUE;
4250      /* gate is gone - mark all nets not already deleted for fi-fo re-eval */
4251      for (i = 1; i < (int32) gp->gpnum; i++)
4252       mark_maybe_gone_nets(gp->gpins[i]);
4253      *some_eaten = TRUE;
4254      __flgates_removable += __inst_mod->flatinum;
4255      __gates_removable++;
4256     }
4257   }
4258  /* no module removable - better to first use some kind of inlining */
4259  /* and then remove gates from that if possible */
4260 
4261  /* try to remove (disconnect) continuous assigns */
4262  /* go through module gates tryng to remove (disconnect) */
4263  for (cap = __inst_mod->mcas, cai = 0; cai < __inst_mod->mcanum; cai++, cap++)
4264   {
4265    if (cap->ca_gone) continue;
4266 
4267    /* can never delete pullup or pulldown */
4268    out_unconn = ins_unconn = FALSE;
4269    /* if output not gone, see if all inputs gone */
4270    if (conn_expr_gone(cap->lhsx)) out_unconn = TRUE;
4271    if (conn_expr_gone(cap->rhsx)) ins_unconn = TRUE;
4272    if (ins_unconn || out_unconn)
4273     {
4274      if (ins_unconn && out_unconn)
4275       __gfinform(448, cap->casym->syfnam_ind, cap->casym->sylin_cnt,
4276        "continuous assign deleteable because it has no connections");
4277      else if (out_unconn)
4278       __gfinform(448, cap->casym->syfnam_ind, cap->casym->sylin_cnt,
4279        "continuous assign deletable because left hand side drives nothing");
4280      else
4281       __gfinform(448, cap->casym->syfnam_ind, cap->casym->sylin_cnt,
4282        "continuous assign deletable because right hand side unconnected");
4283      cap->ca_gone = TRUE;
4284      mark_maybe_gone_nets(cap->lhsx);
4285      mark_maybe_gone_nets(cap->rhsx);
4286      *some_eaten = TRUE;
4287      __flcontas_removable += __inst_mod->flatinum;
4288      __contas_removable++;
4289     }
4290   }
4291 }
4292 
4293 /*
4294  * return T if expression is removable (no connectons)
4295  * notice constants cannot be deleted
4296  *
4297  * also n_mark set for undeletable nets that do not have fi-fo table
4298  * know if n_mark off and not already deleted, know fi-fo table exists
4299  */
conn_expr_gone(struct expr_t * xp)4300 static int32 conn_expr_gone(struct expr_t *xp)
4301 {
4302  register int32 bi;
4303  int32 bi2, nfi, nfo;
4304  struct net_t *np;
4305  struct expr_t *ndx, *ndx2;
4306 
4307  switch ((byte) xp->optyp) {
4308   case ID:
4309    np = xp->lu.sy->el.enp;
4310    if (!np->n_gone) return(FALSE);
4311    break;
4312   case OPEMPTY: break;
4313   case LSB:
4314    np = xp->lu.x->lu.sy->el.enp;
4315    if (!np->n_gone)
4316     {
4317      if (np->n_mark) return(FALSE);
4318      ndx = xp->ru.x;
4319      if (ndx->optyp == NUMBER)
4320       {
4321        bi = __comp_ndx(np, ndx);
4322        if (bi == -1) return(FALSE);
4323        getbit_fifo(np, bi, &nfi, &nfo);
4324        if (nfi == 0 || (nfo == 0 && !np->n_onprocrhs)) break;
4325       }
4326      return(FALSE);
4327     }
4328    break;
4329   case PARTSEL:
4330    np = xp->lu.x->lu.sy->el.enp;
4331    if (!np->n_gone)
4332     {
4333      if (np->n_mark) return(FALSE);
4334      ndx = xp->ru.x->lu.x;
4335      if ((bi = __comp_ndx(np, ndx)) == -1) return(FALSE);
4336      ndx2 = xp->ru.x->ru.x;
4337      if ((bi2 = __comp_ndx(np, ndx2)) == -1) return(FALSE);
4338      for (; bi >= bi2; bi--)
4339       {
4340        getbit_fifo(np, bi, &nfi, &nfo);
4341        if (nfi != 0 && (nfo != 0 || np->n_onprocrhs)) return(FALSE);
4342       }
4343      /* fall thru, all bits of part select unc. */
4344     }
4345    break;
4346   case LCB:
4347    /* for concatenate all components must be gone */
4348    for (ndx2 = xp->ru.x; ndx2 != NULL; ndx2 = ndx2->ru.x)
4349     { if (!conn_expr_gone(ndx2->lu.x)) return(FALSE); }
4350    break;
4351   /* anything else (such as function or arithmetic expr. must stay */
4352   default: return(FALSE);
4353  }
4354  return(TRUE);
4355 }
4356 
4357 /*
4358  * set n_isapthsrc to indicate net can be deleted and must have nlds and
4359  * ndrvs updated and maybe removed
4360  *
4361  * must mark all nets in expr.
4362  * notice constants cannot be deleted
4363  */
mark_maybe_gone_nets(struct expr_t * xp)4364 static void mark_maybe_gone_nets(struct expr_t *xp)
4365 {
4366  struct net_t *np;
4367  struct expr_t *ndx2;
4368 
4369  switch ((byte) xp->optyp) {
4370   case ID:
4371    np = xp->lu.sy->el.enp;
4372    if (!np->n_gone) np->n_isapthsrc = TRUE;
4373    break;
4374   case OPEMPTY: break;
4375   case LSB: case PARTSEL:
4376    np = xp->lu.x->lu.sy->el.enp;
4377    if (!np->n_gone) np->n_isapthsrc = TRUE;
4378    break;
4379   case LCB:
4380    /* for concatenate all components must be gone */
4381    for (ndx2 = xp->ru.x; ndx2 != NULL; ndx2 = ndx2->ru.x)
4382     mark_maybe_gone_nets(ndx2->lu.x);
4383    break;
4384  }
4385 }
4386 
4387 /*
4388  * the the fi and fo for 1 bit
4389  */
getbit_fifo(struct net_t * np,int32 bi,int32 * nfi,int32 * nfo)4390 static void getbit_fifo(struct net_t *np, int32 bi, int32 *nfi, int32 *nfo)
4391 {
4392  int32 wi, biti, wlen;
4393  word32 *wpfi, *wpfo;
4394 
4395  /* must check the bit if constant */
4396  wi = get_wofs_(bi);
4397  biti = get_bofs_(bi);
4398  /* DBG remove */
4399  if ((wpfi = (word32 *) np->nu2.wp) == NULL) __misc_terr(__FILE__, __LINE__);
4400  wlen = wlen_(np->nwid);
4401  wpfo = &(wpfi[wlen]);
4402  *nfi = ((wpfi[wi] & (1L << biti)) != 0L) ? 1 : 0;
4403  *nfo = ((wpfo[wi] & (1L << biti)) != 0L) ? 1 : 0;
4404 }
4405 
4406 /*
4407  * ROUTINES TO DETERMINE IF GATE CAN BE OPTIMIZED (USED ACC ROUTINE)
4408  */
4409 
4410 /*
4411  * return T if gate is acceleratable buf or not
4412  * accelerate classes are 0 std non accel., 2 buf/not, 3 acc. logic
4413  *
4414  * will not accelerate if: 1) >3 inputs, 2) drives strength, 3) 1 in and style
4415  * 4) drives fi>1 wire, 5) output is not scalar or constant bit select,
4416  * 6) inputs not accelerable
4417  *
4418  * notice whether or not has delay does effect acc class
4419  */
__get_acc_class(struct gate_t * gp)4420 extern int32 __get_acc_class(struct gate_t *gp)
4421 {
4422  register int32 gi;
4423  int32 acc_class, st_on_input, wire_pthdel;
4424  word32 gatid;
4425  struct expr_t *xp;
4426  struct net_t *np;
4427 
4428  acc_class = ACC_NONE;
4429  st_on_input = FALSE;
4430  /* can have up to 3 inputs and 1 output for acceleration - fits in byte */
4431  if (gp->g_hasst || gp->gpnum > 4) return(ACC_STD);
4432  gatid = gp->gmsym->el.eprimp->gateid;
4433  switch ((byte) gatid) {
4434   case G_NOT: case G_BUF: case G_ASSIGN: acc_class = ACC_BUFNOT; break;
4435   case G_NAND: case G_BITREDAND: case G_BITREDOR:
4436   case G_NOR: case G_BITREDXOR: case G_REDXNOR:
4437    /* never accelerate degenerate 2 input gates that are usually >=3 in */
4438    if (gp->gpnum == 2) return(ACC_STD);
4439    acc_class = ACC_4IGATE;
4440    break;
4441   default: return(ACC_STD);
4442  }
4443  /* only get here for logic gates - mos, tran, etc. always std */
4444  /* output must be simple wire or constant bsel from wire */
4445  xp = gp->gpins[0];
4446  /* cannot be fi>1 and know if in tran channel will be fi>1 */
4447  if (xp->x_multfi) return(ACC_STD);
4448  if (xp->optyp == ID)
4449   {
4450    np = xp->lu.sy->el.enp;
4451    if (np->n_isavec || np->n_stren) return(ACC_STD);
4452   }
4453  else if (xp->optyp == LSB)
4454   {
4455    if (xp->ru.x->optyp != NUMBER) return(ACC_STD);
4456    np = xp->lu.x->lu.sy->el.enp;
4457    if (np->n_stren) return(ACC_STD);
4458   }
4459  else return(ACC_STD);
4460  /* DBG remove */
4461  if (np->ntraux != NULL) __misc_terr(__FILE__, __LINE__);
4462  /* --- */
4463  if (np->nrngrep == NX_DWIR) wire_pthdel = TRUE; else wire_pthdel = FALSE;
4464 
4465  /* all inputs must be XL accelerateable */
4466  for (st_on_input = FALSE, gi = 0; gi < (int32) gp->gpnum; gi++)
4467   {
4468    xp = gp->gpins[gi];
4469    if (xp->optyp == ID)
4470     {
4471      np = xp->lu.sy->el.enp;
4472      if (np->n_isavec) return(ACC_STD);
4473      if (np->n_stren) st_on_input = TRUE;
4474     }
4475    /* strength on bit select ok, slower does not need separate case */
4476    else if (xp->optyp == LSB)
4477     {
4478      if (xp->ru.x->optyp != NUMBER) return(ACC_STD);
4479      /* SJM 05/17/03 - array (memory) selects on input must not accelerate */
4480      if (xp->lu.x->lu.sy->el.enp->n_isarr) return(ACC_STD);
4481     }
4482    else return(ACC_STD);
4483   }
4484  if (st_on_input)
4485   {
4486    if (acc_class == ACC_BUFNOT) acc_class = ACC_STIBUFNOT;
4487    else if (acc_class == ACC_4IGATE) acc_class = ACC_ST4IGATE;
4488   }
4489  gp->g_pdst = wire_pthdel;
4490  return(acc_class);
4491 }
4492 
4493 /*
4494  * ROUTINES TO CONVERT FROM DT_NONE TO #0 FOR DELAY ANNOTATION
4495  */
4496 
4497 /*
4498  * add delay (set to #0) to gate
4499  *
4500  * know called after prep
4501  */
__add_gate_pnd0del(struct gate_t * gp,struct mod_t * mdp,char * sdfmsg)4502 extern int32 __add_gate_pnd0del(struct gate_t *gp, struct mod_t *mdp,
4503  char *sdfmsg)
4504 {
4505  register int32 gsi;
4506  int32 nbytes;
4507  struct net_t *np;
4508  struct primtab_t *ptp;
4509  struct expr_t *xp;
4510 
4511  ptp = gp->gmsym->el.eprimp;
4512  /* make sure gate can have delay */
4513  if (ptp->gateid == G_TRAN || ptp->gateid == G_RTRAN)
4514   {
4515    /* rnotice error here will stop simulation */
4516    if (sdfmsg != NULL)
4517     __pv_ferr(1199,
4518      "%s delay annotate to %s gate %s for which delay illegal", sdfmsg,
4519      gp->gmsym->synam, gp->gsym->synam);
4520    else __vpi_err(1893, vpiError,
4521     "vpi_put_delays illegal for %s gate %s for which delay illegal",
4522     gp->gmsym->synam, gp->gsym->synam);
4523    return(FALSE);
4524   }
4525  /* set delay to pnd 0 */
4526  gp->g_du.d1v = (word64 *) __my_malloc(sizeof(word64));
4527  gp->g_du.d1v[0] = 0ULL;
4528  gp->g_delrep = DT_1V;
4529 
4530  /* allocate and initialize the inertial pending schd event table */
4531  nbytes = mdp->flatinum*sizeof(i_tev_ndx);
4532  gp->schd_tevs = (i_tev_ndx *) __my_malloc(nbytes);
4533  for (gsi = 0; gsi < mdp->flatinum; gsi++) gp->schd_tevs[gsi] = -1;
4534 
4535  /* if accelerated set g resist if driven wire has delay or path dest */
4536  if (__gate_is_acc(gp))
4537   {
4538    xp = gp->gpins[0];
4539    if (xp->optyp == ID) np = xp->lu.sy->el.enp;
4540    else if (xp->optyp == LSB) np = xp->lu.x->lu.sy->el.enp;
4541    else { np = NULL;  __case_terr(__FILE__, __LINE__); }
4542    if (np->nrngrep == NX_DWIR) gp->g_pdst = TRUE;
4543   }
4544  return(TRUE);
4545 }
4546 
4547 /*
4548  * add conta delay (add drivers and internal conta value too) (set to #0)
4549  *
4550  * know called after prep and know no delay
4551  * SJM 09/29/02 - if per bit this must set master delay and PB drv/schd
4552  */
__add_conta_pnd0del(struct conta_t * cap,struct mod_t * mdp,char * sdfmsg)4553 extern int32 __add_conta_pnd0del(struct conta_t *cap, struct mod_t *mdp,
4554  char *sdfmsg)
4555 {
4556  register int32 i, bi;
4557  struct conta_t *pbcap;
4558 
4559  /* make sure gate can have delay */
4560  if (cap->lhsx->getpatlhs)
4561   {
4562    /* rnotice error here will stop simulation */
4563    __bld_lineloc(__xs, cap->casym->syfnam_ind, cap->casym->sylin_cnt);
4564    if (sdfmsg != NULL)
4565     __pv_ferr(1379,
4566      "%s delay annotate to $getpattern continuous assign at %s illegal",
4567      sdfmsg, __xs);
4568    else __vpi_err(1905, vpiError,
4569      "vpi_put_delays illegal for $getpattern continuous assign at %s", __xs);
4570    return(FALSE);
4571   }
4572 
4573  if (!cap->ca_pb_sim)
4574   {
4575    /* since before any sim or new PLI added del, initialized value correct */
4576    if (!cap->lhsx->x_multfi)
4577     {
4578      /* DBG remove --- */
4579      if (cap->ca_drv_wp.wp != NULL) __misc_terr(__FILE__, __LINE__);
4580      /* --- */
4581      __allocinit_perival(&(cap->ca_drv_wp), mdp->flatinum,
4582       cap->lhsx->szu.xclen, TRUE);
4583     }
4584    /* DBG remove --- */
4585    if (cap->schd_drv_wp.wp != NULL) __misc_terr(__FILE__, __LINE__);
4586    /* --- */
4587    /* nothing will be scheduled and this will not be allocated */
4588    __allocinit_perival(&(cap->schd_drv_wp), mdp->flatinum,
4589    cap->lhsx->szu.xclen, TRUE);
4590    cap->caschd_tevs = (i_tev_ndx *)
4591     __my_malloc(mdp->flatinum*sizeof(i_tev_ndx));
4592    for (i = 0; i < mdp->flatinum; i++) cap->caschd_tevs[i] = -1;
4593   }
4594  else
4595   {
4596    for (bi = 0; bi < cap->lhsx->szu.xclen; bi++)
4597     {
4598      pbcap = &(cap->pbcau.pbcaps[bi]);
4599      /* DBG remove */
4600      if (pbcap->lhsx->szu.xclen != 1) __misc_terr(__FILE__, __LINE__);
4601      /* --- */
4602 
4603      /* since before any sim or new PLI added del, init value correct */
4604      /* SJM 09/28/02 - if master cat expr fi>1, need all per bits */
4605      if (!cap->lhsx->x_multfi)
4606       {
4607        /* DBG remove --- */
4608        if (pbcap->ca_drv_wp.wp != NULL) __misc_terr(__FILE__, __LINE__);
4609        /* --- */
4610        __allocinit_perival(&(pbcap->ca_drv_wp), mdp->flatinum, 1, TRUE);
4611       }
4612      /* DBG remove --- */
4613      if (pbcap->schd_drv_wp.wp != NULL) __misc_terr(__FILE__, __LINE__);
4614      /* --- */
4615      /* nothing will be scheduled and this will not be allocated */
4616      __allocinit_perival(&(pbcap->schd_drv_wp), mdp->flatinum, 1, TRUE);
4617      pbcap->caschd_tevs = (i_tev_ndx *)
4618       __my_malloc(mdp->flatinum*sizeof(i_tev_ndx));
4619      for (i = 0; i < mdp->flatinum; i++) pbcap->caschd_tevs[i] = -1;
4620     }
4621   }
4622 
4623  /* SJM 09/28/02 - delay always in master never per bit */
4624  /* set delay to pnd 0 */
4625  cap->ca_du.d1v = (word64 *) __my_malloc(sizeof(word64));
4626  cap->ca_du.d1v[0] = 0ULL;
4627  cap->ca_delrep = DT_1V;
4628 
4629  return(TRUE);
4630 }
4631 
4632 /*
4633  * ROUTINES TO REMOVE ALL 0 DELAY PATHS
4634  */
4635 
4636 /*
4637  * remove 0 path delays
4638  *
4639  * all this does is link out npp - rest of d.s. small and interlinked
4640  * only remove source tchg npps if not part of other non removed path
4641  *
4642  * FIXME - for now not removing source changes - set ref. count but not using
4643  * will do extra work in recording each path source change but no path
4644  * processing because destinations not path dests any more
4645  */
__rem_0path_dels(void)4646 extern void __rem_0path_dels(void)
4647 {
4648  register int32 pi;
4649  register struct net_pin_t *npp;
4650  struct spcpth_t *pthp;
4651  int32 has_0del, dbi, dbi2, ni;
4652  int32 num_pthrem_mods, num_pthrems, num_flat_pthrems;
4653  int32 num_pthrem_nets, num_flat_pthrem_nets;
4654  struct mod_t *mdp;
4655  struct pathel_t *spep, *dpep;
4656  struct npaux_t *npauxp;
4657  struct net_t *snp, *dnp;
4658  struct pthdst_t *pdp, *pdp2, *last_pdp;
4659  struct rngdwir_t *dwirp;
4660  struct expr_t *lhsx;
4661 
4662  num_pthrem_mods =  num_pthrems = num_flat_pthrems = 0;
4663  num_pthrem_nets = num_flat_pthrem_nets = 0;
4664  for (mdp = __modhdr; mdp != NULL; mdp = mdp->mnxt)
4665   {
4666    if (mdp->mspfy == NULL || mdp->mspfy->spcpths == NULL) continue;
4667 
4668    /* know each delay is NUMBER or REALNUM */
4669    has_0del = FALSE;
4670    for (pthp = mdp->mspfy->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
4671     {
4672      if (pthp->pth_gone) continue;
4673 
4674      if (__chk_0del(pthp->pth_delrep, pthp->pth_du, mdp) == DBAD_0)
4675       {
4676        pthp->pth_0del_rem = TRUE;
4677        num_pthrem_mods++;
4678        has_0del = TRUE;
4679       }
4680     }
4681    if (!has_0del) continue;
4682 
4683    /* know at least one path must be removed */
4684    /* step 1: set all path src ref counts - >1 dests for one src possible */
4685    for (pthp = mdp->mspfy->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
4686     {
4687      /* think impossible for some paths to be gone and make it to prep */
4688      if (pthp->pth_gone) continue;
4689 
4690      for (pi = 0; pi <= pthp->last_pein; pi++)
4691       {
4692        spep = &(pthp->peins[pi]);
4693        snp = spep->penp;
4694        for (npp = snp->nlds; npp != NULL; npp = npp->npnxt)
4695         {
4696          if (npp->npntyp != NP_TCHG || npp->chgsubtyp != NPCHG_PTHSRC)
4697           continue;
4698          /* know tchg sources always per bit - for scalar 0 */
4699 
4700          /* path source npp's always one bit, -1 only if scalar */
4701          if ((npauxp = npp->npaux) != NULL) dbi = npauxp->nbi1;
4702          else dbi = -1;
4703          if (spep->pthi1 == -1 || (dbi <= spep->pthi1 && dbi >= spep->pthi2))
4704           {
4705            /* inc ref. count - know value previously inited to 0 */
4706            (npp->elnpp.etchgp->lastchg[0])++;
4707           }
4708         }
4709       }
4710     }
4711    /* step 2: actually remove path dst npp's and decr. pstchg source counts */
4712    for (pthp = mdp->mspfy->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
4713     {
4714      if (!pthp->pth_0del_rem) continue;
4715 
4716      num_pthrems++;
4717      num_flat_pthrems += mdp->flatinum;
4718 
4719      for (pi = 0; pi <= pthp->last_peout; pi++)
4720       {
4721        dpep = &(pthp->peouts[pi]);
4722        dnp = dpep->penp;
4723 
4724        for (npp = dnp->nlds; npp != NULL; npp = npp->npnxt)
4725         {
4726          if (npp->npntyp != NP_TCHG || npp->chgsubtyp != NPCHG_PTHSRC)
4727           continue;
4728          if (!dnp->n_isavec) dbi = dbi2 = 0;
4729          else
4730           {
4731            if (dpep->pthi1 == -1) { dbi = dnp->nwid - 1; dbi2 = 0; }
4732            else { dbi = dpep->pthi1; dbi2 = dpep->pthi2; }
4733           }
4734 
4735          /* for every bit of destination path element */
4736          dwirp = dnp->nu.rngdwir;
4737          for (; dbi >= dbi2; dbi--)
4738           {
4739            last_pdp = NULL;
4740            for (pdp = dwirp->n_du.pb_pthdst[dbi]; pdp != NULL;)
4741             {
4742              pdp2 = pdp->pdnxt;
4743              if (pdp->pstchgp->chgu.chgpthp == pthp)
4744               {
4745                if (last_pdp == NULL) dwirp->n_du.pb_pthdst[dbi] = pdp->pdnxt;
4746                else last_pdp->pdnxt = pdp->pdnxt;
4747                __my_free((char *) pdp, sizeof(struct pthdst_t));
4748               }
4749              else last_pdp = pdp;
4750              pdp = pdp2;
4751             }
4752           }
4753         }
4754       }
4755     }
4756 
4757    /* for path dest. nets with all pthdst removed - set as non path dest. */
4758    for (ni = 0, dnp = &(mdp->mnets[0]); ni < mdp->mnnum; ni++, dnp++)
4759     {
4760      if (!dnp->n_isapthdst) continue;
4761 
4762      dwirp = dnp->nu.rngdwir;
4763      if (!dnp->n_isavec)
4764       {
4765        if (dwirp->n_du.pb_pthdst[0] != NULL) continue;
4766       }
4767      else
4768       {
4769        for (dbi = dnp->nwid - 1; dbi >= 0; dbi--)
4770         {
4771          if (dwirp->n_du.pb_pthdst[dbi] != NULL) continue;
4772         }
4773       }
4774      /* convert to non path dest. */
4775      __my_free((char *) dwirp->n_du.pb_pthdst,
4776       dnp->nwid*sizeof(struct pthdst_t *));
4777      dwirp->n_du.d1v = NULL;
4778      dwirp->n_delrep = DT_NONE;
4779      dnp->n_isapthdst = FALSE;
4780      num_pthrem_nets++;
4781      num_flat_pthrem_nets += mdp->flatinum;
4782      /* SJM 07/23/03 - must turn off all lhsx ndel marks for completely */
4783      /* removed paths where driver is gate out or conta */
4784      for (npp = dnp->ndrvs; npp != NULL; npp = npp->npnxt)
4785       {
4786        if (npp->npntyp == NP_GATE) lhsx = npp->elnpp.egp->gpins[0];
4787        else if (npp->npntyp == NP_CONTA) lhsx = npp->elnpp.ecap->lhsx;
4788        else continue;
4789 
4790        /* DBG remove */
4791        if (!lhsx->lhsx_ndel) __misc_terr(__FILE__, __LINE__);
4792        /* -- */
4793        if (lhsx->lhsx_ndel) lhsx->lhsx_ndel = FALSE;
4794       }
4795     }
4796 
4797    /* step 3: reset lastchg field and remove if needed - no longer ref cnt */
4798    for (pthp = mdp->mspfy->spcpths; pthp != NULL; pthp = pthp->spcpthnxt)
4799     {
4800      if (pthp->pth_gone) continue;
4801 
4802      for (pi = 0; pi <= pthp->last_pein; pi++)
4803       {
4804        spep = &(pthp->peins[pi]);
4805        snp = spep->penp;
4806        for (npp = snp->nlds; npp != NULL; npp = npp->npnxt)
4807         {
4808          if (npp->npntyp != NP_TCHG || npp->chgsubtyp != NPCHG_PTHSRC)
4809           continue;
4810          /* path source npp's always one bit, -1 only if scalar */
4811          if ((npauxp = npp->npaux) != NULL) dbi = npauxp->nbi1;
4812          else dbi = -1;
4813          if (spep->pthi1 == -1 || (dbi <= spep->pthi1 && dbi >= spep->pthi2))
4814           {
4815            /* reset ref. count */
4816            npp->elnpp.etchgp->lastchg[0] = 0ULL;
4817           }
4818         }
4819       }
4820     }
4821   }
4822  if (num_pthrem_mods != 0 && __verbose)
4823   {
4824    __cv_msg(
4825     "  %d zero delay paths (%d flat) in %d types removed - no effect.\n",
4826     num_pthrems, num_flat_pthrems, num_pthrem_mods);
4827   }
4828  if (num_pthrem_nets != 0 && __verbose)
4829   {
4830    __cv_msg(
4831     "  %d nets (%d flat) no longer path destinations (all paths zero delay).\n",
4832     num_pthrem_nets, num_flat_pthrem_nets);
4833   }
4834 }
4835