mirror of
https://github.com/verilator/verilator.git
synced 2026-09-04 08:33:38 +02:00
Fix $display of fixed-width numbers (#3565).
This commit is contained in:
+78
-30
@@ -905,15 +905,22 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
digits = append.length();
|
||||
}
|
||||
const int needmore = width - digits;
|
||||
std::string padding;
|
||||
if (needmore > 0) {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
output += append + padding;
|
||||
} else {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
}
|
||||
output += padding + append;
|
||||
}
|
||||
} else {
|
||||
output += append;
|
||||
}
|
||||
output += left ? (append + padding) : (padding + append);
|
||||
break;
|
||||
}
|
||||
case '#': { // Unsigned decimal
|
||||
@@ -927,15 +934,22 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
digits = append.length();
|
||||
}
|
||||
const int needmore = width - digits;
|
||||
std::string padding;
|
||||
if (needmore > 0) {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
output += append + padding;
|
||||
} else {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
}
|
||||
output += padding + append;
|
||||
}
|
||||
} else {
|
||||
output += append;
|
||||
}
|
||||
output += left ? (append + padding) : (padding + append);
|
||||
break;
|
||||
}
|
||||
case 't': { // Time
|
||||
@@ -944,21 +958,62 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
output += _vl_vsformat_time(t_tmp, ld, timeunit, left, width);
|
||||
break;
|
||||
}
|
||||
case 'b':
|
||||
for (; lsb >= 0; --lsb) output += (VL_BITRSHIFT_W(lwp, lsb) & 1) + '0';
|
||||
break;
|
||||
case 'o':
|
||||
for (; lsb >= 0; --lsb) {
|
||||
lsb = (lsb / 3) * 3; // Next digit
|
||||
// Octal numbers may span more than one wide word,
|
||||
// so we need to grab each bit separately and check for overrun
|
||||
// Octal is rare, so we'll do it a slow simple way
|
||||
output += static_cast<char>(
|
||||
'0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 0)) ? 1 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 1)) ? 2 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0));
|
||||
case 'b': // FALLTHRU
|
||||
case 'o': // FALLTHRU
|
||||
case 'x': {
|
||||
if (widthSet || left) {
|
||||
lsb = VL_MOSTSETBITP1_W(VL_WORDS_I(lbits), lwp);
|
||||
lsb = (lsb < 1) ? 0 : (lsb - 1);
|
||||
}
|
||||
|
||||
std::string append;
|
||||
int digits;
|
||||
switch (fmt) {
|
||||
case 'b': {
|
||||
digits = lsb + 1;
|
||||
for (; lsb >= 0; --lsb) append += (VL_BITRSHIFT_W(lwp, lsb) & 1) + '0';
|
||||
break;
|
||||
}
|
||||
case 'o': {
|
||||
digits = (lsb + 1 + 2) / 3;
|
||||
for (; lsb >= 0; --lsb) {
|
||||
lsb = (lsb / 3) * 3; // Next digit
|
||||
// Octal numbers may span more than one wide word,
|
||||
// so we need to grab each bit separately and check for overrun
|
||||
// Octal is rare, so we'll do it a slow simple way
|
||||
append += static_cast<char>(
|
||||
'0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 0)) ? 1 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 1)) ? 2 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: { // 'x'
|
||||
digits = (lsb + 1 + 3) / 4;
|
||||
for (; lsb >= 0; --lsb) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
const IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xf;
|
||||
append += "0123456789abcdef"[charval];
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
|
||||
const int needmore = width - digits;
|
||||
if (needmore > 0) {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
output += append + padding;
|
||||
} else {
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
output += padding + append;
|
||||
}
|
||||
} else {
|
||||
output += append;
|
||||
}
|
||||
break;
|
||||
} // b / o / x
|
||||
case 'u':
|
||||
case 'z': { // Packed 4-state
|
||||
const bool is_4_state = (fmt == 'z');
|
||||
@@ -984,13 +1039,6 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
for (; lsb >= 0; --lsb) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
const IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xf;
|
||||
output += "0123456789abcdef"[charval];
|
||||
}
|
||||
break;
|
||||
default: { // LCOV_EXCL_START
|
||||
const std::string msg = std::string{"Unknown _vl_vsformat code: "} + pos[0];
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
|
||||
Reference in New Issue
Block a user