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