Support string values for memory words.

This commit is contained in:
steve 2006-02-21 02:39:27 +00:00
parent 4ba2afbbe1
commit 50ad415c0d
6 changed files with 328 additions and 281 deletions

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*