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
DPI-C structures seem to come out backwards! #1191
Comments
Original Redmine Comment Oh yeah... Using built-in specs. |
Original Redmine Comment Sounds like you might be looking at this yourself, but either way can you please convert this to a test_regress format standalone test? That will be needed either for me to debug, or to take a patch to know it's good. Thanks. |
Original Redmine Comment I created a regression test (see patch) which reflects the issue. One this this regression does not show, however, is that all of the integers in the struct are properly formed; so the solution is not as simple as rolling over the bits. Furthermore, this issue may behave completely differently on big-endian machines... in fact, I suspect the issue does not exist on them. I do not have one at hand that I can use to test. |
Original Redmine Comment I believe the correct behavior is what you indicated with your "this code works" section, which is what Verilator currently does. VCS agrees with Verilator. IEEE says the first structure packed entity is at the highest indicies, so I'm not seeing how your alternative could be right. What simulator disagrees? |
Original Redmine Comment This leaves me deeply concerned with how VCS works... that may be a bug. Modelsim certainly disagrees with Verilator. Note that in the "this code works" the operation is reversed with respect to the Verilog. In the test, I use the exact-same structure definition in Verilog as I do in C, so the general assumption should be that what I put in through Verilog is the same thing I get in C. When I submit two elements in a structure, I use the non-commutative property of subtraction to verify the positioning of the two elements in the structure. I provided code in Verilog that subtracts the two input elements, a - b, and in C, a - b, then compares the result. The "this code works" comment shows that swapping the two elements (b - a) creates the correct answer, which indicates the elements of the structure are swapped. To put it in other terms, when I submit a structure to a DPI-C function, the elements within the structure are in reverse order when they get into C. So if I submit a structure in Verilog:
With the values:
Then in C, I define the exact same struct (omitted... it's identical to the Verilog definition) The following statements are true:
Clearly reversed. So, I decided since Google was not being nice to me and providing the appropriate results, I'd create a little C test program:
Which gave me the following results:
It appears that C's structure has the indices in order, first is lowest in memory, and then up from there. I am looking at IEEE 1800-2012, section 7.2, and I don't see any direct mention of structure order for either packed or unpacked structures. Is it mentioned elsewhere? |
Original Redmine Comment Did the exact test you sent pass on modelsim, that is does "test_regress/t/t_dpi_import.pl --ms" pass? I suspect you're comparing a non-packed struct on modelsim with a packed struct on VCS/Verilator. |
Original Redmine Comment There seems to be 2 issues here: Section 7.2.1 indicates: This means that within SystemVerilog, your packed structure will have it's first elements in the high bits, and the last element in the lowest bits. Think of it like the '{...}' concatenation operator in Verilog. As to how SystemVerilog treats structures passed as arguments to DPI functions, are they copied as-is or are structure members mapped (because obviously C orders structure members the opposite way) ? Looking at chapter 35 (DPI) I see the following: Section 35.2.2.1 says this: Later below, on 35.5.6 it says: I'm not sure how to interpret that, but taking the SystemVerilog struct, casting it into a bit vector and then passing this as an array pointer to C, seems to be the most logical thing to do. Recently I wrote a small script (~300 lines of perl code) at works that takes an external .h file containing simple byte/short/int/enum types in various struct/union combinations, and converts it into the equivalent SystemVerilog header file. This way a CPU can DMA a data structure and the SystemVerilog code parsing it in hardware can share a SystemVerilog struct with the equivalent C struct automatically. |
Original Redmine Comment You didn't indicate if it passed in modelsim. Anyhow I also tried Cadence and it too agrees with Verilator, and besides as you found it's supposedly implementation dependent (though I believe that's silly in this case). Either way I believe Verilator is compliant. I commited your test with the Verilator passing result. |
Original Redmine Comment Is the functionality I'm looking for in unpacked structures? I was having a sincere problem getting the example working in Modelsim. I sent it to one of my designers, he said he got it working however, he never returned code to me nor provided me with results... he's busy in other things, as am I. |
Original Redmine Comment
Yes, though no idea how widely supported that is. |
Author Name: Rob Stoddard
Original Redmine Issue: 1191 from https://www.veripool.org
Original Assignee: Wilson Snyder (@wsnyder)
In my module I have:
And in my C code I have:
Which is using the structure, in C:
Basically identical.
But when run, I get this output:
Which is backwards from what I'd expect.
The text was updated successfully, but these errors were encountered: