In the last post "System Verilog timescale Across Clases Illustrated", I covered some of the troubles of using the realtime type in System Verilog. This post is the conclusion on a viable and safe way of inserting delays across classes or files.
I had been researching the problem with the realtime type across classes and files, and came across a post on a forum by Dave Rich from Mentor that suggested the possible solution. The solution is to use only the real part of the realtime type and normalize it before you send it. Here is the text from the post by Rich.
In SystemVerilog, you can write (timevar = $time/1ns) or better (timevar $realtime/1ns) and you will get your time back in ns. If you need to use timevar as part of a delay expression, make sure you scale it back, i.e. #(timevar*1ns).Dave Rich
from comp.lang.verilog reply to "How to know/read current timescale?"
Below is the example code to implement and test out the idea derived from Rich.
// `timescale 1ps/1ps `timescale 1fs/1fs package shared; class helper; static task delay_ps(real delay); real t0, t1; t0 = $realtime; $printtimescale; $display("delay_ps(%g)", delay); #(delay*1ps); t1 = $realtime; if (t0 == t1) $error("%m timescale not precise enough"); endtask // delay_ps endclass // helper endpackage // shared `timescale 1ps/1ps // `timescale 1fs/1fs module tb (); task print_time(); $display("\n%f is tb time\n", $realtime); endtask initial begin $display("\n"); $printtimescale; $display("\n"); print_time(); #2ps; $display("delay 2ps"); print_time(); shared::helper::delay_ps(2); print_time(); shared::helper::delay_ps(2ps/1ps); print_time(); shared::helper::delay_ps(0.002ns/1ps); print_time(); shared::helper::delay_ps(0.000002us/1ps); print_time(); #2fs; $display("delay 2fs"); print_time(); $finish(); end endmodule
When the shared::helper::delay_ps task is called we are passing variations of time which are all normalized to be in ps. As long as you divide by ps (the unit that the delay_ps task will multiply by) it all works out. If you try to do something below the precision that is possible, the task will tell you it was not successful.
The output of the code above is below.
# Time scale of (tb) is 1ps / 1ps
#
#
#
# 0.000000 is tb time
#
# delay 2ps
#
# 2.000000 is tb time
#
# Time scale of (shared.helper.delay_ps) is 1fs / 1fs
# delay_ps(2)
#
# 4.000000 is tb time
#
# Time scale of (shared.helper.delay_ps) is 1fs / 1fs
# delay_ps(2)
#
# 6.000000 is tb time
#
# Time scale of (shared.helper.delay_ps) is 1fs / 1fs
# delay_ps(2)
#
# 8.000000 is tb time
#
# Time scale of (shared.helper.delay_ps) is 1fs / 1fs
# delay_ps(2)
#
# 10.000000 is tb time
#
# delay 2fs
#
# 10.002000 is tb time