Support left justified . Closes #2101.

This commit is contained in:
Pieter Kapsenberg 2020-01-15 07:32:45 -05:00 committed by Wilson Snyder
parent e9a309ea8d
commit 4443ab34fd
11 changed files with 79 additions and 27 deletions

View File

@ -5,11 +5,13 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.027 devel
** Support attributes (public, isolate_assignments, etc.) in configuration files.
** Support attributes (public, isolate_assignments, etc.) in configuration files.
** Add -match to lint_off to waive warnings. [Philipp Wagner]
** Add -match to lint_off to waive warnings. [Philipp Wagner]
*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman]
*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman]
**** Support left justified $display. Closes #2101. [Pieter Kapsenberg]
**** Add parameter values in XML. #2110. [Pieter Kapsenberg]

View File

@ -27,6 +27,7 @@ Mike Popoloski
Peter Monsson
Patrick Stewart
Philipp Wagner
Pieter Kapsenberg
Richard Myers
Sebastien Van Cauwenberghe
Stefan Wallentowitz

View File

@ -618,6 +618,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
const char* pctp = NULL; // Most recent %##.##g format
bool inPct = false;
bool widthSet = false;
bool left = false;
int width = 0;
for (const char* pos = formatp; *pos; ++pos) {
if (!inPct && pos[0]=='%') {
@ -643,6 +644,10 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
widthSet = true;
width = width*10 + (fmt - '0');
break;
case '-':
left = true;
inPct = true; // Get more digits
break;
case '.':
inPct = true; // Get more digits
break;
@ -662,8 +667,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
case '@': { // Verilog/C++ string
va_arg(ap, int); // # bits is ignored
const std::string* cstrp = va_arg(ap, const std::string*);
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
output += *cstrp;
std::string padding;
if (width > cstrp->size()) padding.append(width - cstrp->size(), ' ');
output += left ? (*cstrp + padding) : (padding + *cstrp);
break;
}
case 'e':
@ -721,8 +727,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
field += (charval==0)?' ':charval;
}
if (width > field.size()) output += std::string(width - field.size(), ' ');
output += field;
std::string padding;
if (width > field.size()) padding.append(width - field.size(), ' ');
output += left ? (field + padding) : (padding + field);
break;
}
case 'd': { // Signed decimal
@ -743,14 +750,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
digits = append.length();
}
int needmore = width-digits;
std::string padding;
if (needmore>0) {
if (pctp && pctp[0] && pctp[1]=='0') { // %0
output.append(needmore, '0'); // Pre-pad zero
padding.append(needmore, '0'); // Pre-pad zero
} else {
output.append(needmore, ' '); // Pre-pad spaces
padding.append(needmore, ' '); // Pre-pad spaces
}
}
output += append;
output += left ? (append + padding) : (padding + append);
break;
}
case '#': { // Unsigned decimal
@ -764,14 +772,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
digits = append.length();
}
int needmore = width-digits;
std::string padding;
if (needmore>0) {
if (pctp && pctp[0] && pctp[1]=='0') { // %0
output.append(needmore, '0'); // Pre-pad zero
padding.append(needmore, '0'); // Pre-pad zero
} else {
output.append(needmore, ' '); // Pre-pad spaces
padding.append(needmore, ' '); // Pre-pad spaces
}
}
output += append;
output += left ? (append + padding) : (padding + append);
break;
}
case 't': { // Time
@ -786,8 +795,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
VL_FATAL_MT(__FILE__, __LINE__, "", "Unsupported VL_TIME_MULTIPLIER");
}
int needmore = width-digits;
if (needmore>0) output.append(needmore, ' '); // Pre-pad spaces
output += tmp;
std::string padding;
if (needmore>0) padding.append(needmore, ' '); // Pad with spaces
output += left ? (tmp + padding) : (padding + tmp);
break;
}
case 'b':

View File

@ -2069,7 +2069,7 @@ private:
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && (isdigit(ch) || ch=='.')) {
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
fmt += ch;
} else if (inPct) {
inPct = false;

View File

@ -1797,7 +1797,8 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
switch (tolower(pos[0])) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
case '.': // FALLTHRU
case '-':
// Digits, like %5d, etc.
vfmt += pos[0];
inPct = true; // Get more digits

View File

@ -270,7 +270,7 @@ private:
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && (isdigit(ch) || ch=='.')) {
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
fmt += ch;
} else if (inPct) {
inPct = false;

View File

@ -497,10 +497,10 @@ bool V3Number::displayedFmtLegal(char format) {
}
}
string V3Number::displayPad(size_t fmtsize, char pad, const string& in) {
string prefix;
if (in.length() < fmtsize) prefix = string(fmtsize - in.length(), pad);
return prefix + in;
string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& in) {
string padding;
if (in.length() < fmtsize) padding = string(fmtsize - in.length(), pad);
return left ? (in + padding) : (padding + in);
}
string V3Number::displayed(AstNode* nodep, const string& vformat) const {
@ -512,6 +512,11 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
UASSERT(pos != vformat.end() && pos[0]=='%',
"$display-like function with non format argument "<<*this);
++pos;
bool left = false;
if (pos[0] == '-') {
left = true;
++pos;
}
string fmtsize;
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) {
fmtsize += pos[0];
@ -574,7 +579,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
}
}
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, ' ', str);
str = displayPad(fmtsizen, ' ', left, str);
return str;
}
case '~': // Signed decimal
@ -604,7 +609,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
// fmtsize might have changed since we parsed the %fmtsize
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), str);
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), left, str);
return str;
}
case 'e':
@ -651,7 +656,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
}
case '@': { // Packed string
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
str = displayPad(fmtsizen, ' ', toString());
str = displayPad(fmtsizen, ' ', left, toString());
return str;
}
default:

View File

@ -175,7 +175,7 @@ private:
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
}
void setNames(AstNode* nodep);
static string displayPad(size_t fmtsize, char pad, const string& in);
static string displayPad(size_t fmtsize, char pad, bool left, const string& in);
string displayed(FileLine* fl, const string& vformat) const;
string displayed(const string& vformat) const {
return displayed(m_fileline, vformat);

View File

@ -2706,7 +2706,7 @@ private:
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && (isdigit(ch) || ch=='.')) {
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
fmt += ch;
} else if (tolower(inPct)) {
inPct = false;

View File

@ -51,5 +51,19 @@ extra argument: 0000000000000000
[0] Embedded <#013> return
[0] Embedded
multiline
'23 23 23'
'23 23 23 '
'23 23 23'
'23 23 23 '
' 24'
'24 '
' 0'
'0 '
' sv-str'
'sv-str '
' meep'
'meep '
' beep'
'beep '
log10(2) = 2
*-* All Finished *-*

View File

@ -13,7 +13,10 @@ module t;
reg [31:0] str; initial str = "\000\277\021\n";
reg [47:0] str2; initial str2 = "\000what!";
reg [79:0] str3; initial str3 = "\000hmmm!1234";
int n; initial n = 23;
reg [7:0] m; initial m = 24;
string svs = "sv-str";
reg [31:0] regstr = "meep";
sub sub ();
sub2 sub2 ();
@ -144,6 +147,22 @@ multiline", $time);
if (str !== 32'h00_bf_11_0a) $stop;
`endif
// Padding
$write("'%0d %2d %8d'\n", 23, 23, 23);
$write("'%-0d %-2d %-8d'\n", 23, 23, 23);
$write("'%0d %2d %8d'\n", n, n, n);
$write("'%-0d %-2d %-8d'\n", n, n, n);
$write("'%8d'\n", m);
$write("'%-8d'\n", m);
$write("'%8t'\n", $time);
$write("'%-8t'\n", $time);
$write("'%8s'\n", svs);
$write("'%-8s'\n", svs);
$write("'%8s'\n", regstr);
$write("'%-8s'\n", regstr);
$write("'%8s'\n", "beep");
$write("'%-8s'\n", "beep");
// $itord conversion bug, note a %d instead of proper float
$display("log10(2) = %d", $log10(100));