From 9c28f085d8176c2acf89f540a1ad024708745702 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 11 May 2002 04:39:35 +0000 Subject: [PATCH] Set and get memory words by string value. --- vvp/Makefile.in | 4 +- vvp/vpi_memory.cc | 96 +++++++++++++++++++++++- vvp/vpi_priv.h | 20 ++++- vvp/vpip_bin.cc | 131 +++++++++++++++++++++++++++++++++ vvp/vpip_hex.cc | 118 ++++++++++++++++++++++++++++++ vvp/vpip_oct.cc | 178 +++++++++++++++++++++++++++++++++++++++++++++ vvp/vpip_to_dec.cc | 56 +++++++++++++- 7 files changed, 598 insertions(+), 5 deletions(-) create mode 100644 vvp/vpip_bin.cc create mode 100644 vvp/vpip_hex.cc create mode 100644 vvp/vpip_oct.cc diff --git a/vvp/Makefile.in b/vvp/Makefile.in index 20c72e46a..129664847 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.36 2002/03/18 00:19:34 steve Exp $" +#ident "$Id: Makefile.in,v 1.37 2002/05/11 04:39:35 steve Exp $" # # SHELL = /bin/sh @@ -63,7 +63,7 @@ check: all V = vpi_modules.o vpi_callback.o vpi_const.o vpi_iter.o vpi_mcd.o \ vpi_priv.o vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \ -vpi_vthr_vector.o vpip_to_dec.o vvp_vpi.o +vpi_vthr_vector.o vpip_bin.o vpip_hex.o vpip_oct.o vpip_to_dec.o vvp_vpi.o O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \ functor.o fvectors.o npmos.o resolv.o symbols.o ufunc.o codes.o vthread.o \ diff --git a/vvp/vpi_memory.cc b/vvp/vpi_memory.cc index f6c03a37b..e85b46b26 100644 --- a/vvp/vpi_memory.cc +++ b/vvp/vpi_memory.cc @@ -27,7 +27,7 @@ * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704. */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_memory.cc,v 1.7 2002/05/10 16:00:57 steve Exp $" +#ident "$Id: vpi_memory.cc,v 1.8 2002/05/11 04:39:35 steve Exp $" #endif # include "vpi_priv.h" @@ -251,6 +251,64 @@ static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val, } break; + /* 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; + } + + 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; + } + + 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; + } + + case vpiBinStrVal: { + unsigned char*bits = new unsigned char[(width+3) / 4]; + vpip_bin_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; + } + default: assert(0); } @@ -281,6 +339,26 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) vp->value.str = buf; break; + case vpiOctStrVal: { + unsigned char*bits = new unsigned char[(width+3) / 4]; + + for (unsigned idx = 0 ; idx < width ; idx += 1) { + unsigned bb = idx / 4; + unsigned bs = (idx % 4) * 2; + unsigned val = memory_get(rfp->mem->mem, bidx+idx); + if (bs == 0) + bits[bb] = val; + else + bits[bb] |= val << bs; + } + + vpip_bits_to_oct_str(bits, width, buf, sizeof buf, false); + + delete[]bits; + vp->value.str = buf; + break; + } + case vpiHexStrVal: { unsigned hval, hwid; hwid = (width + 3) / 4; @@ -320,6 +398,19 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) break; } + case vpiDecStrVal: { + unsigned char*bits = new unsigned char[width]; + + for (unsigned idx = 0 ; idx < width ; idx += 1) + bits[idx] = memory_get(rfp->mem->mem, bidx+idx); + + vpip_bits_to_dec_str(bits, width, buf, sizeof buf, false); + + delete[]bits; + vp->value.str = buf; + break; + } + case vpiIntVal: vp->value.integer = 0; for (unsigned idx = 0; idx < width; idx += 1) { @@ -378,6 +469,9 @@ vpiHandle vpip_make_memory(vvp_memory_t mem) /* * $Log: vpi_memory.cc,v $ + * Revision 1.8 2002/05/11 04:39:35 steve + * Set and get memory words by string value. + * * Revision 1.7 2002/05/10 16:00:57 steve * Support scope iterate over vpiNet,vpiReg/vpiMemory. * diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index a2c86a720..4cde65f37 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 */ #if !defined(WINNT) -#ident "$Id: vpi_priv.h,v 1.32 2002/05/03 15:44:11 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.33 2002/05/11 04:39:35 steve Exp $" #endif # include "vpi_user.h" @@ -282,8 +282,26 @@ extern unsigned vpip_bits_to_dec_str(const unsigned char *bits, 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 void vpip_bin_str_to_bits(unsigned char*bits, unsigned nbits, + const char*buf, 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_oct_str_to_bits(unsigned char*bits, unsigned nbits, + const char*buf, bool signed_flag); + /* * $Log: vpi_priv.h,v $ + * Revision 1.33 2002/05/11 04:39:35 steve + * Set and get memory words by string value. + * * Revision 1.32 2002/05/03 15:44:11 steve * Add vpiModule iterator to vpiScope objects. * diff --git a/vvp/vpip_bin.cc b/vvp/vpip_bin.cc new file mode 100644 index 000000000..8c335f8cf --- /dev/null +++ b/vvp/vpip_bin.cc @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2002 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: vpip_bin.cc,v 1.1 2002/05/11 04:39:35 steve Exp $" +#endif + +# include "config.h" +# include "vpi_priv.h" +# include +# include +# include +# include +#ifdef HAVE_MALLOC_H +# include +#endif +# include + +void vpip_bin_str_to_bits(unsigned char*bits, unsigned nbits, + const char*buf, bool signed_flag) +{ + const char*ebuf = buf + strlen(buf); + unsigned char last = 0x00; + unsigned pos = 0; + + for (unsigned idx = 0 ; idx < (nbits+3)/4 ; idx += 1) + bits[idx] = 0; + + while (ebuf > buf) { + unsigned val; + + if (nbits == 0) + break; + + ebuf -= 1; + switch (*ebuf) { + case '0': val = 0x00; break; + case '1': val = 0x01; break; + case 'x': + case 'X': val = 0x02; break; + case 'z': + case 'Z': val = 0x03; break; + default: val = 0x00; break; + } + + last = val; + switch (pos) { + case 0: + bits[0] = val; + pos = 1; + break; + case 1: + bits[0] |= val << 2; + pos = 2; + break; + case 2: + bits[0] |= val << 4; + pos = 3; + break; + case 3: + bits[0] |= val << 6; + bits += 1; + pos = 0; + } + + nbits -= 1; + } + + /* Calculate the pad value based on the top bit and the signed + flag. We may sign extend or zero extend. */ + switch (last) { + case 0: + last = 0x00; + break; + case 1: + last = signed_flag? 0x01 : 0x00; + break; + case 2: + last = 0x02; + break; + case 3: + last = 0x03; + 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; + } + +} + +/* + * $Log: vpip_bin.cc,v $ + * Revision 1.1 2002/05/11 04:39:35 steve + * Set and get memory words by string value. + * + */ + diff --git a/vvp/vpip_hex.cc b/vvp/vpip_hex.cc new file mode 100644 index 000000000..7af11431c --- /dev/null +++ b/vvp/vpip_hex.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2002 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: vpip_hex.cc,v 1.1 2002/05/11 04:39:35 steve Exp $" +#endif + +# include "config.h" +# include "vpi_priv.h" +# include +# include +# include /* for CHAR_BIT */ +# include +#ifdef HAVE_MALLOC_H +# include +#endif +# include + +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.1 2002/05/11 04:39:35 steve + * Set and get memory words by string value. + * + */ + diff --git a/vvp/vpip_oct.cc b/vvp/vpip_oct.cc new file mode 100644 index 000000000..159972245 --- /dev/null +++ b/vvp/vpip_oct.cc @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2002 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: vpip_oct.cc,v 1.1 2002/05/11 04:39:36 steve Exp $" +#endif + +# include "config.h" +# include "vpi_priv.h" +# include +# include +# include +# include +#ifdef HAVE_MALLOC_H +# include +#endif +# include + +extern const char oct_digits[64]; + +void vpip_oct_str_to_bits(unsigned char*bits, unsigned nbits, + const char*buf, bool signed_flag) +{ + const char*ebuf = buf + strlen(buf); + unsigned char last = 0x00; + unsigned pos = 0; + + for (unsigned idx = 0 ; idx < (nbits+3)/4 ; idx += 1) + bits[idx] = 0; + + while (ebuf > buf) { + unsigned val; + + 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; + else + nbits = 0; + } + + /* 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; + } + + 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) +{ + unsigned slen = (nbits + 2) / 3; + unsigned val = 0; + assert(slen < nbuf); + + buf[slen] = 0; + + for (unsigned idx = 0 ; idx < nbits ; idx += 1) { + unsigned bi = idx/4; + unsigned bs = (idx%4) * 2; + unsigned bit = (bits[bi] >> bs) & 3; + + unsigned vs = (idx%3) * 2; + val |= bit << vs; + + if (vs == 4) { + slen -= 1; + buf[slen] = oct_digits[val]; + val = 0; + } + } + + if (slen > 0) { + slen -= 1; + buf[slen] = oct_digits[val]; + } +} + +/* + * $Log: vpip_oct.cc,v $ + * Revision 1.1 2002/05/11 04:39:36 steve + * Set and get memory words by string value. + * + */ + diff --git a/vvp/vpip_to_dec.cc b/vvp/vpip_to_dec.cc index 7cc239df9..54344927d 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 */ #if !defined(WINNT) -#ident "$Id: vpip_to_dec.cc,v 1.3 2002/02/04 00:41:34 steve Exp $" +#ident "$Id: vpip_to_dec.cc,v 1.4 2002/05/11 04:39:36 steve Exp $" #endif # include "config.h" @@ -26,6 +26,7 @@ # include # include /* for CHAR_BIT */ # include +# include #ifdef HAVE_MALLOC_H # include #endif @@ -199,3 +200,56 @@ unsigned vpip_bits_to_dec_str(const unsigned char *bits, unsigned int nbits, /* free(valv); */ return 0; } + + +void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, + const char*buf, bool signed_flag) +{ + /* The str string is the decimal value with the least + significant digit first. */ + unsigned slen = strlen(buf); + char*str = new char[slen + 1]; + for (unsigned idx = 0 ; idx < slen ; idx += 1) { + if (isdigit(buf[slen-idx-1])) + str[idx] = buf[slen-idx-1]; + else + str[idx] = '0'; + } + + for (unsigned idx = 0 ; idx < nbits ; idx += 1) { + unsigned val = 0; + + switch (str[0]) { + case '1': + case '3': + case '5': + case '7': + case '9': + val = 1; + break; + } + + bits[idx] = val; + + char*cp = str; + while (*cp) { + unsigned val = cp[0] - '0'; + if ((val&1) && (cp > str)) + cp[-1] += 5; + + cp[0] = '0' + val/2; + cp += 1; + } + + } + + delete[]str; +} + + +/* + * $Log: vpip_to_dec.cc,v $ + * Revision 1.4 2002/05/11 04:39:36 steve + * Set and get memory words by string value. + * + */