Disclaimer: I answered my own question, which is explicitly encouraged. I noticed a colleague at work writing code that left the simulation log file difficult to read. I searched the site for a solution, but found none.
I want to $display
strings in a column like in a fixed-width table.
However, I don't know what the maximum column width of my strings is
ahead of time.
Let's say I have an array of SystemVerilog strings (names
).
When I $display
them, I guess at a width for the column (10),
but my guess is too small:
module tb;
string names [5];
initial begin
names = '{
"ALU" ,
"COMPARATOR_3" ,
"MEMORY" ,
"FLOP" ,
"ram_macro_with_a_long_name"
};
// Display all elements of the array
foreach (names[i]) begin
$display("| %10s |", names[i]);
end
end
endmodule
This is the output:
| ALU |
| COMPARATOR_3 |
| MEMORY |
| FLOP |
| ram_macro_with_a_long_name |
This is the output I want:
| ALU |
| COMPARATOR |
| MEMORY |
| FLOP |
| ram_macro_with_a_long_name |
I could guess a really big number (like 100), but it might be a lot bigger than I need.
How can I automatically scale the width of the $display
?
Loop through the array to calculate the maximum string length
using the len
array method. Refer to IEEE Std 1800-2017,
section 6.16 String data type.
Then create the format string using $sformatf
.
module tb;
string names [5];
int maxlen = 0;
string fmt;
initial begin
names = '{
"ALU" ,
"COMPARATOR" ,
"MEMORY" ,
"FLOP" ,
"ram_macro_with_a_long_name"
};
// First, lets calculate the maximum string length
foreach (names[i]) begin
if (names[i].len() > maxlen) maxlen = names[i].len();
end
// Create the format which will be used by $display
// %% ... double "%" is needed to create a literal "%"
// %0d ... this formats the maxlen number
// s ... string format
// | ... this is just the character I chose for the start/end of the field
fmt = $sformatf("| %%%0ds |", maxlen);
// Display all elements of the array
foreach (names[i]) begin
$display($sformatf(fmt, names[i]));
end
end
endmodule
This is the output:
| ALU |
| COMPARATOR |
| MEMORY |
| FLOP |
| ram_macro_with_a_long_name |
Here is a runnable example on edaplayground.
The output above is right-justified. To get left-justified output, use:
fmt = $sformatf("| %%-%0ds |", maxlen);
Output:
| ALU |
| COMPARATOR |
| MEMORY |
| FLOP |
| ram_macro_with_a_long_name |