From 50ad415c0d2d95420a1678ce2a9f0ba6184cad29 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 21 Feb 2006 02:39:27 +0000 Subject: [PATCH] Support string values for memory words. --- vvp/vpi_memory.cc | 117 +++++++++++++++++----------------- vvp/vpi_priv.h | 19 +++--- vvp/vpi_signal.cc | 34 ++-------- vvp/vpip_hex.cc | 156 ++++++++++++++++++++++----------------------- vvp/vpip_oct.cc | 148 +++++++++++++++--------------------------- vvp/vpip_to_dec.cc | 135 ++++++++++++++++++++++++++++++++++++--- 6 files changed, 328 insertions(+), 281 deletions(-) diff --git a/vvp/vpi_memory.cc b/vvp/vpi_memory.cc index db0705f02..aec1a1fa8 100644 --- a/vvp/vpi_memory.cc +++ b/vvp/vpi_memory.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_memory.cc,v 1.28 2006/02/02 02:44:00 steve Exp $" +#ident "$Id: vpi_memory.cc,v 1.29 2006/02/21 02:39:27 steve Exp $" #endif # include "vpi_priv.h" @@ -277,69 +277,50 @@ static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val) } break; } -#if 0 - /* If the caller tries to set a HexStrVal, convert it to - bits and write the bits into the word. */ - case vpiHexStrVal: { - unsigned char*bits = new unsigned char[(width+3) / 4]; - vpip_hex_str_to_bits(bits, width, val->value.str, false); - for (unsigned idx = 0 ; idx < width ; idx += 1) { - unsigned bb = idx / 4; - unsigned bs = (idx % 4) * 2; - unsigned val = (bits[bb] >> bs) & 0x03; - memory_set(rfp->mem->mem, bidx+idx, val); - } - - delete[]bits; - break; - } -#endif -#if 0 - case vpiDecStrVal: { - unsigned char*bits = new unsigned char[width]; - vpip_dec_str_to_bits(bits, width, val->value.str, false); - - for (unsigned idx = 0 ; idx < width ; idx += 1) { - memory_set(rfp->mem->mem, bidx+idx, bits[idx]); - } - - delete[]bits; - break; - } -#endif -#if 0 - case vpiOctStrVal: { - unsigned char*bits = new unsigned char[(width+3) / 4]; - vpip_oct_str_to_bits(bits, width, val->value.str, false); - - for (unsigned idx = 0 ; idx < width ; idx += 1) { - unsigned bb = idx / 4; - unsigned bs = (idx % 4) * 2; - unsigned val = (bits[bb] >> bs) & 0x03; - memory_set(rfp->mem->mem, bidx+idx, val); - } - - delete[]bits; - break; - } -#endif -#if 0 case vpiBinStrVal: { - unsigned char*bits = new unsigned char[(width+3) / 4]; - vpip_bin_str_to_bits(bits, width, val->value.str, false); - + char*str = val->value.str; for (unsigned idx = 0 ; idx < width ; idx += 1) { - unsigned bb = idx / 4; - unsigned bs = (idx % 4) * 2; - unsigned val = (bits[bb] >> bs) & 0x03; - memory_set(rfp->mem->mem, bidx+idx, val); + switch (str[width-idx-1]) { + case '0': + put_val.set_bit(idx, BIT4_0); + break; + case '1': + put_val.set_bit(idx, BIT4_1); + break; + case 'x': + case 'X': + put_val.set_bit(idx, BIT4_X); + break; + case 'z': + case 'Z': + put_val.set_bit(idx, BIT4_Z); + break; + default: + assert(0); + } } - - delete[]bits; break; } -#endif + + case vpiOctStrVal: { + char*str = val->value.str; + vpip_oct_str_to_vec4(put_val, str); + break; + } + + case vpiDecStrVal: { + char*str = val->value.str; + vpip_dec_str_to_vec4(put_val, str, false); + break; + } + + case vpiHexStrVal: { + char*str = val->value.str; + vpip_hex_str_to_vec4(put_val, str); + break; + } + default: cerr << "internal error: memory_word put_value format=" << val->format << endl; @@ -393,6 +374,9 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) switch (vp->format) { default: + cerr << "internal error: Format " + << vp->format + << " not implemented" << endl; assert(0 && "format not implemented"); case vpiBinStrVal: @@ -413,6 +397,13 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) break; } + case vpiDecStrVal: { + rbuf = need_result_buf(width+1, RBUF_VAL); + vpip_vec4_to_dec_str(word_val, rbuf, width+1, false); + vp->value.str = rbuf; + break; + } + case vpiHexStrVal: { unsigned hwid = (width + 3) / 4; @@ -423,6 +414,13 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) vp->value.str = rbuf; break; } + + case vpiIntVal: { + unsigned long val; + vector4_to_value(word_val, val); + vp->value.integer = val; + break; + } #if 0 case vpiDecStrVal: { unsigned char*bits = new unsigned char[width]; @@ -557,6 +555,9 @@ vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name) /* * $Log: vpi_memory.cc,v $ + * Revision 1.29 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.28 2006/02/02 02:44:00 steve * Allow part selects of memory words in l-values. * diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index e2da20f55..37523170a 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_priv.h,v 1.64 2005/07/06 04:29:25 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.65 2006/02/21 02:39:27 steve Exp $" #endif # include "vpi_user.h" @@ -395,25 +395,25 @@ extern unsigned vpip_bits_to_dec_str(const unsigned char *bits, unsigned int nbits, char *buf, unsigned int nbuf, int signed_flag); - -extern void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, - const char*buf, bool signed_flag); +extern unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4, + char *buf, unsigned int nbuf, + int signed_flag); extern void vpip_bin_str_to_bits(unsigned char*bits, unsigned nbits, const char*buf, bool signed_flag); extern void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf, bool signed_flag); -extern void vpip_hex_str_to_bits(unsigned char*bits, unsigned nbits, - const char*buf, bool signed_flag); extern void vpip_bits_to_oct_str(const unsigned char*bits, unsigned nbits, char*buf, unsigned nbuf, bool signed_flag); extern void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf, bool signed_flag); -extern void vpip_oct_str_to_bits(unsigned char*bits, unsigned nbits, - const char*buf, bool signed_flag); +extern void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str); +extern void vpip_dec_str_to_vec4(vvp_vector4_t&val, const char*str, bool sign); +extern void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str); + /* * Function defined in vpi_signal.cc to manage vpi_get_* persistent @@ -429,6 +429,9 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type); /* * $Log: vpi_priv.h,v $ + * Revision 1.65 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.64 2005/07/06 04:29:25 steve * Implement real valued signals and arith nodes. * diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 81cf52bff..3ffd3861c 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_signal.cc,v 1.72 2005/11/30 00:42:14 steve Exp $" +#ident "$Id: vpi_signal.cc,v 1.73 2006/02/21 02:39:27 steve Exp $" #endif /* @@ -659,36 +659,7 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp) break; } #endif -#if 0 - case vpiHexStrVal: { - unsigned char*bits = new unsigned char[(wid+3) / 4]; - vpip_hex_str_to_bits(bits, wid, vp->value.str, false); - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - unsigned bb = idx / 4; - unsigned bs = (idx % 4) * 2; - unsigned val = (bits[bb] >> bs) & 0x03; - - switch (val) { - case 0: /* zero */ - functor_poke(rfp,idx, 0, St0, 0); - break; - case 1: /* one */ - functor_poke(rfp,idx, 1, St1, 0); - break; - case 2: /* x */ - functor_poke(rfp,idx, 2, StX, 0); - break; - case 3: /* z */ - functor_poke(rfp,idx, 3, HiZ, 0); - break; - } - } - - delete[]bits; - break; - } -#endif #if 0 case vpiDecStrVal: { unsigned char*bits = new unsigned char[wid]; @@ -822,6 +793,9 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb, /* * $Log: vpi_signal.cc,v $ + * Revision 1.73 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.72 2005/11/30 00:42:14 steve * vpi_signal supports vvp_fun_signal_vec types. * diff --git a/vvp/vpip_hex.cc b/vvp/vpip_hex.cc index a4d9d2e4f..302fec2e1 100644 --- a/vvp/vpip_hex.cc +++ b/vvp/vpip_hex.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpip_hex.cc,v 1.3 2005/06/13 00:54:04 steve Exp $" +#ident "$Id: vpip_hex.cc,v 1.4 2006/02/21 02:39:27 steve Exp $" #endif # include "config.h" @@ -33,6 +33,80 @@ extern const char hex_digits[256]; +void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str) +{ + unsigned str_len = strlen(str); + + char pad = '0'; + switch (str[0]) { + case 'x': + case 'X': + pad = 'x'; + break; + case 'z': + case 'Z': + pad = 'z'; + break; + } + + for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { + unsigned tmp; + unsigned bit_off = idx%4; + unsigned str_off = idx/4; + + char ch; + if (str_off >= str_len) + ch = pad; + else + ch = str[str_len-str_off-1]; + + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tmp = ch - '0'; + val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + tmp = ch - 'a' + 10; + val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0); + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + tmp = ch - 'A' + 10; + val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0); + break; + case 'x': + case 'X': + val.set_bit(idx, BIT4_X); + break; + case 'z': + case 'Z': + val.set_bit(idx, BIT4_Z); + break; + default: + assert(0); + break; + } + } +} + void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf, bool signed_flag) { @@ -83,86 +157,12 @@ void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf, } } -void vpip_hex_str_to_bits(unsigned char*bits, unsigned nbits, - const char*buf, bool signed_flag) -{ - const char*ebuf = buf + strlen(buf); - unsigned char last = 0x00; - - while (ebuf > buf) { - - if (nbits == 0) - break; - - ebuf -= 1; - switch (*ebuf) { - case '0': *bits = 0x00; break; - case '1': *bits = 0x01; break; - case '2': *bits = 0x04; break; - case '3': *bits = 0x05; break; - case '4': *bits = 0x10; break; - case '5': *bits = 0x11; break; - case '6': *bits = 0x14; break; - case '7': *bits = 0x15; break; - case '8': *bits = 0x40; break; - case '9': *bits = 0x41; break; - case 'a': - case 'A': *bits = 0x44; break; - case 'b': - case 'B': *bits = 0x45; break; - case 'c': - case 'C': *bits = 0x50; break; - case 'd': - case 'D': *bits = 0x51; break; - case 'e': - case 'E': *bits = 0x54; break; - case 'f': - case 'F': *bits = 0x55; break; - case 'x': - case 'X': *bits = 0xaa; break; - case 'z': - case 'Z': *bits = 0xff; break; - default: *bits = 0x00; break; - } - - last = *bits; - bits += 1; - if (nbits < 4) - nbits = 0; - else - nbits -= 4; - } - - /* Calculate the pad value based on the top bit and the signed - flag. We may sign extend or zero extend. */ - switch (last >> 6) { - case 0: - last = 0x00; - break; - case 1: - last = signed_flag? 0x55 : 0x00; - break; - case 2: - last = 0xaa; - break; - case 3: - last = 0xff; - break; - } - - while (nbits > 0) { - *bits = last; - bits += 1; - if (nbits < 4) - nbits = 0; - else - nbits -= 4; - } - -} /* * $Log: vpip_hex.cc,v $ + * Revision 1.4 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.3 2005/06/13 00:54:04 steve * More unified vec4 to hex string functions. * diff --git a/vvp/vpip_oct.cc b/vvp/vpip_oct.cc index 7948bbb3a..68b23bcbd 100644 --- a/vvp/vpip_oct.cc +++ b/vvp/vpip_oct.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpip_oct.cc,v 1.3 2005/06/13 00:54:04 steve Exp $" +#ident "$Id: vpip_oct.cc,v 1.4 2006/02/21 02:39:27 steve Exp $" #endif # include "config.h" @@ -33,112 +33,61 @@ extern const char oct_digits[64]; -void vpip_oct_str_to_bits(unsigned char*bits, unsigned nbits, - const char*buf, bool signed_flag) +void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str) { - const char*ebuf = buf + strlen(buf); - unsigned char last = 0x00; - unsigned pos = 0; + unsigned str_len = strlen(str); - for (unsigned idx = 0 ; idx < (nbits+3)/4 ; idx += 1) - bits[idx] = 0; + char pad = '0'; + switch (str[0]) { + case 'x': + case 'X': + pad = 'x'; + break; + case 'z': + case 'Z': + pad = 'z'; + break; + } - while (ebuf > buf) { - unsigned val; + for (unsigned idx = 0 ; idx < val.size() ; idx += 1) { + unsigned tmp; + unsigned bit_off = idx%3; + unsigned str_off = idx/3; - if (nbits == 0) - break; - - ebuf -= 1; - switch (*ebuf) { - case '0': val = 0x00; break; - case '1': val = 0x01; break; - case '2': val = 0x04; break; - case '3': val = 0x05; break; - case '4': val = 0x10; break; - case '5': val = 0x11; break; - case '6': val = 0x14; break; - case '7': val = 0x15; break; - case 'x': - case 'X': val = 0x2a; break; - case 'z': - case 'Z': val = 0x3f; break; - default: val = 0x00; break; - } - - last = val; - switch (pos) { - case 0: - bits[0] = val; - pos = 3; - break; - case 1: - bits[0] |= val << 2; - bits += 1; - pos = 0; - break; - case 2: - bits[0] |= val << 4; - if (nbits > 2) - bits[1] = val >> 4; - bits += 1; - pos = 1; - break; - case 3: - bits[0] |= val << 6; - if (nbits > 1) - bits[1] = val >> 2; - bits += 1; - pos = 2; - } - - if (nbits > 3) - nbits -= 3; + char ch; + if (str_off >= str_len) + ch = pad; else - nbits = 0; - } + ch = str[str_len-str_off-1]; - /* Calculate the pad value based on the top bit and the signed - flag. We may sign extend or zero extend. */ - switch (last >> 4) { - case 0: - last = 0x00; - break; - case 1: - last = signed_flag? 0x01 : 0x00; - break; - case 2: - last = 0x02; - break; - case 3: - last = 0x03; - break; + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + tmp = ch - '0'; + val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0); + break; + case 'x': + case 'X': + val.set_bit(idx, BIT4_X); + break; + case 'z': + case 'Z': + val.set_bit(idx, BIT4_Z); + break; + default: + assert(0); + break; + } } - - while (nbits > 0) switch (pos) { - case 0: - bits[0] = last; - nbits -= 1; - pos = 1; - break; - case 1: - bits[0] |= last << 2; - nbits -= 1; - pos = 2; - break; - case 2: - bits[0] |= last << 4; - bits -= 1; - pos = 3; - case 3: - bits[0] |= last << 6; - nbits -= 1; - bits += 1; - pos = 0; - } - } + void vpip_bits_to_oct_str(const unsigned char*bits, unsigned nbits, char*buf, unsigned nbuf, bool signed_flag) { @@ -209,6 +158,9 @@ void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf, /* * $Log: vpip_oct.cc,v $ + * Revision 1.4 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.3 2005/06/13 00:54:04 steve * More unified vec4 to hex string functions. * diff --git a/vvp/vpip_to_dec.cc b/vvp/vpip_to_dec.cc index 229df42ef..027a46202 100644 --- a/vvp/vpip_to_dec.cc +++ b/vvp/vpip_to_dec.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpip_to_dec.cc,v 1.7 2004/10/04 01:11:00 steve Exp $" +#ident "$Id: vpip_to_dec.cc,v 1.8 2006/02/21 02:39:27 steve Exp $" #endif # include "config.h" @@ -105,9 +105,123 @@ static inline int write_digits(unsigned long v, char **buf, } -/* bits[0] is the lsb - * bits[nbits-1] is the msb or sign bit - */ +unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4, + char *buf, unsigned int nbuf, + int signed_flag) +{ + unsigned int idx, len, vlen; + unsigned int mbits=vec4.size(); /* number of non-sign bits */ + unsigned count_x = 0, count_z = 0; + /* Jump through some hoops so we don't have to malloc/free valv + * on every call, and implement an optional malloc-less version. */ + static unsigned long *valv=NULL; + static unsigned int vlen_alloc=0; + + unsigned long val=0; + int comp=0; + if (signed_flag) { + switch (vec4.value(vec4.size()-1)) { + case BIT4_X: + count_x += 1; + break; + case BIT4_Z: + count_z += 1; + break; + case BIT4_1: + comp=1; + break; + case BIT4_0: + break; + } + mbits -= 1; + } + assert(mbits<(UINT_MAX-92)/28); + vlen = ((mbits*28+92)/93+BDIGITS-1)/BDIGITS; + /* printf("vlen=%d\n",vlen); */ + +#define ALLOC_MARGIN 4 + if (!valv || vlen > vlen_alloc) { + if (valv) free(valv); + valv = (unsigned long*) + calloc( vlen+ALLOC_MARGIN, sizeof (*valv)); + if (!valv) {perror("malloc"); return 0; } + vlen_alloc=vlen+ALLOC_MARGIN; + } else { + memset(valv,0,vlen*sizeof(valv[0])); + } + + for (idx = 0; idx < mbits; idx += 1) { + /* printf("%c ",bits[mbits-idx-1]); */ + switch (vec4.value(mbits-idx-1)) { + case BIT4_Z: + count_z += 1; + break; + case BIT4_X: + count_x += 1; + break; + case BIT4_1: + if (! comp) + val += 1; + break; + case BIT4_0: + if (comp) + val += 1; + break; + } + + if ((mbits-idx-1)%BBITS==0) { + /* make negative 2's complement, not 1's complement */ + if (comp && idx==mbits-1) ++val; + shift_in(valv,vlen,val); + val=0; + } else { + val=val+val; + } + } + + if (count_x == vec4.size()) { + len = 1; + buf[0] = 'x'; + buf[1] = 0; + } else if (count_x > 0) { + len = 1; + buf[0] = 'X'; + buf[1] = 0; + } else if (count_z == vec4.size()) { + len = 1; + buf[0] = 'z'; + buf[1] = 0; + } else if (count_z > 0) { + len = 1; + buf[0] = 'Z'; + buf[1] = 0; + } else { + int i; + int zero_suppress=1; + if (comp) { + *buf++='-'; + nbuf--; + /* printf("-"); */ + } + for (i=vlen-1; i>=0; i--) { + zero_suppress = write_digits(valv[i], + &buf,&nbuf,zero_suppress); + /* printf(",%.4u",valv[i]); */ + } + /* Awkward special case, since we don't want to + * zero suppress down to nothing at all. The only + * way we can still have zero_suppress on in the + * comp=1 case is if mbits==0, and therefore vlen==0. + * We represent 1'sb1 as "-1". */ + if (zero_suppress) *buf++='0'+comp; + /* printf("\n"); */ + *buf='\0'; + } + /* hold on to the memory, since we expect to be called again. */ + /* free(valv); */ + return 0; +} + unsigned vpip_bits_to_dec_str(const unsigned char *bits, unsigned int nbits, char *buf, unsigned int nbuf, int signed_flag) { @@ -202,7 +316,7 @@ unsigned vpip_bits_to_dec_str(const unsigned char *bits, unsigned int nbits, } -void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, +void vpip_dec_str_to_vec4(vvp_vector4_t&vec, const char*buf, bool signed_flag) { /* The str string is the decimal value with the least @@ -220,8 +334,8 @@ void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, str[slen] = 0; - for (unsigned idx = 0 ; idx < nbits ; idx += 1) { - unsigned val = 0; + for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) { + vvp_bit4_t val4 = BIT4_0; switch (str[0]) { case '1': @@ -229,11 +343,11 @@ void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, case '5': case '7': case '9': - val = 1; + val4 = BIT4_1; break; } - bits[idx] = val; + vec.set_bit(idx, val4); /* Divide the str string by 2 in decimal. */ char*cp = str; @@ -254,6 +368,9 @@ void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, /* * $Log: vpip_to_dec.cc,v $ + * Revision 1.8 2006/02/21 02:39:27 steve + * Support string values for memory words. + * * Revision 1.7 2004/10/04 01:11:00 steve * Clean up spurious trailing white space. *