|
From: Martin W. <mai...@ma...> - 2015-06-22 18:07:47
|
Hello Fabrizio,
First, apologies that it has taken so long for someone to reply to this.
Fabrizio Ferrandi wrote:
> Playing with strings and $fopen I discovered a possible bug of
> format_vpiStringVal in vpi_signal.cc.
>
> This function seems to convert all 0s in spaces. This creates problems when
> a signal is used as first parameter of $fopen and when the signal size is
> greater than the filename to be open. I've changed the code leaving the
> space conversion for middle zeros but I've removed the trailing ones.
I not sure this is really a bug. Verilog itself doesn't use a string
terminator character. The relevant paragraph of the standard (1364-2005,
section 3.6.2) says
"When a variable is larger than required to hold a string value being
assigned, the value is right-justified, and the leftmost bits are padded with
zeros, as is done with nonstring values. If a string is larger than the
destination string variable, the string is right-justified, and the leftmost
characters are truncated."
So if you write
reg [8*8-1:0] str = "hello";
initial $display("%h", str);
the expected output is
00000068656c6c6f
i.e. all the zero padding is at the start of the string. The end of a string
is always the character stored in the least significant bits of the string
variable.
Unfortunately the standard is silent on how $display or vpi_get_value should
handle null ASCII characters when formatting as a string. Clearly it is
necessary to remove the leading nulls, but what happens after that seems to
vary according to which simulator you use. The three choices seem to be:
1) Remove leading nulls and convert the remaining ones to spaces.
2) Remove all nulls.
3) Remove leading nulls and terminate at the first remaining null.
Currently Icarus follows option 1. FWIW, Verilog-XL follows option 1 if you
use $display("%s", str), but option 2 if you use $display("%0s", str) or
vpi_get_value.
Martin
|