7

How do I detect the timescale precision used in a simulation from the source code ?. Consider I have a configuration parameter(cfg_delay_i) of some delay value given by user in timeunits as fs .If the user gives 1000 , my code has to wait 1000fs or 1ps before executing further.

#(cfg_delay_i * 1fs );//will wait only if timescale is 1ps/1fs
do_something(); 

If the timescale precision is 1fs ,there won’t be any problem but if the precision is higher than that it won’t wait and it will work as 0 delay . So I want to write a code which will determine the timescale used by the user and give the delay accordingly.My expected pseudo-code will be like below,

if(timeprecision == 1fs )#(cfg_delay_i * 1fs ) ; 
else if(timeprecision == 1ps )#(cfg_delay_i/1000 * 1ps ) ;

Please help me with the logic to determine the timescale unit and precision internally.

Sreejin TJ
  • 177
  • 12

2 Answers2

6

You can write if (int'(1fs)!=0) // the time precision is 1fs and so on. But there's no need to do this.

#(cfg_delay_i/1000.0 * 1ps)

The above works regardless if the precision is 1ps or smaller. Note the use of the real literal 1000.0 to keep the division real. 1ps is already a real number, so the result of the entire expression will be real. You could also do

#(cfg_delay_i/1.e6 * 1ns)

If the time precision at the point where this code is located is greater than 1fs, the result gets rounded to the nearest precision unit. For example if cfg_delay is 500 and the current precision is 1ps, this would get rounded to #1ps.

Do be aware that the user setting cfg_delay has to take the same care to make sure their value is set with the correct scaling/precision.

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • Thank you sir .When using real literal it avoids the problem but the value has to be taken care of by the user. Also I think that the expression **int'(1fs) == 1** can be used to find the timeunit and not the precision used. (**`eg. if(int'(1ps) == 1)//if yes timeunit is 1ps, it doesn’t infer anything about precision`**).Kindly let me know if I can find the exact precision used in a similar way. – Sreejin TJ Oct 01 '19 at 09:04
  • 1
    You can do a chain of `if/else` or `case` statement checking each precision in increasing magnitude. `1fs!=0.0, 10fs!=0.0, etc.` The first real non-zero is the precision. – dave_59 Oct 01 '19 at 15:48
0

This seems to work in Vivado

// Example where we need to check the clock frequency or the time of an event

    real tscale_unit;
    realtime t_edge1;
    realtime t_edge2;
    realtime t_event;
    real clk_freq;
    
    initial begin
        t_edge1 = 0.0s;
        #1;  // Single unit time delay
        tscale_unit = $realtime / 1ps;  //  Normalise the timescale into picoseconds (1*10^-12)
    end
    
    always begin
        @(posedge clk);
        t_edge2 = t_edge1;
        t_edge1 = $realtime;
        clk_freq = 1.0s/((t_edge1 - t_edge2) * tscale_unit * 1ps);
    end

    always begin
        @(posedge event);
        t_event = $realtime * tscale_unit * 1ps;
    end
Jay M
  • 3,736
  • 1
  • 24
  • 33