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 * various code macro definitions 30 * mostly for speed in long value processing 31 * notice these macros sometimes use globals and call procedures 32 * that are assumed to be defined 33 */ 34 35 /* DBG remove - */ 36 extern void __push_itstk(struct itree_t *); 37 extern void __pop_itstk(void); 38 /* --- */ 39 40 /* these make only 1 or 2 percent different in worse case now */ 41 /* RELEASE NOLONGERUSED MAYBE ADD -- 42 #define __push_itstk(itp) \ 43 do { \ 44 __itstk[++__itspi] = __inst_ptr = (itp); \ 45 __inst_mod = __inst_ptr->itip->imsym->el.emdp; \ 46 __inum = __inst_ptr->itinum; \ 47 } while (0) 48 --- */ 49 50 /* remove assign of nil to inst mod to improve speed if needed */ 51 /* RELEASE NOLONGERUSED MAYBE ADD -- 52 #define __pop_itstk() \ 53 do { \ 54 __inst_ptr = __itstk[--__itspi]; \ 55 if (__itspi != -1) \ 56 { \ 57 __inst_mod = __inst_ptr->itip->imsym->el.emdp; \ 58 __inum = __inst_ptr->itinum; \ 59 } \ 60 -* else { __inst_mod = NULL; __inum = 0xffffffff; } *- \ 61 else __inst_mod = NULL; \ 62 } while (0) 63 -- */ 64 65 /* DBG ??? add -- 66 extern void __pop_xstk(void); 67 -- */ 68 69 /* --- release add */ 70 #define __pop_xstk() __xspi-- 71 /* -- */ 72 73 /* DBG ??? add -- 74 extern struct xstk_t *__push_xstk(int32); 75 #define push_xstk_(xsp, blen) (xsp) = __push_xstk((blen)) 76 --- */ 77 78 /* BEWARE - a and b parts must be contiguous because often refed as only a */ 79 /*--- release add --- */ 80 #define push_xstk_(xsp, blen) \ 81 do { \ 82 if (++__xspi >= __maxxnest) __grow_xstk(); \ 83 (xsp) = __xstk[__xspi]; \ 84 if (wlen_(blen) > (xsp)->xsawlen) __chg_xstk_width((xsp), wlen_(blen)); \ 85 (xsp)->bp = &((xsp)->ap[wlen_(blen)]); \ 86 (xsp)->xslen = (blen); \ 87 } while (0) 88 /* --- */ 89 90 /* DBG ??? add -- 91 extern struct xstk_t *__eval_xpr(struct expr_t *); 92 --- */ 93 /* --- release add */ 94 #define __eval_xpr __eval2_xpr 95 /* --- */ 96 97 /* DBG ??? add --- */ 98 extern i_tev_ndx __alloc_tev(int32, struct itree_t *, word64); 99 #define alloc_tev_(tevpi, etyp, itp, absetime) \ 100 (tevpi) = __alloc_tev((etyp), (itp), (absetime)) 101 /*--- */ 102 103 /* -- ??? release add 104 #define alloc_tev_(tevpi, etyp, itp, absetime) \ 105 do { \ 106 register struct tev_t *tevp__; \ 107 if (__tefreelsti != -1) \ 108 { tevpi = __tefreelsti; __tefreelsti = __tevtab[__tefreelsti].tenxti; } \ 109 else \ 110 { \ 111 if (++__numused_tevtab >= __size_tevtab) __grow_tevtab(); \ 112 tevpi = __numused_tevtab; \ 113 } \ 114 tevp__ = &(__tevtab[tevpi]); \ 115 memset(tevp__, 0, sizeof(struct tev_t)); \ 116 tevp__->tetyp = etyp; \ 117 tevp__->teitp = itp; \ 118 tevp__->etime = absetime; \ 119 tevp__->tenxti = -1; \ 120 } while (0) 121 -- */ 122 123 #define ld_scalval_(ap, bp, bytp) \ 124 do { \ 125 (ap)[0] = (word32) ((bytp)[__inum]); \ 126 (bp)[0] = ((ap)[0] >> 1) & 1L; \ 127 (ap)[0] &= 1L; \ 128 } while(0) 129 130 /* LOOKATME _ notice this assumes av and bv values only occupy low bit */ 131 #define st_scalval_(bp, av, bv) \ 132 (bp)[__inum] = (byte) ((av) | ((bv) << 1)) 133 134 #define st2_scalval_(bp, val) (bp)[__inum] = (byte) (val) 135 136 #define chg_st_scalval_(bp, av, bv) \ 137 do { \ 138 register word32 nval__; \ 139 nval__ = (av) | ((bv) << 1); \ 140 if (((word32) (bp)[__inum]) != (nval__)) \ 141 { (bp)[__inum] = (byte) (nval__); __lhs_changed = TRUE; } \ 142 } while(0) 143 144 #define get_stwire_addr_(sbp, np) \ 145 (sbp) = &((np)->nva.bp[np->nwid*__inum]) 146 147 /* DBG ??? add -- 148 extern void __record_nchg(struct net_t *); 149 #define record_nchg_(np) __record_nchg(np) 150 --- */ 151 152 /* SJM 08/08/03 - can't assume caller turns off chged flag any more */ 153 /* but one record called, it must be off for dctrl processing - not needed */ 154 155 /* recording var change macros */ 156 /* DBG ??? release add --- */ 157 #define record_nchg_(np) \ 158 do { \ 159 __lhs_changed = FALSE; \ 160 if (np->nchg_has_dces) \ 161 __wakeup_delay_ctrls(np, -1, -1); \ 162 if (((np)->nchgaction[__inum] & NCHG_ALL_CHGED) == 0) __add_nchglst_el(np); \ 163 if (((np)->nchgaction[__inum] & (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \ 164 == (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \ 165 { \ 166 (np)->nchgaction[__inum] &= ~(NCHG_DMPVNOTCHGED); \ 167 __add_dmpv_chglst_el(np); \ 168 } \ 169 } while (0) 170 171 /* --- */ 172 173 /* DBG ??? add --- 174 extern void __record_sel_nchg(struct net_t *, int32, int32); 175 #define record_sel_nchg_(np, i1, i2) __record_sel_nchg(np, i1, i2) 176 --- */ 177 178 /* SJM 08/08/03 - can't assume caller turns off chged flag any more */ 179 /* but one record called, it must be off for dctrl processing - not needed */ 180 /* DBG ??? release add --- */ 181 #define record_sel_nchg_(np, i1, i2) \ 182 do { \ 183 __lhs_changed = FALSE; \ 184 if ((np)->dcelst != NULL) __wakeup_delay_ctrls(np, (i1), (i2)); \ 185 if (((np)->nchgaction[__inum] & NCHG_ALL_CHGED) == 0) \ 186 __add_select_nchglst_el((np), (i1), (i2)); \ 187 if (((np)->nchgaction[__inum] & (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \ 188 == (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \ 189 { \ 190 (np)->nchgaction[__inum] &= ~(NCHG_DMPVNOTCHGED); \ 191 __add_dmpv_chglst_el(np); \ 192 } \ 193 } while (0) 194 /* --- */ 195 196 /* conversion macros */ 197 #define valtoch_(c) (((c) < 10) ? '0' + (c) : 'a' + (c) - 10) 198 /* conversion from real to int32 in Verilog is rounding away from 0 */ 199 #define ver_rint_(x) ((int32) (((x) >= 0.0) \ 200 ? ((x) + 0.500000000) : ((x) - 0.500000000))) 201 #define ver_rword(x) ((word32) ((x) + 0.500000000)) 202 203 /* convert a 64 bit delay to no. of sim ticks */ 204 #define cnv_num64to_ticks_(tickstim, inttim, mdp) \ 205 (tickstim) = __itoticks_tab[__des_timeprec - (mdp)->mtime_units]*(inttim) 206 207 /* value extraction macros */ 208 #define get_packintowrd_(nva, inum, vecw) \ 209 (((vecw) <= 4) ? ((word32) (nva).bp[(inum)]) \ 210 : (((vecw) > 8) ? (nva).wp[(inum)] : (word32) (nva).hwp[(inum)])) 211 212 #define st_packintowrd_(nva, ind, uwrd, vecw) \ 213 (((vecw) <= 4) ? ((nva).bp[(ind)] = (byte) (uwrd)) \ 214 : (((vecw) > 8) ? ((nva).wp[(ind)] = (uwrd)) : ((nva).hwp[(ind)] = (hword) (uwrd)))) 215 216 #define ubits_(blen) ((blen) & 0x1f) 217 #define wlen_(blen) (((blen) + 31) >> 5) 218 #define get_wofs_(bi) ((bi) >> 5) 219 #define get_bofs_(bi) ((bi) & 0x1f) 220 221 /* version of ubits that returns 32 for all used not 0 */ 222 #define ubits2_(blen) (((blen & 0x1f) == 0) ? WBITS : (blen & 0x1f)) 223 224 /* get conducting tranif state for cur. instance (for non input 3rd gate) */ 225 /* possibilities are 1 on, 0 off, or 3 unknown */ 226 #define get_tranif_onoff_(gp) \ 227 (((gp)->gstate.wp[get_wofs_(2*__inum)] >> get_bofs_(2*__inum)) & 3L) 228 229 /* -- unused */ 230 /* #define cmpxlen(w1, b1, w2, b2) \ */ 231 /* (((w1)==(w2)) ? ((b1) - (b2)) : ((w1) - (w2))) */ 232 233 /* comparison macros */ 234 #define cvt_wrdbool_(av, bv) \ 235 ((((av) & ~(bv)) != 0L) ? 1 : (((bv) != 0L) ? 3 : 0)) 236 237 #define vval_is0_(wp, blen) \ 238 (((blen) <= WBITS) ? (*(wp) == 0L) : __wide_vval_is0((wp), (blen))) 239 240 /* comparing entire 2 wlen section - unused in both must be 0 */ 241 #define cmp_vval_(wp1, wp2, blen) \ 242 memcmp((wp2), (wp1), (WRDBYTES*(wlen_(blen)))) 243 #define cmp_wvval_(wp1, wp2, wlen) memcmp((wp2), (wp1), (WRDBYTES*wlen)) 244 245 /* bit load and store macros */ 246 #define rhsbsel_(wp, bi) ((wp)[get_wofs_(bi)] >> get_bofs_(bi)) & 1L 247 248 /* value change macros - can't assume no overlap here */ 249 #define cp_walign_(dwp, swp, blen) \ 250 memmove((dwp), (swp), (int32) (WRDBYTES*(wlen_(blen)))); \ 251 (dwp)[wlen_(blen) - 1] &= __masktab[ubits_(blen)] 252 253 #define zero_allbits_(wp, blen) memset(((wp)), 0, \ 254 (int32) (WRDBYTES*(wlen_(blen)))) 255 256 #define one_allbits_(wp, blen) \ 257 do { register int32 __i; \ 258 for (__i = 0; __i < wlen_(blen); __i++) (wp)[__i] = ALL1W; \ 259 (wp)[(wlen_(blen)) - 1] &= __masktab[ubits_(blen)]; \ 260 } while (0) 261 262 /* macro must be passed a byte pointer */ 263 #define set_byteval_(sbp, len, stval) \ 264 do { register int32 __i; \ 265 for (__i = 0; __i < (len); __i++) (sbp)[__i] = ((byte) (stval)); \ 266 } while (0) 267 268 /* this macro may need to be surrounded by { } in some places */ 269 #define set_regtox_(ap, bp, len) \ 270 one_allbits_((ap), len); one_allbits_((bp), len); 271 272 /* map index from source [i1:i2] to internal h:0 */ 273 #define normalize_ndx_(ndxval, mi1, mi2) \ 274 (((mi1) >= (mi2)) ? (ndxval - mi2) : (mi2 - ndxval)) 275 276 /* misc macros */ 277 #define reg_fr_inhibit_(np) \ 278 (np->nu2.qcval[2*__inum].qc_active \ 279 || np->nu2.qcval[2*__inum + 1].qc_active) 280 281 /* i/o macros */ 282 283 #define vis_white_(c) \ 284 ((((__pv_ctv = __pv_ctab[(c) & 0x7f]) == 1) || __pv_ctv == 3) ? TRUE : FALSE) 285 286 #define vis_nonnl_white_(c) ((__pv_ctab[(c) & 0x7f] == 1) ? TRUE : FALSE) 287 288 /* notice this does not leave line null terminated */ 289 #define addch_(ch) \ 290 do { \ 291 if (__cur_sofs >= __exprlinelen - 1) __chg_xprline_size(1); \ 292 __exprline[__cur_sofs++] = (ch); \ 293 } while (0) 294 295 #define my_puts_(s, f) \ 296 do { \ 297 fputs((s), (f)); \ 298 if ((f) == stdout && __log_s != NULL) fputs((s), __log_s); \ 299 } while (0) 300 301 #define my_putc_(c, f) \ 302 do { \ 303 fputc((c), (f)); \ 304 if ((f) == stdout && __log_s != NULL) fputc((c), __log_s); \ 305 } while (0) 306 307 #define my_ungetc_(c, f) \ 308 if (f == NULL) \ 309 { if (c == EOF) *__visp->vichp = '\0'; else *(--__visp->vichp) = c; } \ 310 else ungetc(c, f) 311 312 /* must follow convention only immediately read char can be pushed back */ 313 /* --- DBG remove --- 314 #define my_ungetc_(c, f) \ 315 if (f == NULL) \ 316 { \ 317 if (c == EOF) \ 318 { \ 319 if (*__visp->vichp != '\0') __arg_terr(__FILE__, __LINE__); \ 320 *__visp->vichp = '\0'; \ 321 } \ 322 else \ 323 { \ 324 (__visp->vichp)--; \ 325 if (*__visp->vichp != c) __arg_terr(__FILE__, __LINE__); \ 326 *(__visp->vichp) = c; \ 327 } \ 328 } \ 329 else ungetc(c, f) \ 330 ---- */ 331