Use Larrys bits-to-decimal-string code.
This commit is contained in:
parent
78bb3d6f09
commit
ec82af0c74
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.34 2002/01/02 02:39:34 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.35 2002/02/03 01:01:51 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 vvp_vpi.o
|
||||
vpi_vthr_vector.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 codes.o vthread.o schedule.o \
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_const.cc,v 1.10 2002/01/31 04:28:17 steve Exp $"
|
||||
#ident "$Id: vpi_const.cc,v 1.11 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
|
|
@ -219,48 +219,13 @@ static void binary_value(vpiHandle ref, p_vpi_value vp)
|
|||
vp->format = vpiBinStrVal;
|
||||
break;
|
||||
|
||||
case vpiDecStrVal: {
|
||||
unsigned long val = 0;
|
||||
unsigned count_x = 0, count_z = 0;
|
||||
case vpiDecStrVal:
|
||||
vpip_bits_to_dec_str(rfp->bits, rfp->nbits,
|
||||
buf, sizeof buf, 0);
|
||||
|
||||
vp->value.str = buf;
|
||||
|
||||
for (unsigned idx = 0 ; idx < rfp->nbits ; idx += 1) {
|
||||
unsigned nibble = idx/4;
|
||||
unsigned shift = 2 * (idx%4);
|
||||
unsigned bit_val = (rfp->bits[nibble] >> shift) & 3;
|
||||
switch (bit_val) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
val |= 1 << idx;
|
||||
break;
|
||||
case 2:
|
||||
count_x += 1;
|
||||
break;
|
||||
case 3:
|
||||
count_z += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count_z == rfp->nbits) {
|
||||
sprintf(buf, "z");
|
||||
|
||||
} else if (count_x == rfp->nbits) {
|
||||
sprintf(buf, "x");
|
||||
|
||||
} else if ((count_z > 0) && (count_x == 0)) {
|
||||
sprintf(buf, "Z");
|
||||
|
||||
} else if (count_x > 0) {
|
||||
sprintf(buf, "X");
|
||||
|
||||
} else {
|
||||
sprintf(buf, "%lu", val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
vp->value.str = buf;
|
||||
vp->format = vpiDecStrVal;
|
||||
break;
|
||||
|
||||
case vpiIntVal: {
|
||||
unsigned val = 0;
|
||||
|
|
@ -438,6 +403,9 @@ vpiHandle vpip_make_dec_const(int value)
|
|||
|
||||
/*
|
||||
* $Log: vpi_const.cc,v $
|
||||
* Revision 1.11 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.10 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.27 2002/01/31 04:28:17 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.28 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -255,8 +255,22 @@ extern void vpip_set_time_precision(int pres);
|
|||
extern vpiHandle ipoint_get_scope(vvp_ipoint_t ipt);
|
||||
extern void functor_set_scope(vpiHandle scope);
|
||||
|
||||
/*
|
||||
* This function is used to make decimal string versions of various
|
||||
* vectors. The input format is an array of bit values (0, 1, 2, 3)
|
||||
* lsb first, and the result is written into buf, without overflowing
|
||||
* nbuf.
|
||||
*/
|
||||
extern unsigned vpip_bits_to_dec_str(const unsigned char *bits,
|
||||
unsigned int nbits,
|
||||
char *buf, unsigned int nbuf,
|
||||
int signed_flag);
|
||||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.28 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.27 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_signal.cc,v 1.32 2002/01/09 03:29:12 steve Exp $"
|
||||
#ident "$Id: vpi_signal.cc,v 1.33 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -146,76 +146,21 @@ static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
|
|||
? (rfp->msb - rfp->lsb + 1)
|
||||
: (rfp->lsb - rfp->msb + 1);
|
||||
|
||||
unsigned long val = 0;
|
||||
unsigned count_x = 0, count_z = 0;
|
||||
|
||||
unsigned char*bits = new unsigned char[wid];
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, wid-idx-1);
|
||||
val *= 2;
|
||||
switch (functor_get(fptr)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
val += 1;
|
||||
break;
|
||||
case 2:
|
||||
count_x += 1;
|
||||
break;
|
||||
case 3:
|
||||
count_z += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count_x == wid) {
|
||||
need_result_buf(2);
|
||||
result_buf[0] = 'x';
|
||||
result_buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_x > 0) {
|
||||
need_result_buf(2);
|
||||
result_buf[0] = 'X';
|
||||
result_buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_z == wid) {
|
||||
need_result_buf(2);
|
||||
result_buf[0] = 'z';
|
||||
result_buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_z > 0) {
|
||||
need_result_buf(2);
|
||||
result_buf[0] = 'Z';
|
||||
result_buf[1] = 0;
|
||||
return;
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
|
||||
bits[idx] = functor_get(fptr);
|
||||
}
|
||||
|
||||
need_result_buf((wid+2) / 3 + 1);
|
||||
|
||||
if (rfp->signed_flag) {
|
||||
long tmp;
|
||||
assert(sizeof(tmp) == sizeof(val));
|
||||
if (val & (1<<(wid-1)) && wid < 8*sizeof(tmp)) {
|
||||
tmp = -1;
|
||||
tmp <<= wid;
|
||||
tmp |= val;
|
||||
} else {
|
||||
tmp = val;
|
||||
}
|
||||
sprintf(result_buf, "%ld", tmp);
|
||||
assert(strlen(result_buf) < result_buf_size);
|
||||
vpip_bits_to_dec_str(bits, wid, result_buf, result_buf_size,
|
||||
rfp->signed_flag);
|
||||
|
||||
} else {
|
||||
sprintf(result_buf, "%lu", val);
|
||||
assert(strlen(result_buf) < result_buf_size);
|
||||
}
|
||||
delete[]bits;
|
||||
}
|
||||
|
||||
|
||||
static void signal_vpiStringVal(struct __vpiSignal*rfp, s_vpi_value*vp)
|
||||
{
|
||||
char*cp;
|
||||
|
|
@ -587,6 +532,9 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
|
|||
|
||||
/*
|
||||
* $Log: vpi_signal.cc,v $
|
||||
* Revision 1.33 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.32 2002/01/09 03:29:12 steve
|
||||
* String prints of non-round vectors (PR378)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Larry Doolittle (larry@doolittle.boa.org)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <limits.h> /* for CHAR_BIT */
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <assert.h>
|
||||
|
||||
/* If you are allergic to malloc, you can set a stack memory allocation
|
||||
* here. Otherwise, malloc() is used for the temporary array, so the
|
||||
* conversion length is unlimited. */
|
||||
/* #define MAX_DIGITS 20 */
|
||||
|
||||
|
||||
#ifndef SIZEOF_UNSIGNED_LONG
|
||||
#define SIZEOF_UNSIGNED_LONG 4
|
||||
#endif
|
||||
|
||||
#if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 64
|
||||
#define BDIGITS 9
|
||||
#define BASE 1000000000
|
||||
#define BBITS 32
|
||||
#define BMASK 0xffffffff
|
||||
#else
|
||||
#if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 32
|
||||
#define BDIGITS 4
|
||||
#define BASE 10000
|
||||
#define BBITS 16
|
||||
#define BMASK 0xffff
|
||||
#else
|
||||
#error apparent non-conforming word length
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define B_IS0(x) ((x) == 0)
|
||||
#define B_IS1(x) ((x) == 1)
|
||||
#define B_ISX(x) ((x) == 2)
|
||||
#define B_ISZ(x) ((x) == 3)
|
||||
|
||||
/* The program works by building a base BASE representation of the number
|
||||
* in the valv array. BBITS bits of the number can be put in at a time.
|
||||
* Previous values of each valv element are always less than BASE, the
|
||||
* input val is less than or equal to 2^BBITS, so (valv[i]<<BBITS)+val
|
||||
* is guaranteed less than or equal to BASE<<BBITS, which is configured
|
||||
* less than ULONG_MAX. When this number divided by BASE, to get the amount
|
||||
* propagated as a "carry" to the next array element, the result is again
|
||||
* less than or equal to 2^BBITS. BBITS and BASE are configured above
|
||||
* to depend on the "unsigned long" length of the host, for efficiency.
|
||||
*/
|
||||
static inline void shift_in(unsigned long *valv, unsigned int vlen, unsigned long val)
|
||||
{
|
||||
unsigned int i;
|
||||
/* printf("shift in %u\n",val); */
|
||||
for (i=0; i<vlen; i++) {
|
||||
val=(valv[i]<<BBITS)+val;
|
||||
valv[i]=val%BASE;
|
||||
val=val/BASE;
|
||||
}
|
||||
if (val!=0)
|
||||
fprintf(stderr,"internal error: carry out %lu in " __FILE__ "\n",val);
|
||||
}
|
||||
|
||||
/* Since BASE is a power of ten, conversion of each element of the
|
||||
* valv array to decimal is easy. sprintf(buf,"%d",v) could be made
|
||||
* to work, I suppose, but for speed and control I prefer to write
|
||||
* the steps out longhand.
|
||||
*/
|
||||
static inline int write_digits(unsigned long v, char **buf,
|
||||
unsigned int *nbuf, int zero_suppress)
|
||||
{
|
||||
char segment[BDIGITS];
|
||||
int i;
|
||||
for (i=BDIGITS-1; i>=0; --i) {
|
||||
segment[i] = '0' + v%10;
|
||||
v=v/10;
|
||||
}
|
||||
for (i=0; i<BDIGITS; ++i) {
|
||||
if (!(zero_suppress&=(segment[i]=='0'))) {
|
||||
*(*buf)++=segment[i]; --(*nbuf);
|
||||
}
|
||||
}
|
||||
return zero_suppress;
|
||||
}
|
||||
|
||||
|
||||
/* bits[0] is the lsb
|
||||
* bits[nbits-1] is the msb or sign bit
|
||||
*/
|
||||
unsigned vpip_bits_to_dec_str(const unsigned char *bits, unsigned int nbits,
|
||||
char *buf, unsigned int nbuf, int signed_flag)
|
||||
{
|
||||
unsigned int idx, len, vlen;
|
||||
unsigned int mbits=nbits; /* 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 int vlen_alloc=0;
|
||||
|
||||
unsigned long val=0;
|
||||
int comp=0;
|
||||
if (signed_flag) {
|
||||
if (B_ISZ(bits[nbits-1])) count_z++;
|
||||
else if (B_ISX(bits[nbits-1])) count_x++;
|
||||
else if (B_IS1(bits[nbits-1])) comp=1;
|
||||
--mbits;
|
||||
}
|
||||
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]); */
|
||||
if (B_ISZ(bits[mbits-idx-1])) count_z++;
|
||||
else if (B_ISX(bits[mbits-idx-1])) count_x++;
|
||||
else if (!comp && B_IS1(bits[mbits-idx-1])) ++val;
|
||||
else if ( comp && B_IS0(bits[mbits-idx-1])) ++val;
|
||||
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 == nbits) {
|
||||
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 == nbits) {
|
||||
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;
|
||||
}
|
||||
Loading…
Reference in New Issue