How to know/read current timescale?

U

unfrostedpoptart

Guest
Hi all.

This is one of those things I've never thought about after many years of using Verilog and now I need it can't can't figure out how to do it. I just want a way for my code to know the current timescale so it can interpret $time correctly. The only thing close I've found is $printtimescale, but that's just a print statement and I need to capture it's output into variables. I've googled and searched the LRM and can't find anything.

Thanks for any help!

David
 
On 8/26/2013 10:24 AM, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years
of using Verilog and now I need it can't can't figure out how to do
it. I just want a way for my code to know the current timescale so
it can interpret $time correctly. The only thing close I've found
is $printtimescale, but that's just a print statement and I need to
capture it's output into variables. I've googled and searched the
LRM and can't find anything.

Thanks for any help!

David

I do not know of a standard way using just Verilog/SystemVerilog.
Verilog-A provides $simparam(), but I am guessing that is not available.
I use custom VPI routines to get this information in Verilog-D when I
need it. I can provide more information if needed.

Depending on what you are doing the optional system function $scale()
may be of interest. Without knowing more details about your statement
"... interpret $time correctly." I can only guess what your requirements
are.

If the time unit and time precision do not match you may also want to
use a real variable and $realtime() instead of $time() and a time
variable, but this assumes the simulation time is short enough (very
likely) that the real time value does not suffer from precision
problems. Again there is much subtlety here that depends on what is
being done.

Cary
 
On Monday, August 26, 2013 10:24:31 AM UTC-7, unfrostedpoptart wrote:
Hi all.



This is one of those things I've never thought about after many years of using Verilog and now I need it can't can't figure out how to do it. I just want a way for my code to know the current timescale so it can interpret $time correctly. The only thing close I've found is $printtimescale, but that's just a print statement and I need to capture it's output into variables. I've googled and searched the LRM and can't find anything.



Thanks for any help!



David

In SystemVerilog, you can write (timevar = $time/1ns) or better (timevar $realtime/1ns) and you will get your time back in ns. If you need to use timvar as part of a delay expression, make sure you scale it back, i.e. #(timevar*1ns).

Dave Rich
http://go.mentor.com/drich
 
On 8/26/2013 3:46 PM, Dave R wrote:
On Monday, August 26, 2013 10:24:31 AM UTC-7, unfrostedpoptart
wrote:
Hi all.



This is one of those things I've never thought about after many
years of using Verilog and now I need it can't can't figure out how
to do it. I just want a way for my code to know the current
timescale so it can interpret $time correctly. The only thing
close I've found is $printtimescale, but that's just a print
statement and I need to capture it's output into variables. I've
googled and searched the LRM and can't find anything.


In SystemVerilog, you can write (timevar = $time/1ns) or better
(timevar $realtime/1ns) and you will get your time back in ns. If you
need to use timvar as part of a delay expression, make sure you scale
it back, i.e. #(timevar*1ns).

As written does this actually work for modules with a time unit greater
than 1ns? I understand that the 1ns gets scaled to the local time unit
and truncated using the local time precision, but I would assume that
the 1ns time literal in a 10ns/10ns context would round to zero not the
0.1 you need to make this work universally. I think for this scheme to
work you need to use "1s" or a scaling time literal that has a value
that is as big as the largest time precision, preferably use $realtime
to get the best local time value and a real variable to hold the result.

Of course using "1s" breaks if you have a module with a 10s or 100s time
precision and if you use a larger scaling value you will have problems
with 1fs precisions because of the limited precision in a real value. So
this scheme has some minor problems, but should work for most cases.

Going back to Verilog-A for inspiration it has a time function $abstime
which returns the simulation time in seconds. It's trivial to implement
$abstime as a scaled version of $realtime using the VPI. Though I'm not
sure this is 100% correct since $abstime may not round the value using
the local precision while $realtime is required to do this. I would need
to do some testing to see exactly what it does since the Verilog-A
standard is not very descriptive.

Cary
 
In Verilog (and SystemVerilog) the timescale is known at compile
time, and presumably *you* know it because you set it. Of course
you may have set the timescale non-locally, but that is probably
a mistake, and Icarus Verilog will detect that case and print a
warning.

Really, I think the intent is that you have a time (or timescale)
in mind, and you explicitly tell the compiler that timescale so
that there is no chance for confusion. (Note that time scale is
not the same as precision.) If you really want to query the timescale,
I think you are probably making a mistake, but ignoring that, I
think you can write some PLI code to return the timescale for the
current scope.

On 08/26/2013 10:24 AM, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years of using Verilog and now I need it can't can't figure out how to do it. I just want a way for my code to know the current timescale so it can interpret $time correctly. The only thing close I've found is $printtimescale, but that's just a print statement and I need to capture it's output into variables. I've googled and searched the LRM and can't find anything.

Thanks for any help!

David

--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
 
On Monday, August 26, 2013 6:58:07 PM UTC-7, Stephen Williams wrote:
In Verilog (and SystemVerilog) the timescale is known at compile

time, and presumably *you* know it because you set it. Of course you may have set the timescale non-locally, but that is probably a mistake, and Icarus Verilog will detect that case and print a warning.

Really, I think the intent is that you have a time (or timescale) in mind, and you explicitly tell the compiler that timescale so that there is no chance for confusion. (Note that time scale is not the same as precision.) If you really want to query the timescale, I think you are probably making a mistake, but ignoring that, I think you can write some PLI code to return the timescale for the current scope.

Steve, I don't understand or agree with your reasoning. I'm working on projects with hundreds of files written by dozens of people - including lots of outside IP vendors. I want to put in a monitor that accesses the current simulation time might not "know" the current timescale. If I access $time, how do I know what units it's in?

I'll have to try Dave Rich's suggestion (timevar $realtime/1ns) tomorrow. Looks like a pretty clean way to do this and not have to deal with PLI. I was already writing some DPI calls today to get this same monitor to access the "wall clock" time - another thing Verilog has no standard way to do!

Just seems odd that after so many years and revisions that Verilog doesn't have a standard way to do this. Obviously the hooks are there with $printtimescale but no way to get this back into a variable.

Thanks for the replies!

David
 
On Mon, 26 Aug 2013 10:24:31 -0700, unfrostedpoptart wrote:

Hi all.

This is one of those things I've never thought about after many years of
using Verilog and now I need it can't can't figure out how to do it. I
just want a way for my code to know the current timescale so it can
interpret $time correctly. The only thing close I've found is
$printtimescale, but that's just a print statement and I need to capture
it's output into variables. I've googled and searched the LRM and can't
find anything.

Thanks for any help!

Not that it's relevant here, but in VHDL (which doesn't have a timescale
directive) I do it as follows:

Start with some time, e.g. 1us.

Keep dividing by 10 until it underflows.

Regards,
Allan
 
I think one of the biggest screw-ups of Verilog is that the
`timescale setting can escape a given file. So given that, yes
I agree that you can have difficulty knowing your timescale at
a given point.

But if you put a `timescale directive in front of your test bench
module, then you know by design what your timescale is within
your module. I don't understand why you can't do that. Timescale
is something that is defined lexically, and never at run time.

In SystemVerilog, you can get the timescale for only the current
module. That is far better then the `timescale directive, and
if you have access to SystemVerilog, that is what you should be
using.

On 08/27/2013 12:33 AM, unfrostedpoptart wrote:
On Monday, August 26, 2013 6:58:07 PM UTC-7, Stephen Williams wrote:
In Verilog (and SystemVerilog) the timescale is known at compile

time, and presumably *you* know it because you set it. Of course you may have set the timescale non-locally, but that is probably a mistake, and Icarus Verilog will detect that case and print a warning.

Really, I think the intent is that you have a time (or timescale) in mind, and you explicitly tell the compiler that timescale so that there is no chance for confusion. (Note that time scale is not the same as precision.) If you really want to query the timescale, I think you are probably making a mistake, but ignoring that, I think you can write some PLI code to return the timescale for the current scope.

Steve, I don't understand or agree with your reasoning. I'm working on projects with hundreds of files written by dozens of people - including lots of outside IP vendors. I want to put in a monitor that accesses the current simulation time might not "know" the current timescale. If I access $time, how do I know what units it's in?

I'll have to try Dave Rich's suggestion (timevar $realtime/1ns) tomorrow. Looks like a pretty clean way to do this and not have to deal with PLI. I was already writing some DPI calls today to get this same monitor to access the "wall clock" time - another thing Verilog has no standard way to do!

Just seems odd that after so many years and revisions that Verilog doesn't have a standard way to do this. Obviously the hooks are there with $printtimescale but no way to get this back into a variable.

Thanks for the replies!

David

--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
 
Allan Herriman wrote:
On Mon, 26 Aug 2013 10:24:31 -0700, unfrostedpoptart wrote:

Hi all.

This is one of those things I've never thought about after many years of
using Verilog and now I need it can't can't figure out how to do it. I
just want a way for my code to know the current timescale so it can
interpret $time correctly. The only thing close I've found is
$printtimescale, but that's just a print statement and I need to capture
it's output into variables. I've googled and searched the LRM and can't
find anything.

Thanks for any help!

Not that it's relevant here, but in VHDL (which doesn't have a timescale
directive) I do it as follows:

Start with some time, e.g. 1us.

Keep dividing by 10 until it underflows.

Regards,
Allan

VHDL doesn't have the equivalent of a time scale, either. In VHDL, all
specified times must have a unit. I think you could find the simulation
precision using your method in either language, but in Verilog that's
not the same thing as time scale, which determines the units for delays.

--
Gabor
 
On Tue, 27 Aug 2013 11:43:58 -0400, GaborSzakacs wrote:

Allan Herriman wrote:
On Mon, 26 Aug 2013 10:24:31 -0700, unfrostedpoptart wrote:

Hi all.

This is one of those things I've never thought about after many years
of using Verilog and now I need it can't can't figure out how to do
it. I just want a way for my code to know the current timescale so
it can interpret $time correctly. The only thing close I've found is
$printtimescale, but that's just a print statement and I need to
capture it's output into variables. I've googled and searched the LRM
and can't find anything.

Thanks for any help!

Not that it's relevant here, but in VHDL (which doesn't have a
timescale directive) I do it as follows:

Start with some time, e.g. 1us.

Keep dividing by 10 until it underflows.

Regards,
Allan

VHDL doesn't have the equivalent of a time scale, either. In VHDL, all
specified times must have a unit. I think you could find the simulation
precision using your method in either language, but in Verilog that's
not the same thing as time scale, which determines the units for delays.

Yes, exactly. I thought it was a useful technique worthy of mentioning
in any case.

Allan
 
On Monday, 26 August 2013 13:24:31 UTC-4, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years of using Verilog and now I need it can't can't figure out how to do it. I just want a way for my code to know the current timescale so it can interpret $time correctly. The only thing close I've found is $printtimescale, but that's just a print statement and I need to capture it's output into variables. I've googled and searched the LRM and can't find anything.

Thanks for any help!

David

In case anyone is still looking for it - if $realtime is supported...

initial begin #1; realvar_tscale_unit = $realtime; end
 
gord.allan@gmail.com wrote:
On Monday, 26 August 2013 13:24:31 UTC-4, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years of using Verilog and now I need it can't can't figure out how to do it. I just want a way for my code to know the current timescale so it can interpret $time correctly. The only thing close I've found is $printtimescale, but that's just a print statement and I need to capture it's output into variables. I've googled and searched the LRM and can't find anything.

Thanks for any help!

David

In case anyone is still looking for it - if $realtime is supported...

initial begin #1; realvar_tscale_unit = $realtime; end

I tried that with ISIM (Xilinx simulator bundled with ISE) and
regardless of the time scale it returns 1.0, i.e. the real value
will be in units of the timescale. Do you have different results
on another simulator?

--
Gabor
 
On Mon, 24 Oct 2016 09:06:28 -0400, GaborSzakacs wrote:

gord.allan@gmail.com wrote:
On Monday, 26 August 2013 13:24:31 UTC-4, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years
of using Verilog and now I need it can't can't figure out how to do
it. I just want a way for my code to know the current timescale so
it can interpret $time correctly. The only thing close I've found is
$printtimescale, but that's just a print statement and I need to
capture it's output into variables. I've googled and searched the LRM
and can't find anything.

Thanks for any help!

David

In case anyone is still looking for it - if $realtime is supported...

initial begin #1; realvar_tscale_unit = $realtime; end

I tried that with ISIM (Xilinx simulator bundled with ISE) and
regardless of the time scale it returns 1.0, i.e. the real value will be
in units of the timescale. Do you have different results on another
simulator?

Here's how I do it in VHDL, for those rare times I need to know the
simulator timescale:

pure function get_timescale return time is
variable new_timescale : time := 1 us;
variable last_timescale : time;
begin
loop
last_timescale := new_timescale;
new_timescale := new_timescale / 10;
exit when new_timescale = 0 fs;
end loop;
return last_timescale;
end function get_timescale;

I don't think that translates to Verilog so well though.

Allan
 
Allan Herriman wrote:
On Mon, 24 Oct 2016 09:06:28 -0400, GaborSzakacs wrote:

gord.allan@gmail.com wrote:
On Monday, 26 August 2013 13:24:31 UTC-4, unfrostedpoptart wrote:
Hi all.

This is one of those things I've never thought about after many years
of using Verilog and now I need it can't can't figure out how to do
it. I just want a way for my code to know the current timescale so
it can interpret $time correctly. The only thing close I've found is
$printtimescale, but that's just a print statement and I need to
capture it's output into variables. I've googled and searched the LRM
and can't find anything.

Thanks for any help!

David
In case anyone is still looking for it - if $realtime is supported...

initial begin #1; realvar_tscale_unit = $realtime; end
I tried that with ISIM (Xilinx simulator bundled with ISE) and
regardless of the time scale it returns 1.0, i.e. the real value will be
in units of the timescale. Do you have different results on another
simulator?

Here's how I do it in VHDL, for those rare times I need to know the
simulator timescale:

pure function get_timescale return time is
variable new_timescale : time := 1 us;
variable last_timescale : time;
begin
loop
last_timescale := new_timescale;
new_timescale := new_timescale / 10;
exit when new_timescale = 0 fs;
end loop;
return last_timescale;
end function get_timescale;

I don't think that translates to Verilog so well though.

Allan

I'm not sure what timescale means in VHDL, but in Verilog it has two
components. The first is the units used for # delays, the second is
the simulation resolution. Your code looks like it is for discovering
the simulation resolution. The part that's most likely to be an issue
in Verilog is the units for # delays, since the units are not specified
on each delay as they are in VHDL. Getting it wrong means that the
simulation (for that module) runs at an inappropriate rate.

I suppose if you already new the simulator resolution, you could find
the # delay units in a manner similar to your VHDL code. I don't really
see a way to discover both parts of the Verilog timescale.

--
Gabor
 
Using QuestaSim, time is a floating point number where 1.0 is the time resolution limit. So if you want to see what the limit is set to, just ask in terms of the normalized units you want.

E.g., real LimitInNanoseconds = 10**9/1s;
real LimitInPicoseconds = 10**12/1s;

Test: vsim -t 10ns
$display ("Time Resolution Limit = %0f ns",10**9/1s);
# Time Resolution Limit = 10.000000 ns

vsim -t 10ps
$display ("Time Resolution Limit = %0f ns",10**9/1s);
# Time Resolution Limit = 0.010000 ns
 

Welcome to EDABoard.com

Sponsor

Back
Top