Skip to content
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

Closed
veripoolbot opened this issue Oct 25, 2014 · 10 comments
Closed

VCD generated by --trace has invalid $timescale directive #832

veripoolbot opened this issue Oct 25, 2014 · 10 comments
Labels
resolution: no fix needed Closed; no fix required (not a bug)

Comments

@veripoolbot
Copy link
Contributor


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.

$version Generated by VerilatedVcd $end
$date Fri Oct 24 13:16:31 2014
 $end
$timescale 0ps $end

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!

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-10-25T12:06:25Z


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 :)

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-25T16:56:32Z


So I don't think that's the issue. I am using SystemC but...

  • According to a number of websites I've found the default time resolution for SystemC is 1ps even if you don't set it.
  • I currently do not ever call sc_set_time_resolution in my SystemC testbench.

I printed out the current time resolution as the first call in sc_main without any calls to sc_set_time_resolution like so:

printf("Time Res = %s\n", sc_get_time_resolution().to_string().c_str());

That printed out:

Time Res = 1 ps

I then inserted a call above that printf to sc_set_time_resolution like so:

sc_set_time_resolution(1, SC_PS);

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.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-25T17:02:12Z


I just discovered something very very interesting...

If I set the time resolution to (notice nanoseconds instead of picoseconds):

sc_set_time_resolution(1, SC_NS);

Then the $timescale directive is correctly set to 1ns. But if I change it back to:

sc_set_time_resolution(1, SC_PS);

Then the $timescale directive is set to 0ps.

What the...???

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-10-25T17:18:29Z


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.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-25T20:15:01Z


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:

     cout << "value = " << value << endl;
     cout << "suffixp = " << suffixp << endl;
     cout << "valuestr = " << valuestr << endl;

Output is:

value = 1
suffixp = ps
valuestr = 0ps

Strange... Cya!

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-26T03:26:50Z


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:

make OPT="-O0" -j -f Vmydes_tb.mk Vmydes_tb # I WORK!

make OPT="-O3" -j -f Vmydes_tb.mk Vmydes_tb # I DON'T WORK!! :(

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-26T04:22:44Z


I'm trying to narrow down which specific optimization is causing the problem. -O1 also generates the incorrect result.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-10-30T18:07:04Z


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:

  • Cygwin g++ v4.8.3 on Windows 7 64-bit
  • g++ v4.6.3 on Ubuntu 64-bit

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.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-11-09T23:41:02Z


This seems to be a platform gcc issue, so no fix needed to Verilator itself.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Jonathon Donaldson
Original Date: 2014-11-10T09:20:42Z


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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution: no fix needed Closed; no fix required (not a bug)
Projects
None yet
Development

No branches or pull requests

1 participant