mirror of
https://github.com/verilator/verilator.git
synced 2025-04-16 01:26:54 +00:00
Add V3Number display function, unused as yet
git-svn-id: file://localhost/svn/verilator/trunk/verilator@935 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
9c968c590c
commit
5b620a8dc5
@ -1052,12 +1052,12 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||
// Spec: h d o b c l
|
||||
case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
|
||||
case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
|
||||
case 't':
|
||||
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
|
||||
case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
|
||||
case 'h':
|
||||
case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
|
||||
case 's': displayArg(nodep,&elistp,fmt,'s'); break;
|
||||
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
|
||||
case 'm': {
|
||||
emitDispState.pushFormat("%s");
|
||||
emitDispState.pushArg(NULL, "vlSymsp->name(");
|
||||
|
140
src/V3Number.cpp
140
src/V3Number.cpp
@ -303,7 +303,7 @@ V3Number& V3Number::setMask(int nbits) {
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// ACCESSORS
|
||||
// ACCESSORS - as strings
|
||||
|
||||
string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
||||
ostringstream out;
|
||||
@ -334,34 +334,113 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
||||
|
||||
if (binary) {
|
||||
out<<"b";
|
||||
int bit=width()-1;
|
||||
while (bit && bitIs0(bit)) bit--;
|
||||
for(; bit>=0; --bit) {
|
||||
if (bitIs0(bit)) out<<'0';
|
||||
else if (bitIs1(bit)) out<<'1';
|
||||
else if (bitIsZ(bit)) out<<'z';
|
||||
else out<<'x';
|
||||
}
|
||||
out<<displayed("%0b");
|
||||
}
|
||||
else {
|
||||
if (prefixed) out<<"h";
|
||||
// Always deal with 4 bits at once. Note no 4-state, it's above.
|
||||
int hexStart = width()-1;
|
||||
while (hexStart && bitIs0(hexStart)) hexStart--;
|
||||
while ((hexStart&3)!=3) hexStart++;
|
||||
for(int bit=hexStart; bit>0; ) {
|
||||
int v = 0;
|
||||
if (bitIs1(bit)) v |= 8; bit--;
|
||||
if (bitIs1(bit)) v |= 4; bit--;
|
||||
if (bitIs1(bit)) v |= 2; bit--;
|
||||
if (bitIs1(bit)) v |= 1; bit--;
|
||||
if (v>=10) out<<(char)('a'+v-10);
|
||||
else out<<(char)('0'+v);
|
||||
}
|
||||
out<<displayed("%0h");
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
string V3Number::displayed(const string& vformat) const {
|
||||
string::const_iterator pos = vformat.begin();
|
||||
UASSERT(pos != vformat.end() && pos[0]=='%', "display with non format argument "<<*this);
|
||||
pos++;
|
||||
string fmtsize;
|
||||
for (; pos != vformat.end() && isdigit(pos[0]); pos++) {
|
||||
fmtsize += pos[0];
|
||||
}
|
||||
string str;
|
||||
char code = tolower(pos[0]);
|
||||
switch (code) {
|
||||
case 'b': {
|
||||
int bit = width()-1;
|
||||
if (fmtsize != "0") while (bit && bitIs0(bit)) bit--;
|
||||
for (; bit>0; bit--) {
|
||||
if (bitIs0(bit)) str+='0';
|
||||
else if (bitIs1(bit)) str+='1';
|
||||
else if (bitIsZ(bit)) str+='z';
|
||||
else str+='x';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case 'o': {
|
||||
int bit = width()-1;
|
||||
if (fmtsize != "0") while (bit && bitIs0(bit)) bit--;
|
||||
while ((bit&2)!=2) bit++;
|
||||
for (; bit>0; bit -= 3) {
|
||||
int v = bitsValue(bit-2, 3);
|
||||
str += (char)('0'+v);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case 'h':
|
||||
case 'x': {
|
||||
int bit = width()-1;
|
||||
if (fmtsize != "0") while (bit && bitIs0(bit)) bit--;
|
||||
while ((bit&3)!=3) bit++;
|
||||
for (; bit>0; bit -= 4) {
|
||||
int v = bitsValue(bit-3, 4);
|
||||
if (v>=10) str += (char)('a'+v-10);
|
||||
else str += (char)('0'+v);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case 'c': {
|
||||
if (this->width()>8) m_fileline->v3error("$display of char format of > 8 bit value");
|
||||
int v = bitsValue(0, 8);
|
||||
str += (char)(v);
|
||||
return str;
|
||||
}
|
||||
case 's': {
|
||||
// Spec says always drop leading zeros
|
||||
int bit=this->width()-1;
|
||||
bool start=true;
|
||||
while ((bit&7)!=7) bit++;
|
||||
for (; bit>=0; bit -= 8) {
|
||||
int v = bitsValue(bit-7, 8);
|
||||
if (!start || v) {
|
||||
str = (char)((v==0)?' ':v);
|
||||
start = false; // Drop leading 0s
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case '~': // Signed decimal
|
||||
case 't':
|
||||
case 'd': { // Unsigned decimal
|
||||
bool issigned = (code == '~');
|
||||
if (fmtsize == "") {
|
||||
double mantissabits = this->width() - (issigned?1:0);
|
||||
double maxval = pow(2.0, mantissabits);
|
||||
double dchars = log10(maxval)+1.0;
|
||||
if (issigned) dchars++; // space for sign
|
||||
fmtsize = cvtToStr(int(dchars));
|
||||
}
|
||||
if (width() > 64) {
|
||||
m_fileline->v3error("Unsupported: $display of dec format of > 64 bit results (use hex format instead)");
|
||||
return "ERR";
|
||||
}
|
||||
if (issigned) {
|
||||
str = cvtToStr(asSQuad());
|
||||
} else {
|
||||
str = cvtToStr(asQuad());
|
||||
}
|
||||
int intfmtsize = atoi(fmtsize.c_str());
|
||||
while ((int)(str.length()) < intfmtsize) str = " "+str;
|
||||
return str;
|
||||
}
|
||||
default:
|
||||
m_fileline->v3fatalSrc("Unknown $display format code for number: %"<<pos[0]);
|
||||
return "ERR";
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// ACCESSORS - as numbers
|
||||
|
||||
uint32_t V3Number::asInt() const {
|
||||
UASSERT(!isFourState(),"asInt with 4-state "<<*this);
|
||||
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
||||
@ -369,18 +448,25 @@ uint32_t V3Number::asInt() const {
|
||||
}
|
||||
|
||||
vlsint32_t V3Number::asSInt() const {
|
||||
UASSERT(!isFourState(),"asSInt with 4-state "<<*this);
|
||||
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
||||
uint32_t signExtend = (-((m_value[0]) & (1UL<<(width()-1))));
|
||||
uint32_t extended = m_value[0] | signExtend;
|
||||
uint32_t v = asInt();
|
||||
uint32_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||
uint32_t extended = v | signExtend;
|
||||
return (vlsint32_t)(extended);
|
||||
}
|
||||
|
||||
vluint64_t V3Number::asQuad() const {
|
||||
UASSERT(!isFourState(),"asQuad with 4-state "<<*this);
|
||||
UASSERT(width()<65, "Value too wide "<<*this);
|
||||
if (width()<=32) return ((vluint64_t)m_value[0]);
|
||||
else return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
|
||||
if (width()<=32) return ((vluint64_t)(asInt()));
|
||||
return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
|
||||
}
|
||||
|
||||
vlsint64_t V3Number::asSQuad() const {
|
||||
if (width()<=32) return ((vlsint64_t)(asSInt()));
|
||||
vluint64_t v = asQuad();
|
||||
vluint64_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||
vluint64_t extended = v | signExtend;
|
||||
return (vlsint32_t)(extended);
|
||||
}
|
||||
|
||||
uint32_t V3Number::asHash() const {
|
||||
|
@ -94,6 +94,12 @@ private:
|
||||
bool bitIsZ (int bit) const {
|
||||
if (bit>=m_width) return bitIsZ(m_width-1);
|
||||
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||
uint32_t bitsValue(int lsb, int nbits) const {
|
||||
uint32_t v=0;
|
||||
for (int bitn=0; bitn<nbits; bitn++) { v |= (bitIs1(lsb+bitn)<<bitn); }
|
||||
return v;
|
||||
}
|
||||
|
||||
int words() const { return ((width()+31)/32); }
|
||||
|
||||
public:
|
||||
@ -112,6 +118,7 @@ public:
|
||||
|
||||
// ACCESSORS
|
||||
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
|
||||
string displayed(const string& format) const;
|
||||
int width() const { return m_width; }
|
||||
int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1)
|
||||
bool sized() const { return m_sized; }
|
||||
@ -129,6 +136,7 @@ public:
|
||||
uint32_t asInt() const;
|
||||
vlsint32_t asSInt() const;
|
||||
vluint64_t asQuad() const;
|
||||
vlsint64_t asSQuad() const;
|
||||
uint32_t asHash() const;
|
||||
uint32_t dataWord(int word) const;
|
||||
uint32_t countOnes() const;
|
||||
|
@ -24,6 +24,8 @@ execute (
|
||||
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
|
||||
|
||||
[0] %s=! %s= what! %s= hmmm!1234
|
||||
[0] hello, from a very long string. This gets substituted in.
|
||||
*-* All Finished *-*
|
||||
'),
|
||||
);
|
||||
|
||||
|
@ -33,6 +33,9 @@ module t;
|
||||
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
|
||||
str2[7:0], str2, str3);
|
||||
|
||||
$display("[%0t] %s%s%s", $time,
|
||||
"hel", "lo, fr", "om a very long string. This gets substituted in.");
|
||||
|
||||
// Str check
|
||||
`ifndef nc // NC-Verilog 5.3 chokes on this test
|
||||
if (str !== 32'h00_bf_11_0a) $stop;
|
||||
|
Loading…
Reference in New Issue
Block a user