Hi All ,
I am trying the following code :
`timescale 1ns / 100ps
module top ;
initial begin
static realtime rtdelay = 800.559 ; // What gets stored in rtdelay ?
static time tdelay = 800.509 ; // Rounded to 801
$timeformat( -12 , 0 , "ps" , 5);
#rtdelay;
$display("At T:%t %t" , $realtime , rtdelay );
#tdelay;
$display("At T:%t %t" , $realtime , tdelay );
end
endmodule
I observe output :
At T:800600ps 800559ps
At T:1601600ps 801000ps
Since 100ps == 0.1ns ,Real numbers would be rounded-off to 1 decimal place.
So why is it that rtdelay has value stored as 800.559 instead of rounding it off to 800.6 ?
Delay of #rtdelay corresponds to 800.6ns i.e 800600ps i.e it’s rounded-off to 1 decimal place .
(2) I then added time units to the assignment :
............
initial begin
static realtime rtdelay = 800.559ps ; // What gets stored in rtdelay ?
static time tdelay = 800.509ps ;
........................
The output changes to :
At T:800ps 801ps
At T:1800ps 1000ps
In the 2nd case I believe the time values are scaled to time unit of 1ns
Hence rtdelay would have value 0.8 ( ns ) and tdelay would have value 1 ( ns )
The same are converted to ps and used as delays
However why is it that rtdelay is displayed as 801 and not 800 ?
In reply to MICRO_91:
realtime is equivalent to real.
time is equivalent to logic [63:0].
In earlier versions of Verilog, integers, reals, and time types had implementation dependant number of bit of resolution. Now all built-in types are fixed.
rtdelay stores the real value 800.559. Time scales and precision only apply to expressions using in delay constructs. Not until the appearance of #rtdelay do the scaling and precision apply.
In reply to dave_59:
rtdelay stores the real value 800.559. Time scales and precision only apply to expressions using in delay constructs. Not until the appearance of #rtdelay do the scaling and precision apply
Thanks Dave ,
The above quotes does explain the scaling and precision part .
However I am still confused about the following :
(a) In (1) the value assigned 800.559 is a real no. which is unitless
In (2) the value assigned 800.559 is a real no. which has a unit of ps.
**Does the unit make a difference in what gets stored in variable rtdelay in 2nd case ?**
(b) How does the format specifier %t work with rtdelay as argument in both cases ?
In (1) the value assigned to rtdelay is 800.559 .
It seems that it takes this to be in units of ns and it simply converts it to ps in the output i.e multiplies it by 1000
Similarly I am not fully clear on how 801 is shown in output for (2)
In reply to MICRO_91:
Sorry I missed the second half of your question.
When using “ps” with the time literal, the LRM says
The time literal is interpreted as a realtime value scaled to the current time unit
Since the time unit/scale is 1ns, rtdelay gets the value ‘0.800559’, and tdelay gets the value 1. %t assumes its value argument is in 1ns, but your $timeformat says to scale it back to 1ps, with 0 decimal places of precision. that gets rounded up to 801ps.
LRM Section 5.8 : The time literal is interpreted as a realtime value scaled to the current time unit and rounded to the current time precision.
Hence 800.559ps would be scaled to time unit of 1ns i.e ‘0.800559’ .
Similarly tdelay is scaled to 0.800509 which is rounded-off to 1 in 2nd case
In reply to dave_59:
Hi Dave ,
I was thinking of the reason behind :
%t assumes its value argument is in 1ns
Is this because the arguments to %t are typically $time / $realtime both of which are by default scaled to the time unit of the module ?
hence %t assumes its value argument is already in time unit of the module i.e 1ns
In reply to MICRO_91:
That certainly is one reason.
In reply to dave_59:
Hi Dave,
I reviewed this code, made a few changes, and observed the following.
`timescale 10ns / 10ps
module top ;
initial begin
static real rtdelay = 800.559 ; // What gets stored in rtdelay ?
static time tdelay = 800.509 ; // Rounded to 801
$display(" ",$realtime ," At T:%t" , rtdelay );
$display(" At T:%t %t\n" , $realtime , rtdelay );
#rtdelay;
$display(" ",$realtime ," At T:%t" , rtdelay );
$display(" At T:%t %t\n" , $realtime , rtdelay );
#tdelay;
$display(" ",$realtime ," At T:%t" , tdelay );
$display(" At T:%t %t\n" , $realtime , tdelay );
$timeformat( -10 , 5 , "ps");
$display(" ",$realtime ," At T:%t" , tdelay );
$display(" At T:%t %t" , $realtime , tdelay );
end
endmodule
The output is :
# vsim -voptargs=+acc=npr
# run -all
# 0 At T: 800559
# At T: 0 800559
#
# 800.559 At T: 800559
# At T: 800559 800559
#
# 1601.559 At T: 801000
# At T: 1601559 801000
#
# 1601.559 At T: 80100.00000ps
# At T: 160155.90000ps 80100.00000ps
# exit
- Here, as you can see I have displayed the $realtime in two ways. First-one is using $realtime and the second one uses $realtime along with %t/%0t. We got different results.
Is it because the unit or format of $time or $realtime depends on the time unit and %t/%0t depends on time precision?
Another point is - $timeformat this system function targets only time-precision.
If you go through the last two displays, you will see that in the first one 1601.559, we got after doing the operation on 1601559. 1601559 is in ps and unit-time was in ns. That’s why
$realtime = 1601559 * (current_time_unit / target_time_unit)=1601559 * .001 = 1601.559.
If we consider this theory as the main reason / correct explanation, then in the second display we should have got 160.1559 instead of 1601.559.
In reply to Shubhabrata:
The default setting for $timeformat assumes the global time precision as the time unit format.
Since the global time precision is 10ps and the local time unit is 10ns, it will multiply any value in the current scope by 1000.
You used -10 as the units_number for $timeformat, which is 100ps not 1ps.