From 5b620a8dc5bf514185f4d7b248d968f1092872d4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 14 Jun 2007 14:24:21 +0000 Subject: [PATCH] Add V3Number display function, unused as yet git-svn-id: file://localhost/svn/verilator/trunk/verilator@935 77ca24e4-aefa-0310-84f0-b9a241c72d87 --- src/V3EmitC.cpp | 2 +- src/V3Number.cpp | 140 +++++++++++++++++++++++++++++------- src/V3Number.h | 8 +++ test_regress/t/t_display.pl | 2 + test_regress/t/t_display.v | 3 + 5 files changed, 127 insertions(+), 28 deletions(-) diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index b6c7ca06f..9b5396550 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -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("); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 1e9624fda..1cff44408 100644 --- a/src/V3Number.cpp +++ b/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<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<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: %"<=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