Are variables of type realtime rounded-off based on timeprecision?

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.