-
Notifications
You must be signed in to change notification settings - Fork 544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verilator's vpiStringVal implementation masks byte values of 32 and 0 #5036
Comments
Can you please modify one of the Verilator test cases to show this, and also make sure it passes on 2 other simulators and make a pull request or patch with that? A fix would also be appreciated - should be straight forward once have the tests (to include/verilated_vpi.cpp)! |
I created tests for these edge cases in test_regress/t/t_vpi_var.cpp. These tests fail because vpiStringVal was intended to be used to store ASCII characters for human-readable strings. This explains why leading zeros are replaced by the space character. And why the test macro While the above functionality is ok for ASCII strings, it limits the ability to use vpiStringVal as a byte array data structure. This format is the most memory space efficient of all the options VPI provides: vpiBinStrVal stores 1 bit per byte, vpiHexStrVal stores 4 bits per byte, and vpiStringVal stores 8 bits per byte. For that reason, this use case should be supported. Adding this change would mean that any code that reads a vpiStringVal could not reliably use the null terminator character to determine the end of the string. From a quick keyword search of the codebase, it looks like this only happens in the tests directory. I can create a PR to add those changes in. |
Which other simulators dld you test? We want it passing on at least 2 others, as this change may break code assuming current behavior, so we need it to be right. Thanks. |
Would Vivado or Icarus suffice? |
Yes, but big-3 preferred. |
I created a repo to demonstrate this issue in Modelsim, Icarus, and Verilator. All three produced unique outputs when I tested the edge cases above. This may point to ambiguity in the IEEE standard, which allows for an implementation change that resolves these issues. |
Thanks for experimenting. Given that, is this then not a bug? |
That's correct. This is technically not a bug in that it observes IEEE 1800. However, there is evidently some wiggle room in how |
This matches at least one of the different other simulators? If so I'll take the pull request. |
I do not have access to the other big three simulators, so I can't confirm how VCS and Cadence behave. As for the simulators I tested in the experiment, neither ModelSim nor Icarus allow this usability. However, Verilator's output within the experiment would remain equally distinct (wrt to other simulators) with or without the change. |
Ok, please submit the pull to fix this. |
Looking at the change proposed, the putVal is now ignoring null characters. What is passed in is a C string, which must by rules of C be null terminated. So I don't think we can do this. Also it looks like most of the simulators that aren't completely broken agree with Verilator. Questa:
Xcelium:
Modelsim:
|
I think you'll need to rely on vpiRawTwoStateVal. That should also be portable. Does that work? |
vpiRawTwoStateVal may be a better alternative if it can also be used to read scalar logic values. But the get/put functions for array values are unimplemented in Verilator. Are there plans to add these in the future? |
I agree. Without providing the length along with the string it's impossible to know which null char indicates the termination of the string. vpi_put_value()'s handling for vpiVectorVal is nearly identical to how vpiStringVal is handled in this change, both are vulnerable to overrun. Unfortunately, the standard has no room to add a length argument or struct member. |
Not currently, VPI is basically added as people need a feature, but should be straightforward to make a pull to support them - perhaps something you'd consider? |
Yes, I can add those functions. |
Verilator's vpiStringVal implementation masks byte values of 32 and 0.
verilator version:
Verilator 5.022 2024-02-24 rev UNKNOWN.REV
OS: macOS Sonoma
Hello. I am writing handler functions to write and read signals from a Verilog Top module. My application uses
vpiStringVal
format. I noticed in the implementation forvl_get_value(...)
that byte values equal to 0 are returned as spaces (8'b32) to the caller.To test an edge case where this mechanic might fail, I wrote a simple Verilog Top module that assigns the values (32 << 8) and 32 to two constant outputs. 32 is represented as the ASCII space character.
And a test bench that calls the
vl_get_value
wrapper functionvpi_get_value()
for each output.The result is two identical char arrays. This behavior is problematic because it is not possible to decode the true value of this output when using
vpiStringVal
format.The expected result of printing const1 is
{32, 0, 0}
, and const2 is{0, 32, 0}
.The text was updated successfully, but these errors were encountered: