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 delay preparation and changing routines
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36 
37 #ifdef __DBMALLOC__
38 #include "../malloc.h"
39 #endif
40 
41 #include "v.h"
42 #include "cvmacros.h"
43 
44 /* local prototypes */
45 static void delx_to_deltim(word64 *, struct expr_t *, struct xstk_t *);
46 static void emit_reprepdev_verbmsg(struct gate_t *, struct gate_t *,
47  struct mod_t *, struct itree_t *, int32);
48 static void emit_reprepconta_verbmsg(struct conta_t *, struct gate_t *,
49  struct mod_t *, struct itree_t *, int32);
50 static void emit_reprepnet_verbmsg(struct net_t *, struct gate_t *,
51  struct mod_t *, struct itree_t *, int32);
52 static void emit_reprepstmt_verbmsg(struct st_t *, struct gate_t *,
53  struct mod_t *, struct itree_t *, int32);
54 static void emit_reprepiopath_verbmsg(struct spcpth_t *, struct gate_t *,
55  struct mod_t *, struct itree_t *, int32);
56 static void emit_repreptclim_verbmsg(struct tchk_t *, struct gate_t *,
57  struct mod_t *, struct itree_t *, word32, int32);
58 static void prep2_delay(struct gate_t *, struct paramlst_t *, int32, int32);
59 static void nonis_to_delval(word64 *, struct expr_t *);
60 static void prep_1delform(struct gate_t *, struct expr_t *);
61 static void convert_trireg_1vto4v(struct gate_t *);
62 static void prep_prim_is_dels(struct gate_t *, struct expr_t **, int32, int32);
63 static void prep_path_is_dels(struct gate_t *, struct expr_t **, int32);
64 static void fill_1col_isdel(word64 *, int32, struct expr_t *, int32);
65 static void chg1vform_1instdel(struct gate_t *, struct itree_t *,
66  struct gate_t *);
67 static void set_1is1val(struct gate_t *, int32, int32, word64 *, int32);
68 static void chg4vform_1instdel(struct gate_t *, struct itree_t *,
69  struct gate_t *);
70 static void set_1is416val(struct gate_t *, int32, int32, word64 *, int32);
71 static void chg16vform_1instdel(struct gate_t *, struct itree_t *,
72  struct gate_t *);
73 static void cnv_1is_to_4is(struct gate_t *, int32, int32, int32);
74 static void cnv_1is_to_16is(struct gate_t *, int32, int32, int32);
75 static void create_disv(struct gate_t *, int32, int32, word64 *, int32);
76 static int32 get_ispack(word64);
77 static void unpack_isv1_to_isv2(struct gate_t *, int32, int32);
78 static void unpack_isv1_to_isv(struct gate_t *, int32, int32);
79 static void unpack_isv2_to_isv(struct gate_t *, int32, int32);
80 static void zero_unused_16v(word64 *);
81 static void real_to_ticks(word64 *, double, struct mod_t *);
82 
83 /* extern prototypes (maybe defined in this module) */
84 extern void __hizstrengate_getdel(word64 *, register struct gate_t *);
85 extern void __get_del(register word64 *, register union del_u, word32);
86 extern int32 __real_to_v64tim(word64 *, double);
87 extern void __cnv_ticks_tonum64(word64 *, word64, struct mod_t *);
88 extern void __re_prep_dels(struct net_t *, struct itree_t *, struct mod_t *,
89  int32);
90 extern void __prep_delay(struct gate_t *, struct paramlst_t *, int32, int32, char *, int32, struct sy_t *, int32);
91 extern void __free_del(union del_u, word32, int32);
92 extern void __free_dellst(struct paramlst_t *);
93 extern void __fill_4vconst(word64 *, word64 *, word64 *, word64 *, int32, int32);
94 extern void __fill_16vconst(word64 *, word64 *, int32);
95 extern void __chg_1inst_del(struct gate_t *, struct itree_t *, struct gate_t *);
96 extern char *__bld_delay_str(char *, union del_u, word32);
97 extern void __extract_delval(word64 *, int32 *, union del_u, word32);
98 extern void __map_16v_to_12vform(word64 *, word64 *);
99 extern void __try_reduce_16vtab(word64 *, int32 *);
100 extern void __do_showdel_stask(struct expr_t *, char *);
101 extern struct xstk_t *__eval2_xpr(register struct expr_t *);
102 extern char *__msgexpr_tostr(char *, struct expr_t *);
103 extern char *__to_timstr(char *, word64 *);
104 extern int32 __v64_to_real(double *, word64 *);
105 extern char *__msg2_blditree(char *, struct itree_t *);
106 extern char *__bld_lineloc(char *, word32, int32);
107 extern char *__to_tcnam(char *, word32);
108 extern struct paramlst_t *__copy_dellst(struct paramlst_t *);
109 extern int32 __chk_delparams(struct paramlst_t *, char *, int32);
110 extern void __chk_spec_delay(struct expr_t *, char *);
111 extern char *__my_malloc(int32);
112 extern void __my_free(char *, int32);
113 extern struct expr_t *__copy_expr(struct expr_t *);
114 extern void __free_xtree(struct expr_t *);
115 extern void __push_wrkitstk(struct mod_t *, int32);
116 extern void __pop_wrkitstk(void);
117 extern int32 __is_lnegative(word32 *, int32);
118 
119 extern void __cv_msg(char *, ...);
120 extern void __gfwarn(int32, word32, int32, char *, ...);
121 extern void __sgfwarn(int32, char *, ...);
122 extern void __gferr(int32, word32, int32, char *, ...);
123 extern void __sgferr(int32, char *, ...);
124 extern void __dbg_msg(char *, ...);
125 extern void __arg_terr(char *, int32);
126 extern void __case_terr(char *, int32);
127 extern void __misc_terr(char *, int32);
128 
129 extern int32 errno;
130 extern word32 __masktab[];
131 
132 #if defined(__SVR4) || defined(__hpux)
133 #define drem fmod
134 #endif
135 
136 double __dbl_toticks_tab[] = { 1.0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
137  1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15 };
138 
139 /*
140  * DELAY ACCESS ROUTINES
141  */
142 
143 /*
144  * get a primitive delay for a gate that drives highz[01]
145  * this is only called if g_hasst T
146  *
147  * primitive gate delays always determined solely by new value
148  * and since wire (not gate) driven to z because of strength use wire for
149  * delay
150  */
__hizstrengate_getdel(word64 * gdel,register struct gate_t * gp)151 extern void __hizstrengate_getdel(word64 *gdel, register struct gate_t *gp)
152 {
153  register word32 save_val, stren0;
154 
155  save_val = __new_gateval;
156  /* know one or other must be 0 strength */
157  stren0 = (gp->g_stval >> 3) & 7;
158  if (stren0 == 0) { if (save_val == 0) __new_gateval = 2; }
159  else { if (save_val == 1) __new_gateval = 2; }
160  __get_del(gdel, gp->g_du, gp->g_delrep);
161  __new_gateval = save_val;
162 }
163 
164 /*
165  * get the delay value needed for transition to global __new_gateval
166  * know no delay case already handled
167  *
168  * know 4 array already set with right values if gate or conta
169  * global new gateval must be set to new value (0-3) (0,1,z,x) and
170  * for continuous assign (know > 1) must be corrected (0 if all 0's,
171  * (2 if all z's, else 1 (rise)
172  *
173  * notice this can return a 0 delay that needs to be on pound 0 queue
174  * also these have all been scaled
175  *
176  * need to remove all but low 3 bits because can be used for strenght vals
177  */
__get_del(register word64 * gdel,register union del_u du,word32 drep)178 extern void __get_del(register word64 *gdel, register union del_u du,
179  word32 drep)
180 {
181  register int32 ind;
182  word64 dv1, dv0;
183  struct xstk_t *xsp;
184  struct expr_t *dxp;
185  struct thread_t *sav_curthp;
186 
187  /* -- DBG remove
188   extern void __dbg_dump_del(union del_u, word32);
189 
190  if (__debug_flg) __dbg_dump_del(du, drep);
191  -- */
192 
193  switch ((byte) drep) {
194   case DT_1V: *gdel = du.d1v[0]; break;
195   case DT_IS1V: *gdel = du.dis1v[__inum]; break;
196   case DT_IS1V1:
197    *gdel = (word64) du.dis1v1[__inum];
198    break;
199   case DT_IS1V2:
200    *gdel = (word64) du.dis1v2[__inum];
201    break;
202   case DT_4V:
203    /* notice here the array has precomputed the delay for the new value */
204    /* including min comp. for x/z */
205    *gdel = du.d4v[__new_gateval & 3];
206    break;
207   case DT_IS4V:
208    /* this is time width 32 bit dependent */
209    *gdel = du.d4v[4*__inum + (__new_gateval & 3)];
210    break;
211   case DT_IS4V1:
212    *gdel = (word64) du.dis4v1[4*__inum + (__new_gateval & 3)];
213    break;
214   case DT_IS4V2:
215    *gdel = (word64) du.dis4v2[4*__inum + (__new_gateval & 3)];
216    break;
217   case DT_16V:
218    ind = ((__new_gateval & 3) << 2 | (__old_gateval & 3)) & 0xf;
219    *gdel = du.d16v[ind];
220    break;
221   case DT_IS16V:
222    /* notice size is 16 since x->x transition needed for strengths only chg */
223    ind = 16*__inum
224     + ((((__new_gateval & 3) << 2) | (__old_gateval & 3)) &0xf);
225    *gdel = du.dis16v[ind];
226    break;
227   case DT_IS16V1:
228    ind = 16*__inum
229     + ((((__new_gateval & 3) << 2) | (__old_gateval & 3)) & 0xf);
230    *gdel = (word64) du.dis16v1[ind];
231    break;
232   case DT_IS16V2:
233    ind = 16*__inum
234     + ((((__new_gateval & 3) << 2) | (__old_gateval & 3)) & 0xf);
235    *gdel = (word64) du.dis16v2[ind];
236    break;
237   case DT_1X:
238    /* must run delay expr. eval without context thread */
239    sav_curthp = __cur_thd;
240    __cur_thd = NULL;
241 
242    xsp = __eval_xpr(du.d1x);
243    /* this handles required scaling */
244    delx_to_deltim(gdel, du.d1x, xsp);
245    __pop_xstk();
246    __cur_thd = sav_curthp;
247    break;
248   case DT_4X:
249    /* know at least 2 delays */
250    /* trick here is do not know expr. ordering so can't precompute to z */
251    /* must run delay expr. eval without context thread */
252    sav_curthp = __cur_thd;
253    __cur_thd = NULL;
254    dxp = du.d4x[__new_gateval];
255    if (dxp == NULL)
256     {
257      dxp = du.d4x[0];
258      xsp = __eval_xpr(dxp);
259      delx_to_deltim(&dv0, dxp, xsp);
260      __pop_xstk();
261      dxp = du.d4x[1];
262      xsp = __eval_xpr(dxp);
263 
264      delx_to_deltim(&dv1, dxp, xsp);
265      __pop_xstk();
266      *gdel = (dv1 <= dv0) ? dv1 : dv0;
267      __cur_thd = sav_curthp;
268      return;
269     }
270    xsp = __eval_xpr(dxp);
271    delx_to_deltim(gdel, dxp, xsp);
272    __pop_xstk();
273    __cur_thd = sav_curthp;
274    break;
275   default: __case_terr(__FILE__, __LINE__);
276  }
277 }
278 
279 /*
280  * DELAY CONVERSION ROUTINES
281  */
282 
283 /*
284  * given a delay expression - scale and convert to word64 delay value
285  * no checking - 64 bits
286  */
delx_to_deltim(word64 * dval,struct expr_t * dxp,struct xstk_t * xsp)287 static void delx_to_deltim(word64 *dval, struct expr_t *dxp,
288  struct xstk_t *xsp)
289 {
290  word64 t;
291  double d1;
292  struct mod_t *mdp;
293 
294  mdp = __inst_mod;
295  if (dxp->is_real)
296   {
297    memcpy(&d1, xsp->ap, sizeof(double));
298    real_to_ticks(dval, d1, mdp);
299    return;
300   }
301  if (xsp->bp[0] != 0L)
302   {
303    __sgfwarn(565, "delay expression #(%s) evaluates to x/z changed to #0",
304     __msgexpr_tostr(__xs, dxp));
305    t = 0ULL;
306    *dval = t;
307    return;
308   }
309  t = (word64) xsp->ap[0];
310  if (xsp->xslen > WBITS) t |= (((word64) xsp->ap[1]) << 32);
311 
312  if (!mdp->mno_unitcnv) cnv_num64to_ticks_(*dval, t, mdp);
313  else *dval = t;
314 }
315 
316 /*
317  * convert a real to ticks - here must scale (multiply before) conversion
318  * rule is: multiply to get ticks, round, then convert to time
319  *
320  * notice this is only routine that is called even for mods that do not
321  * need scaling
322  */
real_to_ticks(word64 * tim,double d1,struct mod_t * mdp)323 static void real_to_ticks(word64 *tim, double d1, struct mod_t *mdp)
324 {
325  int32 unit;
326 
327  if (!mdp->mno_unitcnv)
328   {
329     unit = __des_timeprec - mdp->mtime_units;
330     d1 *= __dbl_toticks_tab[unit];
331   }
332  if (!__real_to_v64tim(tim, d1))
333   __sgfwarn(563, "error in conversion of real %g to 64 bit time - set to %s",
334    d1, __to_timstr(__xs, tim));
335 }
336 
337 /*
338  * convert a real value to a 64 bit word32 time
339  * uses normal Verilog rounding from 0.5
340  * return F if error in conversion but still set some time value
341  * illegal if called with negative real
342  *
343  * this now assumes that that double to word32 conversion works
344  * used to not work on Machten
345  */
__real_to_v64tim(word64 * tim,double dv)346 extern int32 __real_to_v64tim(word64 *tim, double dv)
347 {
348  *tim = (word64) (dv + 0.500000);
349  return(TRUE);
350 
351  /* ---
352  double d1, d2, d3, dbase;
353  int32 expbits, good;
354 
355  good = TRUE;
356  tim->th = tim->tl = 0L;
357  if (dv < 0.0) return(FALSE);
358  -* see if value fits in 31 bits *-
359  if (dv <= (double) 0x7fffffff)
360   {
361    -* cannot use c compiler rounding since verilog is to higher magnitude *-
362    tim->tl = ver_rword(dv);
363    return(TRUE);
364   }
365 
366  -* first catch overflow *-
367  d1 = frexp(dv, &expbits);
368  if (errno != 0) good = FALSE;
369  -* know since 0.5 <= d1 < 1.0 will be no bigger than 2*62 - 1 *-
370  if (expbits > 64) return(FALSE);
371  dv += 0.500000000;
372  -* base is 2**32 *-
373  dbase = ((double) ((word32) 0xffffffff)) + 1.0;
374  d1 = floor(dv/dbase);
375  d2 = drem(dv, dbase);
376  tim->th = (word32) d1;
377  tim->tl = (word32) d2;
378  -* DBG remove ---
379  __v64_to_real(&d3, tim);
380  if (fabs(dv - d3) >= EPSILON) __misc_terr(__FILE__, __LINE__);
381  --- *-
382  return(good);
383  -- */
384 }
385 
386 /*
387  * convert from ticks to a module's user time - divide by units pow 10 diff
388  * only called for modules where time needs unscaling
389  * know this will always succeed
390  */
__cnv_ticks_tonum64(word64 * usertim,word64 tickstim,struct mod_t * mdp)391 extern void __cnv_ticks_tonum64(word64 *usertim, word64 tickstim,
392  struct mod_t *mdp)
393 {
394  word64 quot, rem, tscale;
395  int32 unit;
396 
397  /* this subtract backwards here */
398  unit = __des_timeprec - mdp->mtime_units;
399 
400  tscale = __itoticks_tab[unit];
401  rem = tickstim % tscale;
402  quot = tickstim/tscale;
403  if (rem != 0ULL)
404   {
405    /* divide scale period by 2 */
406    tscale = tscale/2;
407    if (rem >= tscale) quot++;
408   }
409  *usertim = quot;
410 }
411 
412 /*
413  * DELAY PREPARATION ROUTINES
414  */
415 
416 /*
417  * after parameter change during SDF annotation re-prepare delays
418  *
419  * for each parameter parm npp list contains each RHS delay expr.
420  * reference to parameter - afer change re-prep each delay again
421  */
__re_prep_dels(struct net_t * parmnp,struct itree_t * itp,struct mod_t * mdp,int32 from_vpi)422 extern void __re_prep_dels(struct net_t *parmnp, struct itree_t *itp,
423  struct mod_t *mdp, int32 from_vpi)
424 {
425  register struct parmnet_pin_t *pnpp;
426  int32 sav_declobj;
427  struct gate_t gwrk;
428  struct net_t *np;
429  struct gate_t *gp;
430  struct conta_t *cap;
431  struct st_t *stp;
432  struct delctrl_t *dctp;
433  struct sy_t tmpsym;
434  struct spcpth_t *pthp;
435  struct tchk_t *tcp;
436  char s1[RECLEN];
437 
438  __push_wrkitstk(mdp, 0);
439  for (pnpp = (struct parmnet_pin_t *) parmnp->nlds; pnpp != NULL;
440   pnpp = pnpp->pnpnxt)
441   {
442    switch ((byte) pnpp->pnptyp) {
443     case PNP_GATEDEL:
444      gp = pnpp->elpnp.egp;
445      __prep_delay(&gwrk, pnpp->pnplp, FALSE, FALSE, "prim delay annotate",
446       FALSE, gp->gsym, FALSE);
447      if (__nd_neg_del_warn)
448       {
449        __gferr(972, gp->gsym->syfnam_ind, gp->gsym->sylin_cnt,
450         "gate %s annotated delay negative (0 used)", gp->gsym->synam);
451         __nd_neg_del_warn = FALSE;
452       }
453      /* free old */
454      __free_del(gp->g_du, gp->g_delrep, mdp->flatinum);
455      gp->g_du = gwrk.g_du;
456      gp->g_delrep = gwrk.g_delrep;
457      if (__sdf_verbose && (!from_vpi || __debug_flg))
458       emit_reprepdev_verbmsg(gp, &gwrk, mdp, itp, from_vpi);
459      break;
460     case PNP_CONTADEL:
461      /* SJM 09/28/02 - know reprep list always master even if per bit */
462      cap = pnpp->elpnp.ecap;
463 
464      __prep_delay(&gwrk, pnpp->pnplp, FALSE, FALSE,
465       "continuous assignment delay", FALSE, cap->casym, FALSE);
466      if (__nd_neg_del_warn)
467       {
468        __gferr(973, cap->casym->syfnam_ind, cap->casym->sylin_cnt,
469         "annotated continuous assign delay negative (0 used)");
470         __nd_neg_del_warn = FALSE;
471       }
472      __free_del(cap->ca_du, cap->ca_delrep, mdp->flatinum);
473      cap->ca_du = gwrk.g_du;
474      cap->ca_delrep = gwrk.g_delrep;
475      if (__sdf_verbose && (!from_vpi || __debug_flg))
476       emit_reprepconta_verbmsg(cap, &gwrk, mdp, itp, from_vpi);
477      break;
478     case PNP_NETDEL:
479      np = pnpp->elpnp.enp;
480      __prep_delay(&gwrk, pnpp->pnplp, FALSE,
481       (np->ntyp == N_TRIREG), "annotated path delay", TRUE, np->nsym, FALSE);
482 
483      if (__nd_neg_del_warn)
484       {
485        __gferr(971, np->nsym->syfnam_ind, np->nsym->sylin_cnt,
486         "annotated wire %s delay negative (0 used)", np->nsym->synam);
487        __nd_neg_del_warn = FALSE;
488       }
489      __free_del(np->nu.rngdwir->n_du, np->nu.rngdwir->n_delrep, mdp->flatinum);
490      np->nu.rngdwir->n_delrep = gwrk.g_delrep;
491      np->nu.rngdwir->n_du = gwrk.g_du;
492      if (__sdf_verbose && (!from_vpi || __debug_flg))
493       emit_reprepnet_verbmsg(np, &gwrk, mdp, itp, from_vpi);
494      break;
495     case PNP_PROCDCTRL:
496      dctp = pnpp->elpnp.edctp;
497      /* 01/25/00 SJM - fixed s now d not need stmt (maybe not around) */
498      /* but pointing to dctrl and using actionst if present */
499      if (dctp->actionst != NULL) stp = dctp->actionst; else stp = NULL;
500      if (stp != NULL)
501       {
502        tmpsym.syfnam_ind = stp->stfnam_ind;
503        tmpsym.sylin_cnt = stp->stlin_cnt;
504       }
505      else { tmpsym.syfnam_ind = 0; tmpsym.sylin_cnt = 0; }
506 
507      __prep_delay(&gwrk, pnpp->pnplp, FALSE, FALSE,
508       "defparam annotate to procedural delay control", FALSE, &tmpsym, FALSE);
509      if (__nd_neg_del_warn)
510       {
511        __sgferr(974,
512         "defparam delay control annotate negative delay illegal (0 used)");
513        __nd_neg_del_warn = FALSE;
514       }
515      __free_del(dctp->dc_du, dctp->dc_delrep, mdp->flatinum);
516      dctp->dc_delrep = gwrk.g_delrep;
517      dctp->dc_du = gwrk.g_du;
518      if (__sdf_verbose && (!from_vpi || __debug_flg))
519       emit_reprepstmt_verbmsg(stp, &gwrk, mdp, itp, from_vpi);
520      break;
521     case PNP_PATHDEL:
522      sav_declobj = __cur_declobj;
523      __cur_declobj = SPECIFY;
524      pthp = pnpp->elpnp.epthp;
525      /* prepare the delay - notice this uses inst mod */
526      __prep_delay(&gwrk, pnpp->pnplp, TRUE, FALSE, "path delay annotate",
527       TRUE, pthp->pthsym, TRUE);
528      if (__nd_neg_del_warn)
529       {
530       __gferr(981, pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt,
531         "annotate path delay negative (used 0)");
532        __nd_neg_del_warn = FALSE;
533       }
534      __free_del(pthp->pth_du, pthp->pth_delrep, mdp->flatinum);
535      pthp->pth_delrep = gwrk.g_delrep;
536      pthp->pth_du = gwrk.g_du;
537      if (__sdf_verbose && (!from_vpi || __debug_flg))
538       emit_reprepiopath_verbmsg(pthp, &gwrk, mdp, itp, from_vpi);
539      __cur_declobj = sav_declobj;
540      break;
541     case PNP_TCHKP1:
542      strcpy(s1, "annotate first timing check limit");
543      goto ano_tchk;
544     case PNP_TCHKP2:
545      strcpy(s1, "annotate second timing check limit");
546 ano_tchk:
547      sav_declobj = __cur_declobj;
548      __cur_declobj = SPECIFY;
549      tcp = pnpp->elpnp.etcp;
550      __prep_delay(&gwrk, pnpp->pnplp, FALSE, FALSE, s1, TRUE, tcp->tcsym,
551       TRUE);
552      if (__nd_neg_del_warn)
553       {
554        __gfwarn(601, tcp->tcsym->syfnam_ind, tcp->tcsym->sylin_cnt,
555         "%s negative delay changed to 0 (ok for timing verifier)", s1);
556        __nd_neg_del_warn = FALSE;
557       }
558      if (pnpp->pnptyp == PNP_TCHKP1)
559       {
560        __free_del(tcp->tclim_du, tcp->tc_delrep, mdp->flatinum);
561        tcp->tc_delrep = gwrk.g_delrep;
562        tcp->tclim_du = gwrk.g_du;
563       }
564      else
565       {
566        __free_del(tcp->tclim2_du, tcp->tc_delrep2, mdp->flatinum);
567        tcp->tc_delrep2 = gwrk.g_delrep;
568        tcp->tclim2_du = gwrk.g_du;
569       }
570      if (__sdf_verbose && (!from_vpi || __debug_flg))
571       emit_repreptclim_verbmsg(tcp, &gwrk, mdp, itp, pnpp->pnptyp, from_vpi);
572      __cur_declobj = sav_declobj;
573      break;
574     default: __case_terr(__FILE__, __LINE__);
575    }
576   }
577  __pop_wrkitstk();
578 }
579 
580 /*
581  * emit changed param new primitive delay
582  */
emit_reprepdev_verbmsg(struct gate_t * gp,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,int32 from_vpi)583 static void emit_reprepdev_verbmsg(struct gate_t *gp, struct gate_t *ogp,
584  struct mod_t *mdp, struct itree_t *itp, int32 from_vpi)
585 {
586  struct itree_t *itp2;
587  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[10];
588 
589  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
590  else { __msg2_blditree(s1, itp); itp2 = itp; }
591  if (from_vpi) strcpy(s4, "VPI_ PLI"); else strcpy(s4, "SDF");
592  __push_itstk(itp2);
593  __cv_msg(
594   "  %s changed defparam: delay set to (%s) prim %s %s at %s in %s\n", s4,
595   __bld_delay_str(s2, ogp->g_du, ogp->g_delrep), gp->gmsym->synam,
596   gp->gsym->synam, __bld_lineloc(s3, gp->gsym->syfnam_ind,
597   gp->gsym->sylin_cnt), s1);
598  __pop_itstk();
599 }
600 
601 /*
602  * emit changed param new continuous assign delay
603  */
emit_reprepconta_verbmsg(struct conta_t * cap,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,int32 from_vpi)604 static void emit_reprepconta_verbmsg(struct conta_t *cap, struct gate_t *ogp,
605  struct mod_t *mdp, struct itree_t *itp, int32 from_vpi)
606 {
607  struct itree_t *itp2;
608  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[10];
609 
610  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
611  else { __msg2_blditree(s1, itp); itp2 = itp; }
612  if (from_vpi) strcpy(s4, "VPI_ PLI"); else strcpy(s4, "SDF");
613 
614  __push_itstk(itp2);
615  __cv_msg(
616   "  %s changed defparam: delay set to (%s) cont. assign at %s in %s\n", s4,
617   __bld_delay_str(s2, ogp->g_du, ogp->g_delrep), __bld_lineloc(s3,
618   cap->casym->syfnam_ind, cap->casym->sylin_cnt), s1);
619  __pop_itstk();
620 }
621 
622 /*
623  * emit changed param new net delay
624  */
emit_reprepnet_verbmsg(struct net_t * np,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,int32 from_vpi)625 static void emit_reprepnet_verbmsg(struct net_t *np, struct gate_t *ogp,
626  struct mod_t *mdp, struct itree_t *itp, int32 from_vpi)
627 {
628  struct itree_t *itp2;
629  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[10];
630 
631  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
632  else { __msg2_blditree(s1, itp); itp2 = itp; }
633  if (from_vpi) strcpy(s4, "VPI_ PLI"); else strcpy(s4, "SDF");
634 
635  __push_itstk(itp2);
636  __cv_msg(
637   "  %s changed defparam: delay set to (%s) net %s in %s at %s\n", s4,
638   __bld_delay_str(s2, ogp->g_du, ogp->g_delrep), np->nsym->synam, s1,
639   __bld_lineloc(s3, np->nsym->syfnam_ind, np->nsym->sylin_cnt));
640  __pop_itstk();
641 }
642 
643 /*
644  * emit changed param new statement procedural delay control
645  */
emit_reprepstmt_verbmsg(struct st_t * stp,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,int32 from_vpi)646 static void emit_reprepstmt_verbmsg(struct st_t *stp, struct gate_t *ogp,
647  struct mod_t *mdp, struct itree_t *itp, int32 from_vpi)
648 {
649  struct itree_t *itp2;
650  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[10];
651 
652  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
653  else { __msg2_blditree(s1, itp); itp2 = itp; }
654  if (from_vpi) strcpy(s4, "VPI_ PLI"); else strcpy(s4, "SDF");
655  __push_itstk(itp2);
656  if (stp != NULL)
657   {
658    __cv_msg(
659     "  %s changed defparam: delay set to (%s) statement at %s in %s\n", s4,
660     __bld_delay_str(s3, ogp->g_du, ogp->g_delrep),
661     __bld_lineloc(s2, stp->stfnam_ind, stp->stlin_cnt), s1);
662   }
663  else
664   {
665    __cv_msg(
666     "  %s changed defparam: delay set to (%s) statement in %s\n", s4,
667     __bld_delay_str(s3, ogp->g_du, ogp->g_delrep), s1);
668   }
669  __pop_itstk();
670 }
671 
672 /*
673  * emit changed param new iopath delay
674  */
emit_reprepiopath_verbmsg(struct spcpth_t * pthp,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,int32 from_vpi)675 static void emit_reprepiopath_verbmsg(struct spcpth_t *pthp,
676  struct gate_t *ogp, struct mod_t *mdp, struct itree_t *itp, int32 from_vpi)
677 {
678  struct itree_t *itp2;
679  char s1[RECLEN], s2[RECLEN], s3[RECLEN], s4[10];
680 
681  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
682  else { __msg2_blditree(s1, itp); itp2 = itp; }
683  if (from_vpi) strcpy(s4, "VPI_ PLI"); else strcpy(s4, "SDF");
684 
685  __push_itstk(itp2);
686  __cv_msg("  %s changed specparam: delay set to (%s) path at %s in %s\n", s4,
687   __bld_delay_str(s3, ogp->g_du, ogp->g_delrep), __bld_lineloc(s2,
688   pthp->pthsym->syfnam_ind, pthp->pthsym->sylin_cnt), s1);
689  __pop_itstk();
690 }
691 
692 /*
693  * emit changed param new timing check (either first or 2nd)
694  */
emit_repreptclim_verbmsg(struct tchk_t * tcp,struct gate_t * ogp,struct mod_t * mdp,struct itree_t * itp,word32 pnptyp,int32 from_vpi)695 static void emit_repreptclim_verbmsg(struct tchk_t *tcp, struct gate_t *ogp,
696  struct mod_t *mdp, struct itree_t *itp, word32 pnptyp, int32 from_vpi)
697 {
698  struct itree_t *itp2;
699  char s1[RECLEN], s2[10], s3[RECLEN], s4[RECLEN], s5[10];
700 
701  if (itp == NULL) { itp2 = mdp->moditps[0]; sprintf(s1, "'*' first"); }
702  else { __msg2_blditree(s1, itp); itp2 = itp; }
703  if (pnptyp == PNP_TCHKP1) strcpy(s2, ""); else strcpy(s2, " 2nd");
704  if (from_vpi) strcpy(s5, "VPI_ PLI"); else strcpy(s5, "SDF");
705 
706  __push_itstk(itp2);
707  __cv_msg(
708   "  %s changed specparam:%s limit set to %s for %s timing check at %s in %s\n",
709   s5, s2, __bld_delay_str(s4, ogp->g_du, ogp->g_delrep), __to_tcnam(s3,
710   tcp->tchktyp), __bld_lineloc(s4, tcp->tcsym->syfnam_ind,
711   tcp->tcsym->sylin_cnt), s1);
712  __pop_itstk();
713 }
714 
715 /*
716  * ROUTINES TO PREP DELAYS
717  */
718 
719 /*
720  * wrapper around prep delay that copies, checks again, and frees
721  *
722  * needed because can change parameters in delay expressions multiple
723  * times so much copy each time fold and check copy (maybe newly wrong) and
724  * use copy for delay expr. but then can change later so need to do again
725  */
__prep_delay(struct gate_t * gp,struct paramlst_t * dhdr,int32 ispath,int32 is_trireg,char * emsg,int32 mustbeconst,struct sy_t * dsym,int32 is_spec)726 extern void __prep_delay(struct gate_t *gp, struct paramlst_t *dhdr,
727  int32 ispath, int32 is_trireg, char *emsg, int32 mustbeconst, struct sy_t *dsym,
728  int32 is_spec)
729 {
730  register struct paramlst_t *pmp;
731  int32 sav_nowarns, sav_noinforms, sav_lcnt, sav_fnind, sav_ecnt;
732  struct paramlst_t *dhdr2;
733 
734  /* any warns or informs already emitted */
735  sav_nowarns = __no_warns;
736  sav_noinforms = __no_informs;
737  __no_warns = TRUE;
738  __no_informs = TRUE;
739  sav_lcnt = __slin_cnt;
740  sav_fnind = __sfnam_ind;
741  __sfnam_ind = (int32) dsym->syfnam_ind;
742  __slin_cnt = dsym->sylin_cnt;
743  sav_ecnt = __pv_err_cnt;
744 
745  dhdr2 = __copy_dellst(dhdr);
746  if (!is_spec) __chk_delparams(dhdr2, emsg, mustbeconst);
747  else
748   {
749    for (pmp = dhdr2; pmp != NULL; pmp = pmp->pmlnxt)
750     { __chk_spec_delay(pmp->plxndp, emsg); }
751   }
752  __no_warns = sav_nowarns;
753  __no_informs = sav_noinforms;
754  __slin_cnt = sav_lcnt;
755  __sfnam_ind = sav_fnind;
756  if (__pv_err_cnt == sav_ecnt) prep2_delay(gp, dhdr2, ispath, is_trireg);
757  __free_dellst(dhdr2);
758 }
759 
760 /*
761  * prepare gate and continuous assignment preprocessed delay arrays
762  * this changes representation for gate del_u field
763  * also used for wire delays
764  *
765  * this routine assumes at least dummy module context set
766  *
767  * know delay list already checked and if error will not get here
768  * also no scaling or conversion from reals performed by fix_nl
769  *
770  * if is trireg, then know will be exactly 3 values in list
771  * that are constants
772  *
773  * for path delays only DT_1V and DT_16V forms possible because
774  * of table look up algorithm (user may code 1,2,3,6,12)
775  */
prep2_delay(struct gate_t * gp,struct paramlst_t * dhdr,int32 ispath,int32 is_trireg)776 static void prep2_delay(struct gate_t *gp, struct paramlst_t *dhdr,
777  int32 ispath, int32 is_trireg)
778 {
779  register int32 i;
780  register struct paramlst_t *pmp;
781  int32 nparams, has_xpr, has_is;
782  word64 rise, fall, toz;
783  word64 *dtab, xt[16];
784  struct expr_t *xa[12], *xp1;
785 
786  /* DBG remove --
787  extern void __dbg_dump_del(union del_u, word32);
788  --- */
789 
790  /* no delays */
791  if (dhdr == NULL) { gp->g_du.d1v = NULL; gp->g_delrep = DT_NONE; return; }
792 
793  /* assume no negative delay constant expr. */
794  __nd_neg_del_warn = FALSE;
795 
796  /* case 1: one delay special case */
797  /* also 1x form handled here */
798  if (dhdr->pmlnxt == NULL)
799   {
800    xp1 = dhdr->plxndp;
801    prep_1delform(gp, xp1);
802    /* trireg 1 value must be converted to 4v since need special toz decay */
803    if (is_trireg) convert_trireg_1vto4v(gp);
804    goto done;
805   }
806 
807  /* figure out representation needed */
808  has_xpr = FALSE;
809  has_is = FALSE;
810  for (pmp = dhdr, nparams = 0; pmp != NULL; pmp = pmp->pmlnxt, nparams++)
811   {
812    xa[nparams] = pmp->plxndp;
813    switch ((byte) xa[nparams]->optyp) {
814     case NUMBER: case REALNUM: break;
815     case ISNUMBER: case ISREALNUM: has_is = TRUE; break;
816     default: has_xpr = TRUE;
817    }
818   }
819 
820  /* case 2: has expression - cannot be path case */
821  if (has_xpr)
822   {
823    /* DBG remove --- */
824    if (ispath) __arg_terr(__FILE__, __LINE__);
825    /* -- */
826 
827    /* if at least one expr, all must evaluate at run time - leave xpr */
828    gp->g_du.d4x = (struct expr_t **) __my_malloc(4*sizeof(struct expr_t *));
829    /* since indexing by new 2 bit value order is f, r, z, x */
830    gp->g_du.d4x[0] = __copy_expr(xa[1]);
831    /* must fold all of these this is point where copy is fixed (elaborated) */
832    gp->g_du.d4x[1] = __copy_expr(xa[0]);
833    if (nparams == 2) gp->g_du.d4x[2] = NULL;
834    else
835     {
836      gp->g_du.d4x[2] = __copy_expr(xa[2]);
837     }
838    gp->g_du.d4x[3] = NULL;
839    gp->g_delrep = DT_4X;
840    goto done;
841   }
842 
843  /* case 3: IS form more than 1 val (if any IS all must be) */
844  if (has_is)
845   {
846    if (ispath) prep_path_is_dels(gp, xa, nparams);
847    else prep_prim_is_dels(gp, xa, nparams, is_trireg);
848    goto done;
849   }
850 
851  /* case 4a: non IS path form and more than 1 value */
852  /* here must be 16V form */
853  if (ispath)
854   {
855    /* first evaluate expr., prep. constant delay form */
856    for (i = 0; i < nparams; i++) nonis_to_delval(&(xt[i]), xa[i]);
857 
858    dtab = (word64 *) __my_malloc(16*sizeof(word64));
859    /* know not 1 value but can be no convert to number 2,3,6, or 12 */
860    __fill_16vconst(dtab, xt, nparams);
861    gp->g_du.d16v = dtab;
862    gp->g_delrep = DT_16V;
863    goto done;
864   }
865  /* case 4b: non IS primitive form */
866  /* DBG remove ---
867  if (nparams > 3) __arg_terr(__FILE__, __LINE__);
868  --- */
869  dtab = (word64 *) __my_malloc(4*sizeof(word64));
870  /* fill the 3 values with scaled ticks */
871  nonis_to_delval(&rise, xa[0]);
872  nonis_to_delval(&fall, xa[1]);
873  if (nparams == 2) toz = 0ULL; else nonis_to_delval(&toz, xa[2]);
874  /* this handles special processing for tri reg if needed */
875  __fill_4vconst(dtab, &rise, &fall, &toz, nparams, is_trireg);
876  gp->g_du.d4v = dtab;
877  gp->g_delrep = DT_4V;
878 
879 done:;
880  /* --- DBG remove
881  if (__debug_flg) __dbg_dump_del(gp->g_du, gp->g_delrep);
882  --- */
883 }
884 
885 /*
886  * convert 1 non is form to a delay value
887  * this takes a num expression checked else so is only for delay prep.
888  */
nonis_to_delval(word64 * ticksval,struct expr_t * xp)889 static void nonis_to_delval(word64 *ticksval, struct expr_t *xp)
890 {
891  double *dp, d1;
892  word32 *wp;
893  word64 delval;
894 
895  if (xp->optyp == REALNUM)
896   {
897    dp = (double *) &(__contab[xp->ru.xvi]);
898    d1 = *dp;
899    if (d1 < 0.0)
900     {
901 neg_del:
902      *ticksval = 0ULL;
903      __nd_neg_del_warn = TRUE;
904      return;
905     }
906    real_to_ticks(ticksval, d1, __inst_mod);
907    return;
908   }
909  wp = &(__contab[xp->ru.xvi]);
910  delval = (word64) wp[0];
911  /* * SJM 08/17/04 - now any value can be signed - need warning */
912  if (xp->szu.xclen > WBITS)
913   {
914    if (__is_lnegative(wp, xp->szu.xclen)) goto neg_del;
915    delval |= (((word64) wp[1]) << 32);
916   }
917  else
918   {
919    if (xp->has_sign && (wp[0] & (1 << (xp->szu.xclen - 1))) != 0)
920     goto neg_del;
921   }
922  if (!__inst_mod->mno_unitcnv)
923   cnv_num64to_ticks_(*ticksval, delval, __inst_mod);
924  else *ticksval = delval;
925 }
926 
927 /*
928  * free one delay - lots of forms
929  * union is 4 bytes in record, so do not need to free union
930  * this is for after preparation freeing
931  */
__free_del(union del_u du,word32 drep,int32 numinsts)932 extern void __free_del(union del_u du, word32 drep, int32 numinsts)
933 {
934  register int32 i;
935 
936  switch ((byte) drep) {
937   case DT_1V:
938    __my_free((char *) du.d1v, sizeof(word64));
939    break;
940   case DT_IS1V:
941    __my_free((char *) du.dis1v, numinsts*sizeof(word64));
942    break;
943   case DT_IS1V1:
944    __my_free((char *) du.dis1v1, numinsts);
945    break;
946   case DT_IS1V2:
947    __my_free((char *) du.dis1v2, 2*numinsts);
948    break;
949   case DT_4V:
950    __my_free((char *) du.d4v, 4*sizeof(word64));
951    break;
952   case DT_IS4V:
953    __my_free((char *) du.dis4v, 4*numinsts*sizeof(word64));
954    break;
955   case DT_IS4V1:
956    __my_free((char *) du.dis4v1, 4*numinsts);
957    break;
958   case DT_IS4V2:
959    __my_free((char *) du.dis4v2, 4*2*numinsts);
960    break;
961   case DT_16V: __my_free((char *) du.d16v, 16*sizeof(word64)); break;
962   case DT_IS16V:
963    __my_free((char *) du.dis16v, 16*numinsts*sizeof(word64));
964    break;
965   case DT_IS16V1:
966    __my_free((char *) du.dis16v1, 16*numinsts);
967    break;
968   case DT_IS16V2:
969    __my_free((char *) du.dis16v2, 16*2*numinsts);
970    break;
971   case DT_1X:
972    __free_xtree(du.d1x);
973    break;
974   case DT_4X:
975    /* notice this is array of 4 expression pointers (ptr to ptrs) */
976    for (i = 0; i < 3; i++) __free_xtree(du.d4x[i]);
977    __my_free((char *) du.d4x, 4*sizeof(struct expr_t *));
978    break;
979   case DT_CMPLST:
980    __free_dellst(du.pdels);
981    break;
982   default: __case_terr(__FILE__, __LINE__);
983  }
984 }
985 
986 /*
987  * free a delay parameter list
988  */
__free_dellst(struct paramlst_t * dhdr)989 extern void __free_dellst(struct paramlst_t *dhdr)
990 {
991  register struct paramlst_t *pmp;
992  struct paramlst_t *pmp2;
993 
994  for (pmp = dhdr; pmp != NULL;)
995   {
996    pmp2 = pmp;
997    pmp = pmp2->pmlnxt;
998    __free_xtree(pmp2->plxndp);
999    __my_free((char *) pmp2, sizeof(struct paramlst_t));
1000   }
1001 }
1002 
1003 /*
1004  * prepare all 1 delay value cases
1005  */
prep_1delform(struct gate_t * gp,struct expr_t * xp1)1006 static void prep_1delform(struct gate_t *gp, struct expr_t *xp1)
1007 {
1008  register int32 ii;
1009  int32 minsiz, nbytes;
1010  word32 *wp, *wp2, w1;
1011  double d1, *dp;
1012  word64 *dtab, *dtab2, ticksval, delval;
1013 
1014  dtab = NULL;
1015  /* know both double and 64 bit time take 8 bytes dependent */
1016  nbytes = sizeof(word64)*__inst_mod->flatinum;
1017  switch ((byte) xp1->optyp) {
1018   case NUMBER:
1019   case REALNUM:
1020    nonis_to_delval(&ticksval, xp1);
1021    gp->g_du.d1v = (word64 *) __my_malloc(sizeof(word64));
1022    *(gp->g_du.d1v) = ticksval;
1023    gp->g_delrep = DT_1V;
1024    break;
1025   case ISNUMBER:
1026    /* this is common because of back annotation for gate arrays */
1027    /* step 1 build the 8 byte case */
1028    /* LOOKATME - can dtab not be nil? */
1029    if (dtab == NULL) dtab = (word64 *) __my_malloc(nbytes);
1030    /* notice never x/z delays by here no matter what */
1031    if (xp1->szu.xclen > WBITS)
1032     {
1033      wp = &(__contab[xp1->ru.xvi]);
1034      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1035       {
1036        /* SJM 08/17/04 - now any value can be signed - need warning */
1037        if (__is_lnegative(wp, xp1->szu.xclen))
1038         {
1039          __nd_neg_del_warn = TRUE;
1040          dtab[ii] = 0ULL;
1041          continue;
1042         }
1043        dtab[ii] = ((word64) wp[2*ii]) | (((word64) wp[2*ii + 1]) << 32);
1044        if (!__inst_mod->mno_unitcnv)
1045 	{
1046          delval = dtab[ii];
1047          cnv_num64to_ticks_(dtab[ii], delval, __inst_mod);
1048         }
1049       }
1050     }
1051    else
1052     {
1053      wp = &(__contab[xp1->ru.xvi]);
1054      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1055       {
1056        wp2 = &(wp[2*ii]);
1057 
1058        /* SJM 08/17/04 - now any value can be signed - need warning */
1059        if (xp1->has_sign && (wp2[0] & (1 << (xp1->szu.xclen - 1))) != 0)
1060         {
1061          __nd_neg_del_warn = TRUE;
1062          dtab[ii] = 0ULL;
1063          continue;
1064         }
1065 
1066        dtab[ii] = (word64) wp2[0];
1067        if (!__inst_mod->mno_unitcnv)
1068 	{
1069          delval = dtab[ii];
1070          cnv_num64to_ticks_(dtab[ii], delval, __inst_mod);
1071         }
1072       }
1073     }
1074 try_narrow:
1075    /* next determine if can be smaller - assume all fit in 1 byte */
1076    for (minsiz = 1, ii = 0; ii < __inst_mod->flatinum; ii++)
1077     {
1078      if (dtab[ii] > WORDMASK_ULL) { minsiz = 8; break; }
1079      w1 = (word32) (dtab[ii] & WORDMASK_ULL);
1080      if ((w1 & 0xffffff00L) == 0L) continue;
1081      if ((w1 & 0xffff0000L) == 0L) { minsiz = 2; continue; }
1082     }
1083    if (minsiz > 2)
1084     {
1085      dtab2 = (word64 *) __my_malloc(nbytes);
1086      memcpy(dtab2, dtab, nbytes);
1087 
1088      gp->g_du.dis1v = dtab2;
1089      gp->g_delrep = DT_IS1V;
1090      break;
1091     }
1092    if (minsiz == 1)
1093     {
1094      gp->g_du.dis1v1 = (byte *) __my_malloc(__inst_mod->flatinum);
1095      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1096       gp->g_du.dis1v1[ii] = (byte) dtab[ii];
1097      gp->g_delrep = DT_IS1V1;
1098     }
1099    else
1100     {
1101      gp->g_du.dis1v2 = (hword *) __my_malloc(2*__inst_mod->flatinum);
1102      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1103       gp->g_du.dis1v2[ii] = (hword) dtab[ii];
1104      gp->g_delrep = DT_IS1V2;
1105     }
1106    break;
1107   case ISREALNUM:
1108    /* here if value too big - silently truncates to mod 64 bits */
1109    if (dtab == NULL) dtab = (word64 *) __my_malloc(nbytes);
1110    dp = (double *) &(__contab[xp1->ru.xvi]);
1111    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1112     {
1113      /* for reals know fits and non x/z but must scale before conversion */
1114      d1 = dp[ii];
1115      if (d1 < 0.0) { dtab[ii] = 0ULL; __nd_neg_del_warn = TRUE; }
1116      else
1117       {
1118        real_to_ticks(&ticksval, d1, __inst_mod);
1119        dtab[ii] = ticksval;
1120       }
1121     }
1122    goto try_narrow;
1123   default:
1124    /* expr. that must be evaluated each time */
1125    /* must copy since delay parm list including expr. will be freed */
1126    gp->g_du.d1x = __copy_expr(xp1);
1127    gp->g_delrep = DT_1X;
1128   }
1129  if (dtab != NULL) __my_free((char *) dtab, nbytes);
1130 }
1131 
1132 /*
1133  * for trireg convert 1v or is1v forms to 4v or is4v
1134  */
convert_trireg_1vto4v(struct gate_t * gp)1135 static void convert_trireg_1vto4v(struct gate_t *gp)
1136 {
1137  register int32 ii;
1138  int32 ninsts;
1139  word64 *dtab;
1140  byte *btab;
1141  hword *htab;
1142 
1143  ninsts = __inst_mod->flatinum;
1144  switch ((byte) gp->g_delrep) {
1145   case DT_1V:
1146    dtab = gp->g_du.d4v;
1147    gp->g_du.d4v = (word64 *) __my_malloc(4*sizeof(word64));
1148    gp->g_du.d4v[0] = dtab[0];
1149    gp->g_du.d4v[1] = dtab[0];
1150    gp->g_du.d4v[3] = dtab[0];
1151    gp->g_du.d4v[2] = 0ULL;
1152    __my_free((char *) dtab, sizeof(word64));
1153    break;
1154   case DT_IS1V:
1155    dtab = gp->g_du.dis1v;
1156    gp->g_du.dis4v = (word64 *) __my_malloc(4*ninsts*sizeof(word64));
1157    for (ii = 0; ii < ninsts; ii++)
1158     {
1159      gp->g_du.dis4v[4*ii] = dtab[ii];
1160      gp->g_du.dis4v[4*ii + 1] = dtab[ii];
1161      gp->g_du.dis4v[4*ii + 3] = dtab[ii];
1162      gp->g_du.dis4v[4*ii + 2] = 0ULL;
1163     }
1164    __my_free((char *) dtab, ninsts*sizeof(word64));
1165    break;
1166   case DT_IS1V1:
1167    btab = gp->g_du.dis1v1;
1168    gp->g_du.dis4v1 = (byte *) __my_malloc(4*ninsts);
1169    for (ii = 0; ii < ninsts; ii++)
1170     {
1171      gp->g_du.dis4v1[4*ii] = btab[ii];
1172      gp->g_du.dis4v1[4*ii + 1] = btab[ii];
1173      gp->g_du.dis4v1[4*ii + 3] = btab[ii];
1174      gp->g_du.dis4v1[4*ii + 2] = 0;
1175     }
1176    __my_free((char *) btab, 1*ninsts);
1177    break;
1178   case DT_IS1V2:
1179    htab = gp->g_du.dis1v2;
1180    gp->g_du.dis4v2 = (hword *) __my_malloc(4*2*ninsts);
1181    for (ii = 0; ii < ninsts; ii++)
1182     {
1183      gp->g_du.dis4v2[4*ii] = htab[ii];
1184      gp->g_du.dis4v2[4*ii + 1] = htab[ii];
1185      gp->g_du.dis4v2[4*ii + 3] = htab[ii];
1186      gp->g_du.dis4v2[4*ii + 2] = 0;
1187     }
1188    __my_free((char *) htab, 2*ninsts);
1189    break;
1190   default: __case_terr(__FILE__, __LINE__);
1191  }
1192 }
1193 
1194 /*
1195  * fill 4v constant where some values require 64 bit amount
1196  * idea is to fill d4v array with delays according to algorithm
1197  *
1198  * 4v only for primitive and wire delays
1199  */
__fill_4vconst(word64 * dv4,word64 * rise,word64 * fall,word64 * toz,int32 nparams,int32 is_trireg)1200 extern void __fill_4vconst(word64 *dv4, word64 *rise, word64 *fall,
1201  word64 *toz, int32 nparams, int32 is_trireg)
1202 {
1203  word64 ltmp;
1204 
1205  /* 4 value array first is fall (destination state as index) */
1206  dv4[0] = *fall;
1207  dv4[1] = *rise;
1208  /* 2 delay case, use minimum for both to-x and to-z */
1209  if (nparams == 2)
1210   {
1211    if (is_trireg)
1212     {
1213      if (dv4[0] <= dv4[1]) dv4[3] = dv4[0]; else dv4[3] = dv4[1];
1214      dv4[2] = 0ULL;
1215     }
1216    else
1217     {
1218      if (dv4[0] <= dv4[1]) dv4[3] = dv4[2] = dv4[0];
1219      else dv4[3] = dv4[2] = dv4[1];
1220     }
1221   }
1222  else
1223   {
1224    dv4[2] = *toz;
1225    /* for trireg to x is smallest of rise and fall */
1226    if (is_trireg)
1227     { if (dv4[0] <= dv4[1]) ltmp = dv4[0]; else ltmp = dv4[1]; }
1228    else
1229     {
1230      /* index 3 (to-x) is minimum of all 3 */
1231      if (dv4[0] <= dv4[1] && dv4[0] <= dv4[2]) ltmp = dv4[0];
1232      else
1233       { if (dv4[1] < dv4[2]) ltmp = dv4[1]; else ltmp = dv4[2]; }
1234     }
1235    dv4[3] = ltmp;
1236   }
1237  /* LOOKATME */
1238  /* form LRM for wider than 1 cont. assign, v[0] is to-0, v[1] is other */
1239  /* and v[3] is to-z */
1240  /* according to LRM this should be overriden to 1, but OVIsim uses fast */
1241  /* as possible to x (wrong just low bit but still uses it */
1242  /* *** if (lhswid > 1) dv4[3] = dv4[1]; */
1243 }
1244 
1245 /* ---
1246 12 form: (0->1, 1->0, 0->z, z->1, 1->z, z->0,
1247           0->x, x->1, 1->x, x->0, x->z, z->x)
1248 0000 --
1249 0001 1->0 - 1
1250 0010 z->0 - 5
1251 0011 x->0 - 9
1252 0100 0->1 - 0
1253 0101 --
1254 0110 z->1 - 3
1255 0111 x->1 - 7
1256 1000 0->z - 2
1257 1001 1->z - 4
1258 1010 ---
1259 1011 x->z - 10
1260 1100 0->x - 6
1261 1101 1->x - 8
1262 1110 z->x - 11
1263 --- */
1264 
1265 /*
1266  * fill a 16v table from table of expressions
1267  * know need 16v because specify and nparams 2,3,6, or 12
1268  */
__fill_16vconst(word64 * dtab,word64 * xt,int32 nparams)1269 extern void __fill_16vconst(word64 *dtab, word64 *xt, int32 nparams)
1270 {
1271  /* have all values just rearrange into nnoo form */
1272  if (nparams == 12)
1273   {
1274 move_to_dtab:
1275    /* FIXME - why needed - same value can happen? */
1276    dtab[0] = 0ULL;
1277    dtab[5] = dtab[10] = dtab[15] = dtab[0];
1278    dtab[1] = xt[1]; dtab[2] = xt[5]; dtab[3] = xt[9]; dtab[4] = xt[0];
1279    dtab[6] = xt[3]; dtab[7] = xt[7]; dtab[8] = xt[2]; dtab[9] = xt[4];
1280    dtab[11] = xt[10]; dtab[12] = xt[6]; dtab[13] = xt[8];
1281    dtab[14] = xt[11];
1282    return;
1283   }
1284 
1285  /* must convert separately from building nnoo dtab */
1286  if (nparams == 2) { xt[2] = xt[3] = xt[0]; xt[4] = xt[5] = xt[1]; }
1287  else if (nparams == 3)
1288   {
1289    /* 0 thru 2 (rise, fall, toz) good */
1290    /* z->1 is rising */
1291    xt[3] = xt[0];
1292    /* 1->z is toz */
1293    xt[4] = xt[2];
1294    /* z->0 is falling */
1295    xt[5] = xt[1];
1296   }
1297  /* 6 value case is (0->1, 1->0, 0->z, z->1, 1->z, z->0) */
1298 
1299  /* here know 0-5 values of xt filled - next fill 6-11 x transitions */
1300  /* 0->x min(0->1, 0->z) */
1301  xt[6] = (xt[0] < xt[2]) ? xt[0] : xt[2];
1302  /* 1->x min(1->0, 1->z) */
1303  xt[8] = (xt[1] < xt[4]) ? xt[1] : xt[4];
1304  /* z->x min(z->0, z->1) */
1305  xt[11] = (xt[5] < xt[3]) ? xt[5] : xt[3];
1306  /* x->0 max(1->0, z->0) */
1307  xt[9] = (xt[1] > xt[5]) ? xt[1] : xt[5];
1308  /* x->1 max(z->1, 0->1) */
1309  xt[7] = (xt[3] > xt[0]) ? xt[3] : xt[0];
1310  /* x->z max(1->z, 0->z) */
1311  xt[10] = (xt[4] > xt[2]) ? xt[4] : xt[2];
1312  goto move_to_dtab;
1313 }
1314 
1315 /*
1316  * handle the primitive non path IS 2v and 3v cases
1317  * this always builds an IS4V table
1318  */
prep_prim_is_dels(struct gate_t * gp,struct expr_t ** xa,int32 nparams,int32 is_trireg)1319 static void prep_prim_is_dels(struct gate_t *gp, struct expr_t **xa,
1320  int32 nparams, int32 is_trireg)
1321 {
1322  register int32 ii;
1323  int32 minsiz, nbytes;
1324  word32 w1;
1325  byte *btab;
1326  hword *htab;
1327  word64 ticksval;
1328  word64 *dtab, *dtab2;
1329 
1330  if (nparams > 3) __arg_terr(__FILE__, __LINE__);
1331 
1332  /* if some NUBMER and some IS then all must be IS */
1333  nbytes = 4*sizeof(word64)*__inst_mod->flatinum;
1334  dtab = (word64 *) __my_malloc(nbytes);
1335  fill_1col_isdel(dtab, 0, xa[0], 4);
1336  fill_1col_isdel(dtab, 1, xa[1], 4);
1337  /* if 3 fill column, if 2 zero toz column */
1338  if (nparams == 3) fill_1col_isdel(dtab, 2, xa[2], 4);
1339  else
1340   {
1341    ticksval = 0ULL;
1342    for (ii = 0; ii < __inst_mod->flatinum; ii++) dtab[4*ii + 2] = ticksval;
1343   }
1344  gp->g_delrep = DT_IS4V;
1345  /* arrange 4 values table for look up - applies missing values rules */
1346  /* to each row of IS form column */
1347  for (ii = 0; ii < __inst_mod->flatinum; ii++)
1348   {
1349    __fill_4vconst(&(dtab[4*ii]), &(dtab[4*ii]), &(dtab[4*ii + 1]),
1350     &(dtab[4*ii + 2]), nparams, is_trireg);
1351   }
1352 
1353  /* now know inum by 4 table filled */
1354  /* attempt to change form */
1355  for (minsiz = 1, ii = 0; ii < 4*__inst_mod->flatinum; ii++)
1356   {
1357    if (dtab[ii] > WORDMASK_ULL) { minsiz = 8; break; }
1358    w1 = (word32) (dtab[ii] & WORDMASK_ULL);
1359    if ((w1 & 0xffffff00) == 0L) continue;
1360    if ((w1 & 0xffff0000) == 0L) { minsiz = 2; continue; }
1361   }
1362  if (minsiz > 2)
1363   {
1364    dtab2 = (word64 *) __my_malloc(nbytes);
1365    memcpy(dtab2, dtab, nbytes);
1366    gp->g_du.dis4v = dtab2;
1367    gp->g_delrep = DT_IS4V;
1368    goto done;
1369   }
1370 
1371  if (minsiz == 1)
1372   {
1373    btab = (byte *) __my_malloc(4*__inst_mod->flatinum);
1374    for (ii = 0; ii < 4*__inst_mod->flatinum; ii++)
1375     btab[ii] = (byte) dtab[ii];
1376    gp->g_du.dis4v1 = btab;
1377    gp->g_delrep = DT_IS4V1;
1378   }
1379  else
1380   {
1381    htab = (hword *) __my_malloc(4*2*__inst_mod->flatinum);
1382    for (ii = 0; ii < 4*__inst_mod->flatinum; ii++)
1383     htab[ii] = (hword) dtab[ii];
1384    gp->g_du.dis4v2 = htab;
1385    gp->g_delrep = DT_IS4V2;
1386   }
1387 done:
1388  __my_free((char *) dtab, nbytes);
1389 }
1390 
1391 /*
1392  * prep the IS 16 value (4 bit change table look up) forms
1393  * know 1 delay case handled elsewhere (do not need 16V)
1394  *
1395  *
1396  * possibilities are 2, 3, 6, 12
1397  * dtab is 16 by flatinum table (need 0 delays for strength only change)
1398  */
prep_path_is_dels(struct gate_t * gp,struct expr_t ** xa,int32 nparams)1399 static void prep_path_is_dels(struct gate_t *gp, struct expr_t **xa,
1400  int32 nparams)
1401 {
1402  register int32 ii;
1403  int32 minsiz, nbytes;
1404  byte *btab;
1405  hword *htab;
1406  word32 w1;
1407  word64 tim1, tim2;
1408  word64 *dtab, *dtab2;
1409 
1410  /* build big enough table */
1411  nbytes = 16*sizeof(word64)*__inst_mod->flatinum;
1412  dtab = (word64 *) __my_malloc(nbytes);
1413  /* have 16 columns to fill */
1414 
1415  /* step 1: zero entire table */
1416  memset((char *) dtab, 0, nbytes);
1417  /* case 1: 12 (all except for 3 unused coded) */
1418  if (nparams == 12)
1419   {
1420    fill_1col_isdel(dtab, 1, xa[1], 16);
1421    fill_1col_isdel(dtab, 2, xa[5], 16);
1422    fill_1col_isdel(dtab, 3, xa[9], 16);
1423    fill_1col_isdel(dtab, 4, xa[0], 16);
1424    fill_1col_isdel(dtab, 6, xa[3], 16);
1425    fill_1col_isdel(dtab, 7, xa[7], 16);
1426    fill_1col_isdel(dtab, 8, xa[2], 16);
1427    fill_1col_isdel(dtab, 9, xa[4], 16);
1428    fill_1col_isdel(dtab, 11, xa[10], 16);
1429    fill_1col_isdel(dtab, 12, xa[6], 16);
1430    fill_1col_isdel(dtab, 13, xa[8], 16);
1431    fill_1col_isdel(dtab, 14, xa[11], 16);
1432    goto minimize;
1433   }
1434 
1435  /* case 2: 6 coded delays */
1436  if (nparams == 6)
1437   {
1438    fill_1col_isdel(dtab, 4, xa[0], 16);
1439    fill_1col_isdel(dtab, 1, xa[1], 16);
1440    fill_1col_isdel(dtab, 8, xa[2], 16);
1441    fill_1col_isdel(dtab, 6, xa[3], 16);
1442    fill_1col_isdel(dtab, 9, xa[4], 16);
1443    fill_1col_isdel(dtab, 2, xa[5], 16);
1444   }
1445  /* case 3: handle similar 2 and 3 value case */
1446  /* dtab is 16 position nnoo index form */
1447  /* for 2,3 and 6 cases first fill dtab 6 transitions not involving x */
1448  else if (nparams == 2)
1449   {
1450    /* first of 2 is all rising transitions */
1451    /* fill dtab[4] - xa[0] (0->1) */
1452    fill_1col_isdel(dtab, 4, xa[0], 16);
1453    /* fill dtab[8] - xa[2] (0->z) */
1454    /* fill dtab[6] - xa[3] (z->1) */
1455    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1456     dtab[16*ii + 8] = dtab[16*ii + 6] = dtab[16*ii + 4];
1457 
1458    /* 2nd of 2 is all falling transitions */
1459    /* fill dtab[1] - xa[1] (1->0) */
1460    fill_1col_isdel(dtab, 1, xa[1], 16);
1461    /* fill dtab[9] - xa[4] (1->z) */
1462    /* fill dtab[2] - xa[5] (z->0) */
1463    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1464     dtab[16*ii + 9] = dtab[16*ii + 2] = dtab[16*ii + 1];
1465   }
1466  else if (nparams == 3)
1467   {
1468    /* rising of 3 */
1469    /* fill dtab[4] - xa[0] (0->1) */
1470    fill_1col_isdel(dtab, 4, xa[0], 16);
1471    /* fill dtab[6] - xa[3] (0->1) */
1472    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1473     dtab[16*ii + 6] = dtab[16*ii + 4];
1474 
1475    /* falling of 3 */
1476    /* fill dtab[1] - xa[1] (1->0) */
1477    fill_1col_isdel(dtab, 1, xa[1], 16);
1478    /* fill dtab[2] - xa[5] (z->0) */
1479    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1480     dtab[16*ii + 2] = dtab[16*ii + 1];
1481 
1482    /* to z */
1483    /* fill dtab[8] - xa[2] (0->z) */
1484    fill_1col_isdel(dtab, 8, xa[2], 16);
1485    /* fill dtab[9] - xa[4] (1->z) */
1486    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1487     dtab[16*ii + 9] = dtab[16*ii + 8];
1488   }
1489  /* next row by row (per inst.) */
1490  for (ii = 0; ii < __inst_mod->flatinum; ii++)
1491   {
1492    /* dtab columns for low 6 filled by here */
1493    /* 0->x min(0->1, 0->z) */
1494    tim1 = dtab[16*ii + 4];
1495    tim2 = dtab[16*ii + 8];
1496    dtab[16*ii + 12] = (tim1 < tim2) ? tim1 : tim2;
1497    /* 1->x min(1->0, 1->z) */
1498    tim1 = dtab[16*ii + 1];
1499    tim2 = dtab[16*ii + 9];
1500    dtab[16*ii + 13] = (tim1 < tim2) ? tim1 : tim2;
1501    /* z->x min(z->0, z->1) */
1502    tim1 = dtab[16*ii + 2];
1503    tim2 = dtab[16*ii + 6];
1504    dtab[16*ii + 14] = (tim1 < tim2) ? tim1 : tim2;
1505    /* x->0 max(1->0, z->0) */
1506    tim1 = dtab[16*ii + 1];
1507    tim2 = dtab[16*ii + 2];
1508    dtab[16*ii + 3] = (tim1 > tim2) ? tim1 : tim2;
1509    /* x->1 max(z->1, 0->1) */
1510    tim1 = dtab[16*ii + 6];
1511    tim2 = dtab[16*ii + 4];
1512    dtab[16*ii + 7] = (tim1 > tim2) ? tim1 : tim2;
1513    /* x->z max(1->z, 0->z) */
1514    tim1 = dtab[16*ii + 9];
1515    tim2 = dtab[16*ii + 8];
1516    dtab[16*ii + 11] = (tim1 > tim2) ? tim1 : tim2;
1517   }
1518 
1519  /* now know inum by 16 table filled */
1520  /* attempt to change form */
1521 minimize:
1522  for (minsiz = 1, ii = 0; ii < 16*__inst_mod->flatinum; ii++)
1523   {
1524    if (dtab[ii] > WORDMASK_ULL) { minsiz = 8; break; }
1525    w1 = (word32) (dtab[ii] & WORDMASK_ULL);
1526    if ((w1 & 0xffffff00) == 0L) continue;
1527    if ((w1 & 0xffff0000) == 0L) { minsiz = 2; continue; }
1528   }
1529  if (minsiz > 2)
1530   {
1531    dtab2 = (word64 *) __my_malloc(nbytes);
1532    memcpy(dtab2, dtab, nbytes);
1533    gp->g_du.dis16v = dtab2;
1534    gp->g_delrep = DT_IS16V;
1535    goto done;
1536   }
1537 
1538  if (minsiz == 1)
1539   {
1540    btab = (byte *) __my_malloc(16*__inst_mod->flatinum);
1541    for (ii = 0; ii < 16*__inst_mod->flatinum; ii++)
1542     btab[ii] = (byte) dtab[ii];
1543    gp->g_du.dis16v1 = btab;
1544    gp->g_delrep = DT_IS16V1;
1545   }
1546  else
1547   {
1548    htab = (hword *) __my_malloc(16*2*__inst_mod->flatinum);
1549    for (ii = 0; ii < 16*__inst_mod->flatinum; ii++)
1550     htab[ii] = (hword) dtab[ii];
1551    gp->g_du.dis16v2 = htab;
1552    gp->g_delrep = DT_IS16V2;
1553   }
1554 done:
1555  __my_free((char *) dtab, nbytes);
1556 }
1557 
1558 /*
1559  * fill one column of the flatinum deep delay table
1560  */
fill_1col_isdel(word64 * dtab,int32 coli,struct expr_t * xp,int32 stride)1561 static void fill_1col_isdel(word64 *dtab, int32 coli, struct expr_t *xp,
1562  int32 stride)
1563 {
1564  register int32 ii;
1565  word32 *wp;
1566  word64 ticksval, delval;
1567  double d1, *dp;
1568 
1569  switch ((byte) xp->optyp) {
1570   case REALNUM:
1571   case NUMBER:
1572    nonis_to_delval(&ticksval, xp);
1573    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1574     dtab[stride*ii + coli] = ticksval;
1575    break;
1576   case ISREALNUM:
1577    dp = (double *) &(__contab[xp->ru.xvi]);
1578    for (ii = 0; ii < __inst_mod->flatinum; ii++)
1579     {
1580      d1 = dp[ii];
1581      if (d1 < 0.0)
1582       {
1583        ticksval = 0ULL;
1584        __nd_neg_del_warn = TRUE;
1585       }
1586      else real_to_ticks(&ticksval, d1, __inst_mod);
1587      dtab[stride*ii + coli] = ticksval;
1588     }
1589    break;
1590   case ISNUMBER:
1591    if (xp->szu.xclen > WBITS)
1592     {
1593      wp = &(__contab[xp->ru.xvi]);
1594      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1595       {
1596        /* SJM 08/17/04 - now for ver 2001 any width can be signed */
1597        if (__is_lnegative(wp, xp->szu.xclen))
1598         {
1599          __nd_neg_del_warn = TRUE;
1600          ticksval = 0ULL;
1601         }
1602        else
1603         {
1604          ticksval = ((word64) wp[2*ii]) | (((word64) wp[2*ii + 1]) << 32);
1605          if (!__inst_mod->mno_unitcnv)
1606 	  {
1607            delval = ticksval;
1608            cnv_num64to_ticks_(ticksval, delval, __inst_mod);
1609           }
1610         }
1611        dtab[stride*ii + coli] = ticksval;
1612       }
1613     }
1614    else
1615     {
1616      wp = &(__contab[xp->ru.xvi]);
1617      for (ii = 0; ii < __inst_mod->flatinum; ii++)
1618       {
1619        ticksval = (word64) wp[2*ii];
1620 
1621        /* SJM 08/17/04 - now for ver 2001 any width can be signed */
1622        if (xp->has_sign && (wp[0] & (1 << (xp->szu.xclen - 1))) != 0)
1623         {
1624          ticksval = 0ULL;
1625          __nd_neg_del_warn = TRUE;
1626         }
1627        else if (!__inst_mod->mno_unitcnv)
1628 	{
1629          delval = ticksval;
1630          cnv_num64to_ticks_(ticksval, delval, __inst_mod);
1631         }
1632        dtab[stride*ii + coli] = ticksval;
1633       }
1634     }
1635    break;
1636    default: __case_terr(__FILE__, __LINE__);
1637   }
1638 }
1639 
1640 /*
1641  * DELAY REPRESENTATION CHANGE ROUTINES
1642  */
1643 
1644 /*
1645  * change one instance delay form
1646  *
1647  * this merges the 1 inst into IS form
1648  * know new delay is not IS form since for 1 instance
1649  * this does not need itree loc. on itree stack uses passed value
1650  */
__chg_1inst_del(struct gate_t * mgp,struct itree_t * mastitp,struct gate_t * ngp)1651 extern void __chg_1inst_del(struct gate_t *mgp, struct itree_t *mastitp,
1652  struct gate_t *ngp)
1653 {
1654  switch ((byte) ngp->g_delrep) {
1655   case DT_1V: chg1vform_1instdel(mgp, mastitp, ngp); break;
1656   case DT_4V: chg4vform_1instdel(mgp, mastitp, ngp); break;
1657   case DT_16V: chg16vform_1instdel(mgp, mastitp, ngp); break;
1658   default: __case_terr(__FILE__, __LINE__);
1659  }
1660 }
1661 
1662 /*
1663  * change one instance delay form when new is DT_1V form
1664  * know mgp always is form after here
1665  * can be called from any form either prim or path delay
1666  */
chg1vform_1instdel(struct gate_t * mgp,struct itree_t * mastitp,struct gate_t * ngp)1667 static void chg1vform_1instdel(struct gate_t *mgp, struct itree_t *mastitp,
1668  struct gate_t *ngp)
1669 {
1670  register int32 i;
1671  int32 numinsts, tmp, mwid;
1672  word64 ntim[16], mtim[16];
1673 
1674  numinsts = mastitp->itip->imsym->el.emdp->flatinum;
1675  ntim[0] = ngp->g_du.d1v[0];
1676  switch ((byte) mgp->g_delrep) {
1677   case DT_1V:
1678    /* if values same, nothing to do */
1679    mtim[0] = mgp->g_du.d1v[0];
1680    if (mtim[0] == ntim[0]) break;
1681 
1682    __my_free((char *) mgp->g_du.d1v, sizeof(word64));
1683    /* attempt to store in packed form */
1684    mwid = get_ispack(ntim[0]);
1685    tmp = get_ispack(mtim[0]);
1686    if (tmp > mwid) mwid = tmp;
1687    create_disv(mgp, numinsts, 1, mtim, mwid);
1688    /* set the new value */
1689    set_1is1val(mgp, mastitp->itinum, 1, ntim, mwid);
1690    break;
1691   case DT_4V:
1692    for (i = 0; i < 4; i++) mtim[i] = mgp->g_du.d4v[i];
1693    for (i = 0; i < 4; i++) { if (mtim[i] != ntim[0]) goto nd_is4v; }
1694    break;
1695 nd_is4v:
1696    __my_free((char *) mgp->g_du.d4v, 4*sizeof(word64));
1697    mwid = get_ispack(ntim[0]);
1698    for (i = 0; i < 4; i++)
1699     { tmp = get_ispack(mtim[i]); if (tmp > mwid) mwid = tmp; }
1700    create_disv(mgp, numinsts, 4, mtim, mwid);
1701    set_1is1val(mgp, mastitp->itinum, 4, ntim, mwid);
1702    break;
1703   case DT_16V:
1704    for (i = 0; i < 16; i++) mtim[i] = mgp->g_du.d16v[i];
1705    for (i = 1; i < 16; i++)
1706     {
1707      if (i == 5 || i == 10 || i == 15) continue;
1708      if (mtim[i] != ntim[0]) goto nd_is16v;
1709     }
1710    break;
1711 nd_is16v:
1712    __my_free((char *) mgp->g_du.d16v, 16*sizeof(word64));
1713    mwid = get_ispack(ntim[0]);
1714    for (i = 1; i < 16; i++)
1715     {
1716      if (i == 5 || i == 10 || i == 15) continue;
1717      tmp = get_ispack(mtim[i]);
1718      if (tmp > mwid) mwid = tmp;
1719     }
1720    create_disv(mgp, numinsts, 16, mtim, mwid);
1721    set_1is1val(mgp, mastitp->itinum, 16, ntim, mwid);
1722    break;
1723   case DT_IS1V:
1724    mgp->g_du.dis1v[mastitp->itinum] = ntim[0];
1725    /* slight possibility that could now narrow but rare */
1726    break;
1727   case DT_IS1V1:
1728    mwid = get_ispack(ntim[0]);
1729    if (mwid == 1)
1730     { mgp->g_du.dis1v1[mastitp->itinum] = (byte) ntim[0]; break; }
1731    if (mwid == 2)
1732     {
1733      unpack_isv1_to_isv2(mgp, numinsts, 1);
1734      mgp->g_du.dis1v2[mastitp->itinum] = (hword) ntim[0];
1735      break;
1736     }
1737    unpack_isv1_to_isv(mgp, numinsts, 1);
1738    mgp->g_du.dis1v[mastitp->itinum] = ntim[0];
1739    break;
1740   case DT_IS1V2:
1741    mwid = get_ispack(ntim[0]);
1742    if (mwid < 8) mgp->g_du.dis1v2[mastitp->itinum] = (hword) ntim[0];
1743    else
1744     {
1745      unpack_isv2_to_isv(mgp, numinsts, 1);
1746      mgp->g_du.dis1v[mastitp->itinum] = ntim[0];
1747     }
1748    break;
1749   case DT_IS4V:
1750    for (i = 0; i < 4; i++) mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[0];
1751    /* slight possibility that could now narrow but rare */
1752    break;
1753   case DT_IS4V1:
1754    mwid = get_ispack(ntim[0]);
1755    if (mwid == 1)
1756     {
1757      for (i = 0; i < 4; i++)
1758       mgp->g_du.dis4v1[4*mastitp->itinum + i] = (byte) ntim[0];
1759      break;
1760     }
1761    if (mwid == 2)
1762     {
1763      unpack_isv1_to_isv2(mgp, numinsts, 4);
1764      for (i = 0; i < 4; i++)
1765       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[0];
1766      break;
1767     }
1768    unpack_isv1_to_isv(mgp, numinsts, 4);
1769    for (i = 0; i < 4; i++)
1770     mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[0];
1771    break;
1772   case DT_IS4V2:
1773    mwid = get_ispack(ntim[0]);
1774    if (mwid < 8)
1775     {
1776      for (i = 0; i < 4; i++)
1777       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[0];
1778     }
1779    else
1780     {
1781      unpack_isv2_to_isv(mgp, numinsts, 4);
1782      for (i = 0; i < 4; i++)
1783       mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[0];
1784     }
1785    break;
1786   case DT_IS16V:
1787    for (i = 0; i < 16; i++)
1788     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[0];
1789    zero_unused_16v(&(mgp->g_du.dis16v[16*mastitp->itinum]));
1790    /* slight possibility that could now narrow but rare */
1791    break;
1792   case DT_IS16V1:
1793    mwid = get_ispack(ntim[0]);
1794    if (mwid == 1)
1795     {
1796      for (i = 0; i < 16; i++)
1797       {
1798        if (i == 0 || i == 5 || i == 10 || i == 15)
1799         { mgp->g_du.dis16v1[16*mastitp->itinum + i] = 0; continue; }
1800        mgp->g_du.dis16v1[16*mastitp->itinum + i] = (byte) ntim[0];
1801       }
1802      break;
1803     }
1804    if (mwid == 2)
1805     {
1806      unpack_isv1_to_isv2(mgp, numinsts, 16);
1807      for (i = 0; i < 16; i++)
1808       {
1809        if (i == 0 || i == 5 || i == 10 || i == 15)
1810         { mgp->g_du.dis16v2[16*mastitp->itinum + i] = 0; continue; }
1811        mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[0];
1812       }
1813      break;
1814     }
1815    unpack_isv1_to_isv(mgp, numinsts, 16);
1816    for (i = 0; i < 16; i++)
1817     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[0];
1818    zero_unused_16v(&(mgp->g_du.dis16v[16*mastitp->itinum]));
1819    break;
1820   case DT_IS16V2:
1821    mwid = get_ispack(ntim[0]);
1822    if (mwid < 8)
1823     {
1824      for (i = 0; i < 16; i++)
1825       {
1826        if (i == 0 || i == 5 || i == 10 || i == 15)
1827         { mgp->g_du.dis16v2[16*mastitp->itinum + i] = 0; continue; }
1828        mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[0];
1829       }
1830     }
1831    else
1832     {
1833      unpack_isv2_to_isv(mgp, numinsts, 16);
1834      for (i = 0; i < 16; i++)
1835       mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[0];
1836      zero_unused_16v(&(mgp->g_du.dis16v[16*mastitp->itinum]));
1837     }
1838    break;
1839   default: __case_terr(__FILE__, __LINE__);
1840  }
1841 }
1842 
1843 /*
1844  * routine to set 1 instance of IS form value
1845  * here know only 0th element of ntim used since previous known 1 value
1846  */
set_1is1val(struct gate_t * gp,int32 iti,int32 nvals,word64 * ntim,int32 mwid)1847 static void set_1is1val(struct gate_t *gp, int32 iti, int32 nvals, word64 *ntim,
1848  int32 mwid)
1849 {
1850  register int32 i, ivalnum;
1851 
1852  /* set the new value */
1853  ivalnum = nvals*iti;
1854  if (mwid == 1)
1855   {
1856    for (i = 0; i < nvals; i++)
1857     {
1858      if (nvals == 16)
1859       {
1860        if (i == 0 || i == 5 || i == 10 || i == 15)
1861         gp->g_du.dis16v1[ivalnum + i] = 0;
1862        else gp->g_du.dis16v1[ivalnum + i] = (byte) ntim[0];
1863       }
1864      else gp->g_du.dis4v1[ivalnum + i] = (byte) ntim[0];
1865     }
1866   }
1867  else if (mwid == 8)
1868   {
1869    for (i = 0; i < nvals; i++) gp->g_du.dis16v[ivalnum + i] = ntim[0];
1870    if (nvals == 16) zero_unused_16v(&(gp->g_du.dis16v[ivalnum]));
1871   }
1872  else
1873   {
1874    for (i = 0; i < nvals; i++)
1875     {
1876      if (nvals == 16)
1877       {
1878        if (i == 0 || i == 5 || i == 10 || i == 15)
1879         gp->g_du.dis16v2[ivalnum + i] = 0;
1880        else gp->g_du.dis16v2[ivalnum + i] = (hword) ntim[0];
1881       }
1882      /* since all ptrs to array of hwords use 4v2 form, could use any */
1883      else gp->g_du.dis4v2[ivalnum + i] = (hword) ntim[0];
1884     }
1885   }
1886 }
1887 
1888 /*
1889  * change one instance delay form when new is DT_4V form
1890  * know old can only be 1v or 4v form since 16v impossible for prim delay
1891  */
chg4vform_1instdel(struct gate_t * mgp,struct itree_t * mastitp,struct gate_t * ngp)1892 static void chg4vform_1instdel(struct gate_t *mgp, struct itree_t *mastitp,
1893  struct gate_t *ngp)
1894 {
1895  register int32 i;
1896  int32 numinsts, tmp, mwid;
1897  word64 ntim[16], mtim[16];
1898 
1899  numinsts = mastitp->itip->imsym->el.emdp->flatinum;
1900  for (i = 0; i < 4; i++) ntim[i] = ngp->g_du.d4v[i];
1901  switch ((byte) mgp->g_delrep) {
1902   case DT_1V:
1903    /* new is 4 value, master is 1 value */
1904    /* since new is 4v always need at least 4v */
1905    mtim[0] = mgp->g_du.d1v[0];
1906    /* if all 4 new same as same as 1v, leave 1 v */
1907    for (i = 0; i < 4; i++) { if (mtim[0] != ntim[i]) goto nd_is1v4v; }
1908    break;
1909 nd_is1v4v:
1910    /* duplicate 1 to all of master times */
1911    mtim[1] = mtim[2] = mtim[3] = mtim[0];
1912    __my_free((char *) mgp->g_du.d1v, sizeof(word64));
1913    mwid = get_ispack(mtim[0]);
1914    for (i = 0; i < 4; i++)
1915     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
1916    create_disv(mgp, numinsts, 4, mtim, mwid);
1917    set_1is416val(mgp, mastitp->itinum, 4, ntim, mwid);
1918    break;
1919   case DT_4V:
1920    /* master is 4 and new is 4 */
1921    for (i = 0; i < 4; i++) mtim[i] = mgp->g_du.d4v[i];
1922    for (i = 0; i < 4; i++) { if (mtim[i] != ntim[i]) goto nd_is4v; }
1923    break;
1924 nd_is4v:
1925    __my_free((char *) mgp->g_du.d1v, 4*sizeof(word64));
1926    mwid = get_ispack(ntim[0]);
1927    for (i = 1; i < 4; i++)
1928     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
1929    for (i = 0; i < 4; i++)
1930     { tmp = get_ispack(mtim[i]); if (tmp > mwid) mwid = tmp; }
1931    /* notice only difference from 1v here is mtim has 4 different vals */
1932    create_disv(mgp, numinsts, 4, mtim, mwid);
1933    set_1is416val(mgp, mastitp->itinum, 4, ntim, mwid);
1934    break;
1935   case DT_IS1V:
1936    /* new is 4 value, master is 1 IS form */
1937    /* convert 1 IS to 4 IS */
1938    cnv_1is_to_4is(mgp, numinsts, 8, 8);
1939    /* SJM 08/14/01 - was wrongly filling is1v case - other 3 not filled */
1940    for (i = 0; i < 4; i++)
1941     mgp->g_du.dis1v[4*mastitp->itinum + i] = ntim[i];
1942    /* slight possibility that could now narrow but rare */
1943    break;
1944   case DT_IS1V1:
1945    /* master is 1 byte 1 value IS and new time is 4v */
1946    mwid = get_ispack(ntim[0]);
1947    for (i = 1; i < 4; i++)
1948     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
1949    if (mwid == 1)
1950     {
1951      cnv_1is_to_4is(mgp, numinsts, 1, 1);
1952      for (i = 0; i < 4; i++)
1953       mgp->g_du.dis4v1[4*mastitp->itinum + i] = (byte) ntim[i];
1954      break;
1955     }
1956    if (mwid == 2)
1957     {
1958      cnv_1is_to_4is(mgp, numinsts, 1, 2);
1959      for (i = 0; i < 4; i++)
1960       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[i];
1961      break;
1962     }
1963    cnv_1is_to_4is(mgp, numinsts, 1, 8);
1964    for (i = 0; i < 4; i++)
1965     mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[i];
1966    break;
1967   case DT_IS1V2:
1968    mwid = get_ispack(ntim[0]);
1969    for (i = 1; i < 4; i++)
1970     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
1971    if (mwid < 8)
1972     {
1973      cnv_1is_to_4is(mgp, numinsts, 2, 2);
1974      for (i = 0; i < 4; i++)
1975       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[i];
1976      break;
1977     }
1978    cnv_1is_to_4is(mgp, numinsts, 2, 8);
1979    for (i = 0; i < 4; i++)
1980     mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[i];
1981    break;
1982   case DT_IS4V:
1983    /*  new 4v and master 4v is */
1984    for (i = 0; i < 4; i++) mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[i];
1985    /* slight possibility that could now narrow but rare */
1986    break;
1987   case DT_IS4V1:
1988    mwid = get_ispack(ntim[0]);
1989    for (i = 1; i < 4; i++)
1990     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
1991    if (mwid == 1)
1992     {
1993      for (i = 0; i < 4; i++)
1994       mgp->g_du.dis4v1[4*mastitp->itinum + i] = (byte) ntim[i];
1995      break;
1996     }
1997    if (mwid == 2)
1998     {
1999      unpack_isv1_to_isv2(mgp, numinsts, 4);
2000      for (i = 0; i < 4; i++)
2001       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[i];
2002      break;
2003     }
2004    unpack_isv1_to_isv(mgp, numinsts, 4);
2005    for (i = 0; i < 4; i++)
2006     mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[i];
2007    break;
2008   case DT_IS4V2:
2009    mwid = get_ispack(ntim[0]);
2010    for (i = 1; i < 4; i++)
2011     { tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp; }
2012    if (mwid < 8)
2013     {
2014      for (i = 0; i < 4; i++)
2015       mgp->g_du.dis4v2[4*mastitp->itinum + i] = (hword) ntim[i];
2016     }
2017    else
2018     {
2019      unpack_isv2_to_isv(mgp, numinsts, 4);
2020      for (i = 0; i < 4; i++)
2021       mgp->g_du.dis4v[4*mastitp->itinum + i] = ntim[i];
2022     }
2023    break;
2024   /* all 16 v forms here are impossible */
2025   default: __case_terr(__FILE__, __LINE__);
2026  }
2027 }
2028 
2029 /*
2030  * routine to set 1 instance of IS form value where ntim has right
2031  * width and nvals assigned for 1 changed instance
2032  */
set_1is416val(struct gate_t * gp,int32 iti,int32 nvals,word64 * ntim,int32 mwid)2033 static void set_1is416val(struct gate_t *gp, int32 iti, int32 nvals, word64 *ntim,
2034  int32 mwid)
2035 {
2036  register int32 i, ivalnum;
2037 
2038  /* set the new value */
2039  ivalnum = nvals*iti;
2040  if (mwid == 1)
2041   {
2042    for (i = 0; i < nvals; i++)
2043     {
2044      if (nvals == 16)
2045       {
2046        if (i == 0 || i == 5 || i == 10 || i == 15)
2047         gp->g_du.dis16v1[ivalnum + i] = 0;
2048        else gp->g_du.dis16v1[ivalnum + i] = (byte) ntim[i];
2049       }
2050      else gp->g_du.dis4v1[ivalnum + i] = (byte) ntim[i];
2051     }
2052   }
2053  else if (mwid == 8)
2054   {
2055    for (i = 0; i < nvals; i++)
2056     gp->g_du.dis16v[ivalnum + i] = ntim[i];
2057    if (nvals == 16) zero_unused_16v(&(gp->g_du.dis16v[ivalnum]));
2058   }
2059  else
2060   {
2061    for (i = 0; i < nvals; i++)
2062     {
2063      if (nvals == 16)
2064       {
2065        if (i == 0 || i == 5 || i == 10 || i == 15)
2066         gp->g_du.dis16v2[ivalnum + i] = 0;
2067        else gp->g_du.dis16v2[ivalnum + i] = (hword) ntim[i];
2068       }
2069      else gp->g_du.dis4v2[ivalnum + i] = (hword) ntim[i];
2070     }
2071   }
2072 }
2073 
2074 /*
2075  * change one instance of IS delay form when new is DT_16V form
2076  * here old 4v form impossible since must be path delay
2077  */
chg16vform_1instdel(struct gate_t * mgp,struct itree_t * mastitp,struct gate_t * ngp)2078 static void chg16vform_1instdel(struct gate_t *mgp, struct itree_t *mastitp,
2079  struct gate_t *ngp)
2080 {
2081  register int32 i;
2082  int32 numinsts, tmp, mwid;
2083  word64 tmptim, ntim[16], mtim[16];
2084 
2085  numinsts = mastitp->itip->imsym->el.emdp->flatinum;
2086  for (i = 0; i < 16; i++) ntim[i] = ngp->g_du.d16v[i];
2087  switch ((byte) mgp->g_delrep) {
2088   case DT_1V:
2089    /* new is 16 value, master is 1 value */
2090    mtim[0] = mgp->g_du.d1v[0];
2091    for (i = 1; i < 16; i++)
2092     {
2093      if (i == 5 || i == 10 || i == 15) continue;
2094      if (mtim[0] != ntim[i]) goto nd_is1v16v;
2095     }
2096    break;
2097 nd_is1v16v:
2098    /* duplicate 1 to all of master times */
2099    tmptim = mtim[0];
2100    for (i = 1; i < 16; i++) mtim[i] = tmptim;
2101    zero_unused_16v(mtim);
2102    __my_free((char *) mgp->g_du.d1v, sizeof(word64));
2103    mwid = get_ispack(mtim[0]);
2104    for (i = 1; i < 16; i++)
2105     {
2106      if (i == 5 || i == 10 || i == 15) continue;
2107      tmp = get_ispack(ntim[i]);
2108      if (tmp > mwid) mwid = tmp;
2109     }
2110    create_disv(mgp, numinsts, 16, mtim, mwid);
2111    set_1is416val(mgp, mastitp->itinum, 16, ntim, mwid);
2112    break;
2113   case DT_16V:
2114    /* new 16 values, master 16 */
2115    for (i = 0; i < 16; i++) mtim[i] = mgp->g_du.d16v[i];
2116    for (i = 0; i < 16; i++) { if (mtim[i] != ntim[i]) goto nd_is16v; }
2117    break;
2118 nd_is16v:
2119    /* must look at 12 master's and 4 news */
2120    mwid = get_ispack(ntim[1]);
2121    for (i = 2; i < 16; i++)
2122     {
2123      if (i == 5 || i == 10 || i == 15) continue;
2124      tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp;
2125     }
2126    for (i = 1; i < 16; i++)
2127     {
2128      if (i == 5 || i == 10 || i == 15) continue;
2129      tmp = get_ispack(mtim[i]); if (tmp > mwid) mwid = tmp;
2130     }
2131    /* set the new value */
2132    create_disv(mgp, numinsts, 16, mtim, mwid);
2133    set_1is416val(mgp, mastitp->itinum, 16, ntim, mwid);
2134    break;
2135   case DT_IS1V:
2136    /* new is 16 value, master is 1 IS form */
2137    /* convert 1 is to 16 IS and set to dummy value */
2138    cnv_1is_to_16is(mgp, numinsts, 8, 8);
2139    /* SJM 08/14/01 - was wrongly filling is1v case - other 15 not filled */
2140    for (i = 0; i < 16; i++)
2141     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2142    /* slight possibility that could now narrow but rare */
2143    break;
2144   case DT_IS1V1:
2145    /* master is 1 byte 1 value IS and new time is 16v */
2146    mwid = get_ispack(ntim[1]);
2147    for (i = 2; i < 16; i++)
2148     {
2149      if (i == 5 || i == 10 || i == 15) continue;
2150      tmp = get_ispack(ntim[i]);
2151      if (tmp > mwid) mwid = tmp;
2152     }
2153    if (mwid == 1)
2154     {
2155      cnv_1is_to_16is(mgp, numinsts, 1, 1);
2156      for (i = 0; i < 16; i++)
2157       mgp->g_du.dis16v1[16*mastitp->itinum + i] = (byte) ntim[i];
2158      break;
2159     }
2160    if (mwid == 2)
2161     {
2162      cnv_1is_to_16is(mgp, numinsts, 1, 2);
2163      for (i = 0; i < 16; i++)
2164       mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[i];
2165      break;
2166     }
2167    cnv_1is_to_16is(mgp, numinsts, 1, 8);
2168    for (i = 0; i < 16; i++)
2169     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2170    break;
2171   case DT_IS1V2:
2172    mwid = get_ispack(ntim[1]);
2173    for (i = 2; i < 16; i++)
2174     {
2175      if (i == 5 || i == 10 || i == 15) continue;
2176      tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp;
2177     }
2178    if (mwid < 8)
2179     {
2180      cnv_1is_to_16is(mgp, numinsts, 2, 2);
2181      for (i = 0; i < 16; i++)
2182       mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[i];
2183      break;
2184     }
2185    cnv_1is_to_16is(mgp, numinsts, 2, 8);
2186    for (i = 0; i < 16; i++)
2187     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2188    break;
2189   case DT_IS16V:
2190    /*  new 16v and master 16v is */
2191    for (i = 0; i < 16; i++)
2192     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2193    /* slight possibility that could now narrow but rare */
2194    break;
2195   case DT_IS16V1:
2196    mwid = get_ispack(ntim[1]);
2197    for (i = 2; i < 16; i++)
2198     {
2199      if (i == 5 || i == 10 || i == 15) continue;
2200      tmp = get_ispack(ntim[i]); if (tmp > mwid) mwid = tmp;
2201     }
2202    if (mwid == 1)
2203     {
2204      for (i = 0; i < 16; i++)
2205       mgp->g_du.dis16v1[16*mastitp->itinum + i] = (byte) ntim[i];
2206      break;
2207     }
2208    if (mwid == 2)
2209     {
2210      unpack_isv1_to_isv2(mgp, numinsts, 16);
2211      for (i = 0; i < 16; i++)
2212       mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[i];
2213      break;
2214     }
2215    unpack_isv1_to_isv(mgp, numinsts, 16);
2216    for (i = 0; i < 16; i++)
2217     mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2218    break;
2219   case DT_IS16V2:
2220    mwid = get_ispack(ntim[1]);
2221    for (i = 2; i < 16; i++)
2222     {
2223      if (i == 5 || i == 15) continue;
2224      tmp = get_ispack(ntim[i]);
2225      if (tmp > mwid) mwid = tmp;
2226     }
2227    if (mwid < 8)
2228     {
2229      for (i = 0; i < 16; i++)
2230       mgp->g_du.dis16v2[16*mastitp->itinum + i] = (hword) ntim[i];
2231     }
2232    else
2233     {
2234      unpack_isv2_to_isv(mgp, numinsts, 16);
2235      for (i = 0; i < 16; i++)
2236       mgp->g_du.dis16v[16*mastitp->itinum + i] = ntim[i];
2237     }
2238    break;
2239   /* 4v forms illegal here */
2240   default: __case_terr(__FILE__, __LINE__);
2241  }
2242 }
2243 
2244 /*
2245  * convert 1 IS packed opck size to 4 IS form packed npck
2246  */
cnv_1is_to_4is(struct gate_t * gp,int32 numinsts,int32 opck,int32 npck)2247 static void cnv_1is_to_4is(struct gate_t *gp, int32 numinsts, int32 opck, int32 npck)
2248 {
2249  register int32 ii, i;
2250  union del_u sav_du;
2251  word64 ntim[16];
2252 
2253  for (i = 0; i < 4; i++) ntim[i] = 0ULL;
2254  sav_du = gp->g_du;
2255  /* build nvals value packed acording to new value */
2256  create_disv(gp, numinsts, 4, ntim, npck);
2257 
2258  for (ii = 0; ii < numinsts; ii++)
2259   {
2260    for (i = 0; i < 4; i++)
2261     {
2262      if (opck == 1) ntim[i] = (word64) sav_du.dis1v1[ii];
2263      else if (opck == 2) ntim[i] = (word64) sav_du.dis1v2[ii];
2264      else ntim[i] = sav_du.dis1v[ii];
2265     }
2266    if (npck == 1)
2267     {
2268      for (i = 0; i < 4; i++)
2269       gp->g_du.dis4v1[4*ii + i] = (byte) ntim[i];
2270     }
2271    else if (npck == 2)
2272     {
2273      for (i = 0; i < 4; i++)
2274       gp->g_du.dis4v2[4*ii + i] = (hword) ntim[i];
2275     }
2276    else
2277     { for (i = 0; i < 4; i++) gp->g_du.dis4v[4*ii + i] = ntim[i]; }
2278   }
2279  if (opck == 1) __my_free((char *) sav_du.dis1v1, numinsts);
2280  else if (opck == 2) __my_free((char *) sav_du.dis1v2, 2*numinsts);
2281  else __my_free((char *) sav_du.dis1v, sizeof(word64)*numinsts);
2282 }
2283 
2284 /*
2285  * convert 1 IS packed opck size to 6 IS form packed npck
2286  * separate routine becase 0, 5, 10 must be 0
2287  */
cnv_1is_to_16is(struct gate_t * gp,int32 numinsts,int32 opck,int32 npck)2288 static void cnv_1is_to_16is(struct gate_t *gp, int32 numinsts, int32 opck, int32 npck)
2289 {
2290  register int32 ii, i;
2291  union del_u sav_du;
2292  word64 ntim[16];
2293 
2294  for (i = 0; i < 4; i++) ntim[i] = 0ULL;
2295  sav_du = gp->g_du;
2296  /* build nvals value packed according to npck */
2297  create_disv(gp, numinsts, 16, ntim, npck);
2298 
2299  for (ii = 0; ii < numinsts; ii++)
2300   {
2301    for (i = 1; i < 16; i++)
2302     {
2303      if (i == 5 || i == 10) continue;
2304 
2305      if (opck == 1) ntim[i] = (word64) sav_du.dis1v1[ii];
2306      else if (opck == 2) ntim[i] = (word64) sav_du.dis1v2[ii];
2307      else ntim[i] = sav_du.dis1v[ii];
2308     }
2309    if (npck == 1)
2310     {
2311      for (i = 0; i < 16; i++)
2312       gp->g_du.dis16v1[16*ii + i] = (byte) ntim[i];
2313     }
2314    else if (npck == 2)
2315     {
2316      for (i = 0; i < 16; i++)
2317       gp->g_du.dis16v2[16*ii + i] = (hword) ntim[i];
2318     }
2319    else
2320     { for (i = 0; i < 16; i++) gp->g_du.dis16v[16*ii + i] = ntim[i]; }
2321   }
2322  if (opck == 1) __my_free((char *) sav_du.dis1v1, numinsts);
2323  else if (opck == 2) __my_free((char *) sav_du.dis1v2, 2*numinsts);
2324  else __my_free((char *) sav_du.dis1v, sizeof(word64)*numinsts);
2325 }
2326 
2327 /*
2328  * change from dv? to dis?v
2329  * nvals of tim must be filled
2330  * this always uses 16v form since just pointer to alloced array
2331  */
create_disv(struct gate_t * gp,int32 numinsts,int32 nvals,word64 * tim,int32 wid)2332 static void create_disv(struct gate_t *gp, int32 numinsts, int32 nvals,
2333  word64 *tim, int32 wid)
2334 {
2335  register int32 ii, i;
2336 
2337  if (wid == 1)
2338   {
2339    gp->g_du.dis16v1 = (byte *) __my_malloc(nvals*numinsts);
2340    for (ii = 0; ii < numinsts; ii++)
2341     {
2342      for (i = 0; i < nvals; i++)
2343       gp->g_du.dis16v1[nvals*ii + i] = (byte) tim[i];
2344     }
2345    gp->g_delrep = (nvals == 1) ? DT_IS1V1
2346     : ((nvals == 4) ? DT_IS4V1 : DT_IS16V1);
2347    return;
2348   }
2349  if (wid == 8)
2350   {
2351    gp->g_du.dis16v = (word64 *) __my_malloc(nvals*numinsts*sizeof(word64));
2352    for (ii = 0; ii < numinsts; ii++)
2353     { for (i = 0; i < nvals; i++) gp->g_du.dis16v[nvals*ii + i] = tim[i]; }
2354    gp->g_delrep = (nvals == 1) ? DT_IS1V : ((nvals == 4) ? DT_IS4V : DT_IS16V);
2355    return;
2356   }
2357  /* final rare fits in 2 bytes case */
2358  gp->g_du.dis16v2 = (hword *) __my_malloc(2*nvals*numinsts);
2359  for (ii = 0; ii < numinsts; ii++)
2360   {
2361    for (i = 0; i < nvals; i++)
2362     gp->g_du.dis16v2[nvals*ii + i] = (hword) tim[i];
2363   }
2364  gp->g_delrep = (nvals == 1) ? DT_IS1V2
2365   : ((nvals == 4) ? DT_IS4V2 : DT_IS16V2);
2366 }
2367 
2368 /*
2369  * get width
2370  */
get_ispack(word64 tim)2371 static int32 get_ispack(word64 tim)
2372 {
2373  register word32 w1;
2374 
2375  w1 = (word32) (tim & WORDMASK_ULL);
2376  if (tim > WORDMASK_ULL || (w1 & 0xffff0000) != 0) return(8);
2377  if ((w1 & 0xffffff00) != 0) return(2);
2378  return(1);
2379 }
2380 
2381 /*
2382  * unpack from isv1 to isv2, nvals determines if 1, 4, or 16 value form
2383  * caller must insure unpack will fit
2384  * uses 16v form since just pointer to array
2385  */
unpack_isv1_to_isv2(struct gate_t * gp,int32 numinsts,int32 nvals)2386 static void unpack_isv1_to_isv2(struct gate_t *gp, int32 numinsts, int32 nvals)
2387 {
2388  register int32 ii, i;
2389  union del_u sav_du;
2390 
2391  sav_du = gp->g_du;
2392  gp->g_du.dis16v2 = (hword *) __my_malloc(2*numinsts*nvals);
2393  for (ii = 0; ii < numinsts; ii++)
2394   {
2395    for (i = 0; i < nvals; i++)
2396     gp->g_du.dis16v2[nvals*ii + i] = (hword) sav_du.dis16v1[nvals*ii + i];
2397   }
2398  __my_free((char *) sav_du.dis16v1, numinsts*nvals);
2399  gp->g_delrep = (nvals == 1) ? DT_IS1V2
2400   : ((nvals == 4) ? DT_IS4V2 : DT_IS16V2);
2401 }
2402 
2403 /*
2404  * unpack from isv1 to isv, nvals determines if 1, 4, or 16 value form
2405  * caller must insure unpack will fit
2406  */
unpack_isv1_to_isv(struct gate_t * gp,int32 numinsts,int32 nvals)2407 static void unpack_isv1_to_isv(struct gate_t *gp, int32 numinsts, int32 nvals)
2408 {
2409  register int32 ii, i;
2410  union del_u sav_du;
2411 
2412  sav_du = gp->g_du;
2413  gp->g_du.dis16v = (word64 *) __my_malloc(sizeof(word64)*numinsts*nvals);
2414  for (ii = 0; ii < numinsts; ii++)
2415   {
2416    for (i = 0; i < nvals; i++)
2417     {
2418      gp->g_du.dis16v[nvals*ii + i] = (word64) sav_du.dis16v1[nvals*ii + i];
2419     }
2420   }
2421  __my_free((char *) sav_du.dis16v1, numinsts*nvals);
2422  gp->g_delrep = (nvals == 1) ? DT_IS1V : ((nvals == 4) ? DT_IS4V : DT_IS16V);
2423 }
2424 
2425 /*
2426  * unpack from isv2 to isv, nvals determines if 1, 4, or 16 value form
2427  * caller must insure unpack will fit
2428  * uses 16v form since just ptr to array
2429  */
unpack_isv2_to_isv(struct gate_t * gp,int32 numinsts,int32 nvals)2430 static void unpack_isv2_to_isv(struct gate_t *gp, int32 numinsts, int32 nvals)
2431 {
2432  register int32 ii, i;
2433  union del_u sav_du;
2434 
2435  sav_du = gp->g_du;
2436  gp->g_du.dis16v = (word64 *) __my_malloc(sizeof(word64)*numinsts*nvals);
2437  for (ii = 0; ii < numinsts; ii++)
2438   {
2439    for (i = 0; i < nvals; i++)
2440     {
2441      gp->g_du.dis16v[nvals*ii + i] = (word64) sav_du.dis16v2[nvals*ii + i];
2442     }
2443   }
2444  __my_free((char *) sav_du.dis16v2, 2*numinsts*nvals);
2445  gp->g_delrep = (nvals == 1) ? DT_IS1V : ((nvals == 4) ? DT_IS4V : DT_IS16V);
2446 }
2447 
2448 /*
2449  * zero unused 16v values
2450  */
zero_unused_16v(word64 * tim)2451 static void zero_unused_16v(word64 *tim)
2452 {
2453  tim[0] = 0ULL;
2454  tim[5] = 0ULL;
2455  tim[10] = 0ULL;
2456 }
2457 
2458 /*
2459  * build a delay using current itree loc.
2460  *
2461  * can not be called until delays prepared
2462  * uses current itree loc for instance if delay per inst.
2463  */
__bld_delay_str(char * s,union del_u du,word32 drep)2464 extern char *__bld_delay_str(char *s, union del_u du, word32 drep)
2465 {
2466  register int32 i;
2467  int32 ndels, sav_nd_timstr_suf;
2468  word64 tim[12], timval;
2469  struct mod_t *mdp;
2470  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
2471 
2472  sav_nd_timstr_suf = __nd_timstr_suf;
2473  __nd_timstr_suf = FALSE;
2474  __extract_delval(tim, &ndels, du, drep);
2475  mdp =__inst_mod;
2476  if (ndels > 0 && !mdp->mno_unitcnv)
2477   {
2478    for (i = 0; i < ndels; i++)
2479     { __cnv_ticks_tonum64(&timval, tim[i], mdp); tim[i] = timval; }
2480   }
2481  switch ((byte) drep) {
2482   case DT_1V: case DT_IS1V: case DT_IS1V1: case DT_IS1V2:
2483    sprintf(s, "%s", __to_timstr(s1, &(tim[0])));
2484    break;
2485   case DT_4V: case DT_IS4V: case DT_IS4V1: case DT_IS4V2:
2486    sprintf(s, "%s, %s, %s", __to_timstr(s1, &(tim[0])),
2487     __to_timstr(s2, &(tim[1])), __to_timstr(s3, &(tim[2])));
2488    break;
2489   case DT_16V: case DT_IS16V: case DT_IS16V1: case DT_IS16V2:
2490    for (i = 0; i < ndels; i++)
2491     {
2492      if (i == 0) { sprintf(s, "%s", __to_timstr(s1, &(tim[0]))); continue; }
2493      sprintf(s1, ", %s", __to_timstr(s2, &(tim[i])));
2494      strcat(s, s1);
2495     }
2496    break;
2497   case DT_1X:
2498    sprintf(s, "**EXPR: %s", __to_timstr(s1, &(tim[0]))); break;
2499   case DT_4X:
2500    if (ndels == 3)
2501     {
2502      sprintf(s, "**EXPR: %s, %s, %s", __to_timstr(s1, &(tim[0])),
2503      __to_timstr(s2, &(tim[1])), __to_timstr(s3, &(tim[2])));
2504     }
2505    else
2506     {
2507      sprintf(s, "**EXPR: %s, %s", __to_timstr(s1, &(tim[0])),
2508      __to_timstr(s2, &(tim[1])));
2509     }
2510    break;
2511   case DT_CMPLST: strcpy(s, "**WRONG SOURCE FORM LIST**"); break;
2512   case DT_PTHDST: strcpy(s, "**PATH DESTIONATION PLACE HOLDER**"); break;
2513   case DT_NONE: strcpy(s, "**NO DELAY**"); break;
2514   default: __case_terr(__FILE__, __LINE__);
2515  }
2516  __nd_timstr_suf = sav_nd_timstr_suf;
2517  return(s);
2518 }
2519 
2520 /*
2521  * extract delays and fill passed tim array
2522  *
2523  * caller must push itree loc.
2524  * errors odd delays, and scaling processed by caller above
2525  * only for delays during sim
2526  * can return 1,3,6, or 12 delays
2527  * (or 0 for DT NONE - used for SDF or vpi_ annotate adding new)
2528  *
2529  * SJM 02/03/00 - cast to word64 word32 because packed form always unsigned
2530  */
__extract_delval(word64 * tim,int32 * ndels,union del_u du,word32 drep)2531 extern void __extract_delval(word64 *tim, int32 *ndels, union del_u du,
2532  word32 drep)
2533 {
2534  struct xstk_t *xsp;
2535 
2536  switch ((byte) drep) {
2537   case DT_NONE: *ndels = 0; break;
2538   case DT_1V: tim[0] = du.d1v[0]; *ndels = 1; break;
2539   case DT_IS1V:
2540    tim[0] = du.dis1v[__inum];
2541    *ndels = 1;
2542    break;
2543   case DT_IS1V1:
2544    tim[0] = (word64) du.dis1v1[__inum];
2545    *ndels = 1;
2546    break;
2547   case DT_IS1V2:
2548    tim[0] = (word64) du.dis1v2[__inum];
2549    *ndels = 1;
2550    break;
2551   case DT_4V:
2552    /* (rise, fall, toz) */
2553    tim[0] = du.d4v[1]; tim[1] = du.d4v[0]; tim[2] = du.d4v[2];
2554    *ndels = 3;
2555    break;
2556   case DT_IS4V:
2557    /* (rise, fall, toz) */
2558    tim[0] = du.dis4v[4*__inum + 1];
2559    tim[1] = du.dis4v[4*__inum + 0];
2560    tim[2] = du.dis4v[4*__inum + 2];
2561    *ndels = 3;
2562    break;
2563   case DT_IS4V1:
2564    /* (rise, fall, toz) */
2565    tim[0] = (word64) du.dis4v1[4*__inum + 1];
2566    tim[1] = (word64) du.dis4v1[4*__inum + 0];
2567    tim[2] = (word64) du.dis4v1[4*__inum + 2];
2568    *ndels = 3;
2569    break;
2570   case DT_IS4V2:
2571    /* (rise, fall, toz) */
2572    tim[0] = (word64) du.dis4v2[4*__inum + 1];
2573    tim[1] = (word64) du.dis4v2[4*__inum + 0];
2574    tim[2] = (word64) du.dis4v2[4*__inum + 2];
2575    *ndels = 3;
2576    break;
2577   /* notice all the 6 forms are really size 16 tables */
2578   case DT_16V:
2579    /* map from 16v table to 12 input list form */
2580    __map_16v_to_12vform(tim, du.d16v);
2581    __try_reduce_16vtab(tim, ndels);
2582    break;
2583   case DT_IS16V:
2584    tim[0] = du.dis16v[16*__inum + 4];
2585    tim[1] = du.dis16v[16*__inum + 1];
2586    tim[2] = du.dis16v[16*__inum + 8];
2587    tim[3] = du.dis16v[16*__inum + 6];
2588    tim[4] = du.dis16v[16*__inum + 9];
2589    tim[5] = du.dis16v[16*__inum + 2];
2590    tim[6] = du.dis16v[16*__inum + 12];
2591    tim[7] = du.dis16v[16*__inum + 7];
2592    tim[8] = du.dis16v[16*__inum + 13];
2593    tim[9] = du.dis16v[16*__inum + 3];
2594    tim[10] = du.dis16v[16*__inum + 11];
2595    tim[11] = du.dis16v[16*__inum + 14];
2596    __try_reduce_16vtab(tim, ndels);
2597    break;
2598   case DT_IS16V1:
2599    tim[0] = (word64) du.dis16v1[16*__inum + 4];
2600    tim[1] = (word64) du.dis16v1[16*__inum + 1];
2601    tim[2] = (word64) du.dis16v1[16*__inum + 8];
2602    tim[3] = (word64) du.dis16v1[16*__inum + 6];
2603    tim[4] = (word64) du.dis16v1[16*__inum + 9];
2604    tim[5] = (word64) du.dis16v1[16*__inum + 2];
2605    tim[6] = (word64) du.dis16v1[16*__inum + 12];
2606    tim[7] = (word64) du.dis16v1[16*__inum + 7];
2607    tim[8] = (word64) du.dis16v1[16*__inum + 13];
2608    tim[9] = (word64) du.dis16v1[16*__inum + 3];
2609    tim[10] = (word64) du.dis16v1[16*__inum + 11];
2610    tim[11] = (word64) du.dis16v1[16*__inum + 14];
2611    __try_reduce_16vtab(tim, ndels);
2612    break;
2613   case DT_IS16V2:
2614    tim[0] = (word64) du.dis16v2[16*__inum + 4];
2615    tim[1] = (word64) du.dis16v2[16*__inum + 1];
2616    tim[2] = (word64) du.dis16v2[16*__inum + 8];
2617    tim[3] = (word64) du.dis16v2[16*__inum + 6];
2618    tim[4] = (word64) du.dis16v2[16*__inum + 9];
2619    tim[5] = (word64) du.dis16v2[16*__inum + 2];
2620    tim[6] = (word64) du.dis16v2[16*__inum + 12];
2621    tim[7] = (word64) du.dis16v2[16*__inum + 7];
2622    tim[8] = (word64) du.dis16v2[16*__inum + 13];
2623    tim[9] = (word64) du.dis16v2[16*__inum + 3];
2624    tim[10] = (word64) du.dis16v2[16*__inum + 11];
2625    tim[11] = (word64) du.dis16v2[16*__inum + 14];
2626    __try_reduce_16vtab(tim, ndels);
2627    break;
2628   case DT_1X:
2629    xsp = __eval_xpr(du.d1x);
2630    tim[0] = (word64) xsp->ap[0];
2631    if (xsp->xslen > WBITS) tim[0] |= (((word64) xsp->ap[1]) << 32);
2632    *ndels = 1;
2633    __pop_xstk();
2634    break;
2635   case DT_4X:
2636    xsp = __eval_xpr(du.d4x[1]);
2637    tim[0] = (word64) xsp->ap[0];
2638    if (xsp->xslen > WBITS) tim[0] |= (((word64) xsp->ap[1]) << 32);
2639    __pop_xstk();
2640    xsp = __eval_xpr(du.d4x[0]);
2641    tim[1] = (word64) xsp->ap[0];
2642    if (xsp->xslen > WBITS) tim[1] |= (((word64) xsp->ap[1]) << 32);
2643    __pop_xstk();
2644    if (du.d4x[2] != NULL)
2645     {
2646      xsp = __eval_xpr(du.d4x[2]);
2647      tim[2] = (word64) xsp->ap[0];
2648      if (xsp->xslen > WBITS) tim[2] |= (((word64) xsp->ap[1]) << 32);
2649      __pop_xstk();
2650      *ndels = 3;
2651     }
2652    else
2653     {
2654      /* LOOKATME - is this right */
2655      if (tim[0] < tim[1]) tim[2] = tim[0]; else tim[2] = tim[1];
2656      *ndels = 2;
2657     }
2658    break;
2659   default: __case_terr(__FILE__, __LINE__); *ndels = 0;
2660  }
2661 }
2662 
2663 /*
2664  * map from 16 delay internal table to 12v input form list
2665  */
__map_16v_to_12vform(word64 * ntim,word64 * tim)2666 extern void __map_16v_to_12vform(word64 *ntim, word64 *tim)
2667 {
2668  ntim[0] = tim[4]; ntim[1] = tim[1]; ntim[2] = tim[8];
2669  ntim[3] = tim[6]; ntim[4] = tim[9]; ntim[5] = tim[2];
2670  ntim[6] = tim[12]; ntim[7] = tim[7]; ntim[8] = tim[13];
2671  ntim[9] = tim[3]; ntim[10] = tim[11]; ntim[11] = tim[14];
2672 }
2673 
2674 /*
2675  * try to reduce a 16 value tim form to 2, 3, 6 if possible
2676  * this sets nnvals to number of values after reductions
2677  * for tim narrow just ignore higher values
2678  * reducible to 1 value will never be 16v in first place
2679  */
__try_reduce_16vtab(word64 * tim,int32 * nvals)2680 extern void __try_reduce_16vtab(word64 *tim, int32 *nvals)
2681 {
2682  word64 tmin, tmax;
2683 
2684  /* know already mapped to 12v form */
2685  /* see if can reduce to 6 form */
2686  *nvals = 12;
2687  /* 0->x min(0->1, 0->z) */
2688  tmin = tim[0];
2689  if (tim[2] < tmin) tmin = tim[2];
2690  if (tmin != tim[6]) return;
2691 
2692  /* 1->x min(1->0, 1->z) */
2693  tmin = tim[1];
2694  if (tim[4] < tmin) tmin = tim[4];
2695  if (tmin != tim[8]) return;
2696 
2697  /* z->x min(z->0, z->1) */
2698  tmin = tim[5];
2699  if (tim[3] < tmin) tmin = tim[3];
2700  if (tmin != tim[11]) return;
2701 
2702  /* x->0 max(1->0, z->0) */
2703  tmax = tim[1];
2704  if (tim[5] > tmax) tmax = tim[5];
2705  if (tmax != tim[9]) return;
2706 
2707  /* x->1 max(z->1, 0->1) */
2708  tmax = tim[3];
2709  if (tim[0] > tmax) tmax = tim[0];
2710  if (tmax != tim[7]) return;
2711 
2712  /* x->z max(1->z, 0->z) */
2713  tmax = tim[4];
2714  if (tim[2] > tmax) tmax = tim[2];
2715  if (tmax != tim[10]) return;
2716 
2717  /* see if 6 can reduce to 2 */
2718  *nvals = 6;
2719  if (tim[0] == tim[2] && tim[2] == tim[3] && tim[1] == tim[4]
2720   && tim[4] == tim[5])
2721   { *nvals = 2; return; }
2722  /* see if 6 can reduce to 3 */
2723  if ((tim[0] != tim[3]) || (tim[1] != tim[5]) || (tim[2] != tim[4])) return;
2724  *nvals = 3;
2725 }
2726 
2727 
2728 /*
2729  * DELAY DEBUGGING ROUTINES
2730  */
2731 
2732 /*
2733  * dump all 16 (really 12) delay transitions
2734  * DBG only routine
2735  */
2736 /* ---
2737 extern void __dbg_dump_del(union del_u du, word32 drep)
2738 {
2739  register int32 i;
2740  struct xstk_t *xsp;
2741  struct expr_t *dxp;
2742  word64 dtab[16], tdel, dv0, dv1, dvx, dvz;
2743  char s1[RECLEN], s2[RECLEN], s3[RECLEN];
2744 
2745  switch ((byte) drep) {
2746   case DT_1V:
2747    for (i = 0; i < 16; i++) dtab[i] = du.d1v[0];
2748    break;
2749   case DT_IS1V:
2750    for (i = 0; i < 16; i++) dtab[i] = du.dis1v[__inum];
2751    break;
2752   case DT_IS1V1:
2753    for (i = 0; i < 16; i++)
2754     { dtab[i] = (word64) du.dis1v1[__inum]; }
2755    break;
2756   case DT_IS1V2:
2757    for (i = 0; i < 16; i++)
2758     { dtab[i] = (word64) du.dis1v2[__inum]; }
2759    break;
2760   case DT_4V:
2761    dtab[0x1] = du.d4v[0]; dtab[0x2] = du.d4v[0]; dtab[0x3] = du.d4v[0];
2762    dtab[0x4] = du.d4v[1]; dtab[0x6] = du.d4v[1]; dtab[0x7] = du.d4v[1];
2763    dtab[0x8] = du.d4v[2]; dtab[0x9] = du.d4v[2]; dtab[0xb] = du.d4v[2];
2764    dtab[0xc] = du.d4v[3]; dtab[0xe] = du.d4v[3]; dtab[0xd] = du.d4v[3];
2765    break;
2766   case DT_IS4V:
2767    tdel = du.d4v[4*__inum + 0];
2768    dtab[0x1] = tdel; dtab[0x2] = tdel; dtab[0x3] = tdel;
2769    tdel = du.d4v[4*__inum + 1];
2770    dtab[0x4] = tdel; dtab[0x6] = tdel; dtab[0x7] = tdel;
2771    tdel = du.d4v[4*__inum + 2];
2772    dtab[0x8] = tdel; dtab[0x9] = tdel; dtab[0xb] = tdel;
2773    tdel = du.d4v[4*__inum + 3];
2774    dtab[0xc] = tdel; dtab[0xe] = tdel; dtab[0xd] = tdel;
2775    break;
2776   case DT_IS4V1:
2777    tdel = (word64) du.dis4v1[4*__inum + 0];
2778    dtab[0x1] = tdel; dtab[0x2] = tdel; dtab[0x3] = tdel;
2779    tdel = (word64) du.dis4v1[4*__inum + 1];
2780    dtab[0x4] = tdel; dtab[0x6] = tdel; dtab[0x7] = tdel;
2781    tdel = (word64) du.dis4v1[4*__inum + 2];
2782    dtab[0x8] = tdel; dtab[0x9] = tdel; dtab[0xb] = tdel;
2783    tdel = (word64) du.dis4v1[4*__inum + 3];
2784    dtab[0xc] = tdel; dtab[0xe] = tdel; dtab[0xd] = tdel;
2785    break;
2786   case DT_IS4V2:
2787    tdel = (word64) du.dis4v2[4*__inum + 0];
2788    dtab[0x1] = tdel; dtab[0x2] = tdel; dtab[0x3] = tdel;
2789    tdel = (word64) du.dis4v1[4*__inum + 1];
2790    dtab[0x4] = tdel; dtab[0x6] = tdel; dtab[0x7] = tdel;
2791    tdel = (word64) du.dis4v1[4*__inum + 2];
2792    dtab[0x8] = tdel; dtab[0x9] = tdel; dtab[0xb] = tdel;
2793    tdel = (word64) du.dis4v1[4*__inum + 3];
2794    dtab[0xc] = tdel; dtab[0xe] = tdel; dtab[0xd] = tdel;
2795    break;
2796   case DT_16V:
2797    for (i = 0; i < 16; i++) dtab[i] = du.d16v[i];
2798    break;
2799   case DT_IS16V:
2800    for (i = 0; i < 16; i++) dtab[i] = du.dis16v[16*__inum + i];
2801    break;
2802   case DT_IS16V1:
2803    for (i = 0; i < 16; i++)
2804     {
2805      dtab[i] = (word64) du.dis16v1[16*__inum + i];
2806     }
2807    break;
2808   case DT_IS16V2:
2809    for (i = 0; i < 16; i++)
2810     {
2811      dtab[i] = (word64) du.dis16v2[16*__inum + i];
2812     }
2813    break;
2814   case DT_1X:
2815    xsp = __eval_xpr(du.d1x);
2816    delx_to_deltim(&tdel, du.d1x, xsp);
2817    for (i = 0; i < 16; i++) dtab[i] = tdel;
2818    __pop_xstk();
2819    break;
2820   case DT_4X:
2821    dxp = du.d4x[0];
2822    xsp = __eval_xpr(dxp);
2823    delx_to_deltim(&dv0, dxp, xsp);
2824    __pop_xstk();
2825    dxp = du.d4x[1];
2826    xsp = __eval_xpr(dxp);
2827    delx_to_deltim(&dv1, dxp, xsp);
2828    __pop_xstk();
2829    if (du.d4x[2] == NULL) dvz = (dv1 < dv0) ? dv1 : dv0;
2830    else
2831     {
2832      dxp = du.d4x[2];
2833      xsp = __eval_xpr(dxp);
2834      delx_to_deltim(&dvz, dxp, xsp);
2835      __pop_xstk();
2836     }
2837    if (du.d4x[2] == NULL) dvx = (dv1 < dv0) ? dv1 : dv0;
2838    else
2839     {
2840      if (dv0 < dv1) { dvx = (dv0 < dvz) ? dv0 : dvz; }
2841      else { dvx = (dv1 < dvz) ? dv1 : dvz; }
2842     }
2843    dtab[0x1] = dv0; dtab[0x2] = dv0; dtab[0x3] = dv0;
2844    dtab[0x4] = dv1; dtab[0x6] = dv1; dtab[0x7] = dv1;
2845    dtab[0x8] = dvz; dtab[0x9] = dvz; dtab[0xb] = dvz;
2846    dtab[0xc] = dvx; dtab[0xe] = dvx; dtab[0xd] = dvx;
2847    break;
2848   default: __case_terr(__FILE__, __LINE__);
2849  }
2850  __dbg_msg(":: to 0 transitions: 1->0 = %s, z->0 = %s , x->0 = %s\n",
2851   __to_timstr(s1, &(dtab[0x1])), __to_timstr(s2, &(dtab[0x2])),
2852   __to_timstr(s3, &(dtab[0x3])));
2853  __dbg_msg(":: to 1 transitions: 0->1 = %s, z->1 = %s , x->1 = %s\n",
2854   __to_timstr(s1, &(dtab[0x4])), __to_timstr(s2, &(dtab[0x6])),
2855   __to_timstr(s3, &(dtab[0x7])));
2856  __dbg_msg(":: to z transitions: 0->z = %s, 1->z = %s , x->z = %s\n",
2857   __to_timstr(s1, &(dtab[0x8])), __to_timstr(s2, &(dtab[0x9])),
2858   __to_timstr(s3, &(dtab[0xb])));
2859  __dbg_msg(":: to x transitions: 0->x = %s, 1->x = %s , z->x = %s\n",
2860   __to_timstr(s1, &(dtab[0xc])), __to_timstr(s2, &(dtab[0xd])),
2861   __to_timstr(s3, &(dtab[0xe])));
2862 }
2863 --- */
2864