forked from github/verilator
Support left justified . Closes #2101.
This commit is contained in:
parent
e9a309ea8d
commit
4443ab34fd
8
Changes
8
Changes
@ -5,11 +5,13 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||||||
|
|
||||||
* Verilator 4.027 devel
|
* 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]
|
**** Add parameter values in XML. #2110. [Pieter Kapsenberg]
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ Mike Popoloski
|
|||||||
Peter Monsson
|
Peter Monsson
|
||||||
Patrick Stewart
|
Patrick Stewart
|
||||||
Philipp Wagner
|
Philipp Wagner
|
||||||
|
Pieter Kapsenberg
|
||||||
Richard Myers
|
Richard Myers
|
||||||
Sebastien Van Cauwenberghe
|
Sebastien Van Cauwenberghe
|
||||||
Stefan Wallentowitz
|
Stefan Wallentowitz
|
||||||
|
@ -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
|
const char* pctp = NULL; // Most recent %##.##g format
|
||||||
bool inPct = false;
|
bool inPct = false;
|
||||||
bool widthSet = false;
|
bool widthSet = false;
|
||||||
|
bool left = false;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
for (const char* pos = formatp; *pos; ++pos) {
|
for (const char* pos = formatp; *pos; ++pos) {
|
||||||
if (!inPct && pos[0]=='%') {
|
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;
|
widthSet = true;
|
||||||
width = width*10 + (fmt - '0');
|
width = width*10 + (fmt - '0');
|
||||||
break;
|
break;
|
||||||
|
case '-':
|
||||||
|
left = true;
|
||||||
|
inPct = true; // Get more digits
|
||||||
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
inPct = true; // Get more digits
|
inPct = true; // Get more digits
|
||||||
break;
|
break;
|
||||||
@ -662,8 +667,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
case '@': { // Verilog/C++ string
|
case '@': { // Verilog/C++ string
|
||||||
va_arg(ap, int); // # bits is ignored
|
va_arg(ap, int); // # bits is ignored
|
||||||
const std::string* cstrp = va_arg(ap, const std::string*);
|
const std::string* cstrp = va_arg(ap, const std::string*);
|
||||||
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
|
std::string padding;
|
||||||
output += *cstrp;
|
if (width > cstrp->size()) padding.append(width - cstrp->size(), ' ');
|
||||||
|
output += left ? (*cstrp + padding) : (padding + *cstrp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'e':
|
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;
|
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
|
||||||
field += (charval==0)?' ':charval;
|
field += (charval==0)?' ':charval;
|
||||||
}
|
}
|
||||||
if (width > field.size()) output += std::string(width - field.size(), ' ');
|
std::string padding;
|
||||||
output += field;
|
if (width > field.size()) padding.append(width - field.size(), ' ');
|
||||||
|
output += left ? (field + padding) : (padding + field);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd': { // Signed decimal
|
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();
|
digits = append.length();
|
||||||
}
|
}
|
||||||
int needmore = width-digits;
|
int needmore = width-digits;
|
||||||
|
std::string padding;
|
||||||
if (needmore>0) {
|
if (needmore>0) {
|
||||||
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
||||||
output.append(needmore, '0'); // Pre-pad zero
|
padding.append(needmore, '0'); // Pre-pad zero
|
||||||
} else {
|
} else {
|
||||||
output.append(needmore, ' '); // Pre-pad spaces
|
padding.append(needmore, ' '); // Pre-pad spaces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output += append;
|
output += left ? (append + padding) : (padding + append);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '#': { // Unsigned decimal
|
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();
|
digits = append.length();
|
||||||
}
|
}
|
||||||
int needmore = width-digits;
|
int needmore = width-digits;
|
||||||
|
std::string padding;
|
||||||
if (needmore>0) {
|
if (needmore>0) {
|
||||||
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
||||||
output.append(needmore, '0'); // Pre-pad zero
|
padding.append(needmore, '0'); // Pre-pad zero
|
||||||
} else {
|
} else {
|
||||||
output.append(needmore, ' '); // Pre-pad spaces
|
padding.append(needmore, ' '); // Pre-pad spaces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output += append;
|
output += left ? (append + padding) : (padding + append);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 't': { // Time
|
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");
|
VL_FATAL_MT(__FILE__, __LINE__, "", "Unsupported VL_TIME_MULTIPLIER");
|
||||||
}
|
}
|
||||||
int needmore = width-digits;
|
int needmore = width-digits;
|
||||||
if (needmore>0) output.append(needmore, ' '); // Pre-pad spaces
|
std::string padding;
|
||||||
output += tmp;
|
if (needmore>0) padding.append(needmore, ' '); // Pad with spaces
|
||||||
|
output += left ? (tmp + padding) : (padding + tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'b':
|
case 'b':
|
||||||
|
@ -2069,7 +2069,7 @@ private:
|
|||||||
if (!inPct && ch=='%') {
|
if (!inPct && ch=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
fmt = ch;
|
fmt = ch;
|
||||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||||
fmt += ch;
|
fmt += ch;
|
||||||
} else if (inPct) {
|
} else if (inPct) {
|
||||||
inPct = false;
|
inPct = false;
|
||||||
|
@ -1797,7 +1797,8 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||||||
switch (tolower(pos[0])) {
|
switch (tolower(pos[0])) {
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
case '.':
|
case '.': // FALLTHRU
|
||||||
|
case '-':
|
||||||
// Digits, like %5d, etc.
|
// Digits, like %5d, etc.
|
||||||
vfmt += pos[0];
|
vfmt += pos[0];
|
||||||
inPct = true; // Get more digits
|
inPct = true; // Get more digits
|
||||||
|
@ -270,7 +270,7 @@ private:
|
|||||||
if (!inPct && ch=='%') {
|
if (!inPct && ch=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
fmt = ch;
|
fmt = ch;
|
||||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||||
fmt += ch;
|
fmt += ch;
|
||||||
} else if (inPct) {
|
} else if (inPct) {
|
||||||
inPct = false;
|
inPct = false;
|
||||||
|
@ -497,10 +497,10 @@ bool V3Number::displayedFmtLegal(char format) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Number::displayPad(size_t fmtsize, char pad, const string& in) {
|
string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& in) {
|
||||||
string prefix;
|
string padding;
|
||||||
if (in.length() < fmtsize) prefix = string(fmtsize - in.length(), pad);
|
if (in.length() < fmtsize) padding = string(fmtsize - in.length(), pad);
|
||||||
return prefix + in;
|
return left ? (in + padding) : (padding + in);
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Number::displayed(AstNode* nodep, const string& vformat) const {
|
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]=='%',
|
UASSERT(pos != vformat.end() && pos[0]=='%',
|
||||||
"$display-like function with non format argument "<<*this);
|
"$display-like function with non format argument "<<*this);
|
||||||
++pos;
|
++pos;
|
||||||
|
bool left = false;
|
||||||
|
if (pos[0] == '-') {
|
||||||
|
left = true;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
string fmtsize;
|
string fmtsize;
|
||||||
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) {
|
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) {
|
||||||
fmtsize += pos[0];
|
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()));
|
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||||
str = displayPad(fmtsizen, ' ', str);
|
str = displayPad(fmtsizen, ' ', left, str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
case '~': // Signed decimal
|
case '~': // Signed decimal
|
||||||
@ -604,7 +609,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||||||
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
|
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
|
||||||
// fmtsize might have changed since we parsed the %fmtsize
|
// fmtsize might have changed since we parsed the %fmtsize
|
||||||
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
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;
|
return str;
|
||||||
}
|
}
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -651,7 +656,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||||||
}
|
}
|
||||||
case '@': { // Packed string
|
case '@': { // Packed string
|
||||||
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||||
str = displayPad(fmtsizen, ' ', toString());
|
str = displayPad(fmtsizen, ' ', left, toString());
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -175,7 +175,7 @@ private:
|
|||||||
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
|
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
|
||||||
}
|
}
|
||||||
void setNames(AstNode* nodep);
|
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(FileLine* fl, const string& vformat) const;
|
||||||
string displayed(const string& vformat) const {
|
string displayed(const string& vformat) const {
|
||||||
return displayed(m_fileline, vformat);
|
return displayed(m_fileline, vformat);
|
||||||
|
@ -2706,7 +2706,7 @@ private:
|
|||||||
if (!inPct && ch=='%') {
|
if (!inPct && ch=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
fmt = ch;
|
fmt = ch;
|
||||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||||
fmt += ch;
|
fmt += ch;
|
||||||
} else if (tolower(inPct)) {
|
} else if (tolower(inPct)) {
|
||||||
inPct = false;
|
inPct = false;
|
||||||
|
@ -51,5 +51,19 @@ extra argument: 0000000000000000
|
|||||||
[0] Embedded <#013> return
|
[0] Embedded <#013> return
|
||||||
[0] Embedded
|
[0] Embedded
|
||||||
multiline
|
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
|
log10(2) = 2
|
||||||
*-* All Finished *-*
|
*-* All Finished *-*
|
||||||
|
@ -13,7 +13,10 @@ module t;
|
|||||||
reg [31:0] str; initial str = "\000\277\021\n";
|
reg [31:0] str; initial str = "\000\277\021\n";
|
||||||
reg [47:0] str2; initial str2 = "\000what!";
|
reg [47:0] str2; initial str2 = "\000what!";
|
||||||
reg [79:0] str3; initial str3 = "\000hmmm!1234";
|
reg [79:0] str3; initial str3 = "\000hmmm!1234";
|
||||||
|
int n; initial n = 23;
|
||||||
|
reg [7:0] m; initial m = 24;
|
||||||
string svs = "sv-str";
|
string svs = "sv-str";
|
||||||
|
reg [31:0] regstr = "meep";
|
||||||
|
|
||||||
sub sub ();
|
sub sub ();
|
||||||
sub2 sub2 ();
|
sub2 sub2 ();
|
||||||
@ -144,6 +147,22 @@ multiline", $time);
|
|||||||
if (str !== 32'h00_bf_11_0a) $stop;
|
if (str !== 32'h00_bf_11_0a) $stop;
|
||||||
`endif
|
`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
|
// $itord conversion bug, note a %d instead of proper float
|
||||||
$display("log10(2) = %d", $log10(100));
|
$display("log10(2) = %d", $log10(100));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user