For this code
module foo;
timeunit 1ns / 1ps;
parameter T = 4837ps;
bit aclk;
initial begin
$timeformat(-9, 3, "ns", 10);
aclk=1'b0;
forever begin
#(T) aclk = ~aclk;
$display("%t %t: %0b time=%16x %f", $time, $realtime, aclk, $time, $realtime);
end
end
endmodule
LRM 20.3.1 “The $time system function returns an integer that is a 64-bit time, scaled to the time unit of the module that invoked it.” So it can only report the time (rounded up or down to) the nearest 1ns, when printed with %t and %x formats.
LRM 20.3.3 “The $realtime system function returns a real number time that, like $time, is scaled to the time unit of the module that invoked it.” It shows the time to the ps resolution of the parameter T, when printed with %t and %f formats.
My simulator shows this output. Makes sense.
# 5.000ns 4.837ns: 1 time=0000000000000005 4.837000
# 10.000ns 9.674ns: 0 time=000000000000000a 9.674000
# 15.000ns 14.511ns: 1 time=000000000000000f 14.511000
# 19.000ns 19.348ns: 0 time=0000000000000013 19.348000
If the parameter statement is instead
parameter time T = 4837ps;
then $realtime does not show the ps resolution of T.
# 5.000ns 5.000ns: 1 time=0000000000000005 5.000000
# 10.000ns 10.000ns: 0 time=000000000000000a 10.000000
# 15.000ns 15.000ns: 1 time=000000000000000f 15.000000
# 20.000ns 20.000ns: 0 time=0000000000000014 20.000000
This thread
https://verificationacademy.com/forums/t/time-by-time-division/33191
mentions that “time literals are real numbers scaled to the current timescale” and “time is just a 64-bit type”.
Why does “parameter time T” appear to cause a loss of precision?