# uvm_tlm_time

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.

Summary

uvm_tlm_time
Canonical time type that can be used in different timescales
Class Declaration
> class uvm_tlm_time
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, regardless of the current timescale of the caller.
set_abstime | Set the current canonical time value, to the number of specified time unit, regardless 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.

### set_time_resolution

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

### new

> 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.

### get_name

> function string get_name()

Return the name of this instance

### reset

> function void reset()

Reset the value to 0

### get_realtime

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

### incr

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

### decr

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

### get_abstime

> function real get_abstime(
> | real | secs
> )

Return the current canonical time value, in the number of specified time unit, regardless 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));

### set_abstime

> function void set_abstime(
> | real | t,
> | real | secs
> )

Set the current canonical time value, to the number of specified time unit, regardless 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));

### 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. 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

- different time scale
- different time precision

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

yields

>     T=10 ps (10,000)

Scaling is needed every time 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.

> class uvm_tlm_time

Canonical time type that can be used in different timescales

> static function void set_time_resolution(
> | real | res
> )

Set the default canonical time resolution.

> function new(
> | string | name | = | "uvm_tlm_time",
> | real | res | = | 0
> )

Create a new canonical time value.

> function string get_name()

Return the name of this instance

> function void reset()

Reset the value to 0

> function real get_realtime(
> | time | scaled, |  |
> | real | secs | = | 1.0e-9
> )

Return the current canonical time value, scaled for the caller’s timescale

> function void incr(
> | real | t, |  |
> | time | scaled, |  |
> | real | secs | = | 1.0e-9
> )

Increment the time value by the specified number of scaled time unit

> function void decr(
> | real | t,
> | time | scaled,
> | real | secs
> )

Decrement the time value by the specified number of scaled time unit

> function real get_abstime(
> | real | secs
> )

Return the current canonical time value, in the number of specified time unit, regardless of the current timescale of the caller.

> function void set_abstime(
> | real | t,
> | real | secs
> )

Set the current canonical time value, to the number of specified time unit, regardless of the current timescale of the caller.
Integers are not sufficient, on their own, to represent time without any ambiguity: you need to know the scale of that integer value.