Canonical time type that can be used in different timescales
This time type is used to represent time values in a canonical form that can bridge initiators and targets located in different timescales and time precisions.
For a detailed explanation of the purpose for this class, see Why is this necessary.
uvm_tlm_time | ||
Canonical time type that can be used in different timescales | ||
Class Declaration | ||
| ||
set_time_resolution | Set the default canonical time resolution. | |
new | Create a new canonical time value. | |
get_name | Return the name of this instance | |
reset | Reset the value to 0 | |
get_realtime | Return the current canonical time value, scaled for the caller’s timescale | |
incr | Increment the time value by the specified number of scaled time unit | |
decr | Decrement the time value by the specified number of scaled time unit | |
get_abstime | Return the current canonical time value, in the number of specified time unit, reguardless of the current timescale of the caller. | |
set_abstime | Set the current canonical time value, to the number of specified time unit, reguardless of the current timescale of the caller. | |
Why is this necessary | Integers are not sufficient, on their own, to represent time without any ambiguity: you need to know the scale of that integer value. |
static function void set_time_resolution( real res )
Set the default canonical time resolution.
Must be a power of 10. When co-simulating with SystemC, it is recommended that default canonical time resolution be set to the SystemC time resolution.
By default, the default resolution is 1.0e-12 (ps)
function new( string name = "uvm_tlm_time", real res = 0 )
Create a new canonical time value.
The new value is initialized to 0. If a resolution is not specified, the default resolution, as specified by set_time_resolution(), is used.
function real get_realtime( time scaled, real secs = 1.0e-9 )
Return the current canonical time value, scaled for the caller’s timescale
scaled must be a time literal value that corresponds to the number of seconds specified in secs (1ns by default). It must be a time literal value that is greater or equal to the current timescale.
#(delay.get_realtime(1ns)); #(delay.get_realtime(1fs, 1.0e-15));
function void incr( real t, time scaled, real secs = 1.0e-9 )
Increment the time value by the specified number of scaled time unit
t is a time value expressed in the scale and precision of the caller. scaled must be a time literal value that corresponds to the number of seconds specified in secs (1ns by default). It must be a time literal value that is greater or equal to the current timescale.
delay.incr(1.5ns, 1ns); delay.incr(1.5ns, 1ps, 1.0e-12);
function void decr( real t, time scaled, real secs )
Decrement the time value by the specified number of scaled time unit
t is a time value expressed in the scale and precision of the caller. scaled must be a time literal value that corresponds to the number of seconds specified in secs (1ns by default). It must be a time literal value that is greater or equal to the current timescale.
delay.decr(200ps, 1ns);
function real get_abstime( real secs )
Return the current canonical time value, in the number of specified time unit, reguardless of the current timescale of the caller.
secs is the number of seconds in the desired time unit e.g. 1e-9 for nanoseconds.
$write("%.3f ps\n", delay.get_abstime(1e-12));
function void set_abstime( real t, real secs )
Set the current canonical time value, to the number of specified time unit, reguardless of the current timescale of the caller.
secs is the number of seconds in the time unit in the value t e.g. 1e-9 for nanoseconds.
delay.set_abstime(1.5, 1e-12));
Integers are not sufficient, on their own, to represent time without any ambiguity: you need to know the scale of that integer value. That scale is information conveyed outside of that integer. In SystemVerilog, it is based on the timescale that was active when the code was compiled. SystemVerilog properly scales time literals, but not integer values. That’s because it does not know the difference between an integer that carries an integer value and an integer that carries a time value. The ‘time’ variables are simply 64-bit integers, they are not scaled back and forth to the underlying precision.
`timescale 1ns/1ps module m(); time t; initial begin #1.5; $write("T=%f ns (1.5)\n", $realtime()); t = 1.5; #t; $write("T=%f ns (3.0)\n", $realtime()); #10ps; $write("T=%f ns (3.010)\n", $realtime()); t = 10ps; #t; $write("T=%f ns (3.020)\n", $realtime()); end endmodule
yields
T=1.500000 ns (1.5) T=3.500000 ns (3.0) T=3.510000 ns (3.010) T=3.510000 ns (3.020)
Within SystemVerilog, we have to worry about
Because each endpoint in a socket could be coded in different packages and thus be executing under different timescale directives, a simple integer cannot be used to exchange time information across a socket.
For example
`timescale 1ns/1ps package a_pkg; class a; function void f(inout time t); t += 10ns; endfunction endclass endpackage `timescale 1ps/1ps program p; import a_pkg::*; time t; initial begin a A = new; A.f(t); #t; $write("T=%0d ps (10,000)\n", $realtime()); end endprogram
yeilds
T=10 ps (10,000)
Scaling is needed everytime you make a procedural call to code that may interpret a time value in a different timescale.
Using the uvm_tlm_time type
`timescale 1ns/1ps package a_pkg; import uvm_pkg::*; class a; function void f(uvm_tlm_time t); t.incr(10ns, 1ns); endfunction endclass endpackage `timescale 1ps/1ps program p; import uvm_pkg::*; import a_pkg::*; uvm_tlm_time t = new; initial begin a A = new; A.f(t); #(t.get_realtime(1ns)); $write("T=%0d ps (10,000)\n", $realtime()); end endprogram
yields
T=10000 ps (10,000)
A similar procedure is required when crossing any simulator or language boundary, such as interfacing between SystemVerilog and SystemC.
Canonical time type that can be used in different timescales
class uvm_tlm_time
Set the default canonical time resolution.
static function void set_time_resolution( real res )
Create a new canonical time value.
function new( string name = "uvm_tlm_time", real res = 0 )
Return the name of this instance
function string get_name()
Reset the value to 0
function void reset()
Return the current canonical time value, scaled for the caller’s timescale
function real get_realtime( time scaled, real secs = 1.0e-9 )
Increment the time value by the specified number of scaled time unit
function void incr( real t, time scaled, real secs = 1.0e-9 )
Decrement the time value by the specified number of scaled time unit
function void decr( real t, time scaled, real secs )
Return the current canonical time value, in the number of specified time unit, reguardless of the current timescale of the caller.
function real get_abstime( real secs )
Set the current canonical time value, to the number of specified time unit, reguardless of the current timescale of the caller.
function void set_abstime( real t, real secs )