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
VCD generated by --trace has invalid $timescale directive #832
Comments
Original Redmine Comment I believe only your C code could change that. Assuming you are not using SystemC, you are presumably calling set_time_resolution with zero. If you're using SystemC, you're calling sc_set_time_resolution with zero. Don't do that :) |
Original Redmine Comment So I don't think that's the issue. I am using SystemC but...
I printed out the current time resolution as the first call in sc_main without any calls to sc_set_time_resolution like so:
That printed out:
I then inserted a call above that printf to sc_set_time_resolution like so:
The resulting printf reported the same resolution (i.e. "1 ps"). In both cases the $timescale directive was still set to 0ps in the generated VCD. Any more ideas? :) Also, I'm using SystemC v2.3.1 if that's helpful. |
Original Redmine Comment I just discovered something very very interesting... If I set the time resolution to (notice nanoseconds instead of picoseconds):
Then the $timescale directive is correctly set to 1ns. But if I change it back to:
Then the $timescale directive is set to 0ps. What the...??? |
Original Redmine Comment Add printf's to verilated_vcd_c.cpp where the timescale is printed to the file, and work backwards, there's very little code involved. |
Original Redmine Comment Cool. I put in the some print statements in doubleToTimescale. It appears sprintf is doing something weird. I have to go somewhere right now but just wanted to give you this update. I'll work on it more when i get back. Added this to doubleToTimescale in verilated_vcd_c.cpp:
Output is:
Strange... Cya! |
Original Redmine Comment Okay, so this is some kind of weird compiler optimization problem. I was trying to debug the doubleToTimescale() function and there wasn't anything programmatically wrong with it (as far as I could tell). But at one point I added a printf("here") debug string and the function correctly output "1ps" for the $timescale. So then I was like "Uh oh...". Haha. So I commented out the print statement and it started outputting "0ps" again. This led me to think of some compiler issue so I removed the "-O3" from my make command line and the untouched master repository version of the doubleToTimescale function is now outputting "1ps" as it should. If I put the "-O3" back in then it starts outputting "0ps" again. :( I can't understand why -O3 would make the doubleToTimescale() function return the wrong result. What the function is doing is extremely basic... The function that is specifically failing is sprintf. sprintf is inserting a numeral 0 instead of a numeral 1 into valuestr when -O3 is turned on. Very strange... So I've got:
|
Original Redmine Comment I'm trying to narrow down which specific optimization is causing the problem. -O1 also generates the incorrect result. |
Original Redmine Comment So I went through and enabled every individual optimization that I could find that is supposed to be enabled with -O1 and I couldn't reproduce the issue. I could only get the function to fail when I used the -O1 switch explicitly. So somehow I'm missing some optimization that gets turned on with -O1. I did determine that the timescale is not corrupted when building on linux even with -O3 turned on. But I don't think that's really useful information. It really just makes me wonder what other things are getting corrupted when building on windows... I'm using:
It would be useful to check for this timescale corruption on other windows machines running cygwin g++. I have one other windows machine that I can try on. But I expect it to be the same since it's running the same version of g++ on the same version of windows. |
Original Redmine Comment This seems to be a platform gcc issue, so no fix needed to Verilator itself. |
Original Redmine Comment Agreed. Very annoying though. One way that I've gotten it to work consistently is to insert a call to printf at some totally arbitrary point in the doubleToTimescale() method. I have attached a patch if someone wants it. Note that this patch doesn't require recompiling verilator itself; the verilated_vcd_c.cpp file is compiled in with your verilated design (assuming tracing was enabled). NOTE!! This is not the proper fix for this bug. There is some really weird optimization stuff going on here (see previous comments). It's likely a bug in GCC. There are a number of other ways to get it to "magically" start working properly but a simple printf is the least intrusive. |
Author Name: Jonathon Donaldson
Original Redmine Issue: 832 from https://www.veripool.org
Original Date: 2014-10-25
Hi,
I'm not sure if it's something I'm doing wrong (or not doing) but when verilator generates the VCD file for my design it specifies a 0ps $timescale directive.
The value 0 for the timescale is invalid according to the VCD file format. It must be one of 1, 10, or 100. This is causing issues when I use gtkwave's vcd2fst function. When it converts the vcd to FST format the timescale gets replaced by a default value of 1ns since 0ps is invalid. This causes all simulation measurements to be wrong in gtkwave when using the FST format.
Is there some way that I'm supposed to set this timescale directive myself? Or is this an actual bug in verilator?
Thanks!
The text was updated successfully, but these errors were encountered: