Assign random delay to existing clock

Hi, I want to assign a random delay to my existing clock.
I tried below code but not sure if its correct or not, any help would be appreciated

real rand_val;
initial begin
rand_val = $urandom_range(0,128)/100.0;
`uvm_info(“DELTA”, $sformatf(“Randomized delta: %f”, rand_val), UVM_NONE);
end

always @(posedge itf.clk_itf[CLK_UNSHAPED].clk) begin
`uvm_info(“DELTA”, $sformatf(“Randomized delta: %f”, rand_val), UVM_NONE);
#rand_val itf.clk_itf[CLK_UNSHAPED].clk =~ itf.clk_itf[CLK_UNSHAPED].clk;
//itf.clk_itf[CLK_UNSHAPED].clk = #rand_val itf.clk_itf[CLK_UNSHAPED].clk;

In reply to rushabhmangukiya27:

Hi, I want to assign a random delay to my existing clock.
I tried below code but not sure if its correct or not, any help would be appreciated

If I understand your question correctly, you are saying that:


module m;
   `include "uvm_macros.svh"   import uvm_pkg::*;
  timeunit 1ns;  timeprecision 100ps;  
  bit clk, clk_d;
  int t;
  always @(posedge clk) begin
    if (!randomize(t)  with 
      { t dist {0:=1, 1:=2, 2:= 1, 3:=1};
        }) `uvm_error("MYERR", "This is a randomize error")
   `uvm_info("DELTA_to_1", $sformatf("Randomized delta: %d", t),UVM_NONE);
   #t clk_d=1; 
   @(negedge clk) 
   if (!randomize(t)  with 
        { t dist {0:=1, 1:=2, 2:= 1, 3:=1};
        }) `uvm_error("MYERR", "This is a randomize error")
     `uvm_info("DELTA_to_1", $sformatf("Randomized delta: %d", t), UVM_NONE);
   #t clk_d=0; 
  end  
  initial forever #10 clk=!clk;   
  initial #200 $finish; 
endmodule
https://www.edaplayground.com/x/WD7c



Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  2. Free books: * Component Design by Example https://rb.gy/9tcbhl
  1. Papers:

Udemy courses by Srinivasan Venkataramanan (http://cvcblr.com/home.html)
https://www.udemy.com/course/sva-basic/
https://www.udemy.com/course/sv-pre-uvm/

Hi Ben,

Thanks for you reply.
I think you misunderstood, I have one clock there named CLK, I want to delayed this clock by some random values. random delay should be from (0 to 1.28ns).

real rand_val;
initial begin
rand_val = $urandom_range(0,128)/100.0;
`uvm_info(“DELTA”, $sformatf(“Randomized delta: %f”, rand_val), UVM_NONE);
end

so here, I randomized the delay which is rand_val now I want my CLK to be delayed by that rand_val value. Is that you meant?

In reply to rushabhmangukiya27:

What is the source of this clock? Is it external or is it generated?
What is the frequency of this clock?
You may be saying:

  1. I have a symmetrical clock with a period of 10ns (10,000 ps)
  2. This clock has jitter from 0 to 1.28ns (1280 ps)
    Meaning it is 0 for 5ns+delay, then 1 for 5ns+delay
    also at Edit code - EDA Playground
    This is my test code. You need to check the units.

module m;
    timeunit 1ps;  timeprecision 100fs;    
    `include "uvm_macros.svh"   import uvm_pkg::*;
    bit clk, clk_d;
    int rand_val;
   
  initial forever begin
    int half_p;
    rand_val = $urandom_range(0,128);
    `uvm_info("DELTA", $sformatf("Randomized delta: %d", rand_val), UVM_NONE);
    half_p=5000 + rand_val; 
    #half_p clk=1; 
    $display("t=%t, clk=%b", $realtime, clk);
    //
    rand_val = $urandom_range(0,128);
    `uvm_info("DELTA", $sformatf("Randomized delta: %d", rand_val), UVM_NONE);
    half_p=5000 + rand_val; 
    #half_p clk=0;  
    $display("t=%t, clk=%b", $realtime, clk);
  end  
   
   
   initial begin 
     repeat(10) begin 
       @(posedge clk); 
       $display("t2=%t", $realtime);
     end 
    $finish;
   end
   endmodule
  
  

my clock period is 1.28ns.
frequency is 781Mhz.

The above code is for clock generator. but in my case there is already one clock and I want to delay/shift it by random delay. My random delay should be 0 to 1.28ns. It should be added at the beginning of the clock. (In other words I just want to shift phase).

for example:
lets say first positive edge comes at 1ns without adding any delay.
Now, my random delay is 1ns which is from [0, 1.28]ns.
Now, 1st positive edge should come on at 2ns, so we are shifting entire clock by 1ns delay.

so can we do like this? or you can suggest better way.

real rand_val;
initial begin
rand_val = $urandom_range(0,128)/100.0;
`uvm_info(“DELTA”, $sformatf(“Randomized delta: %f”, rand_val), UVM_NONE);
end

always @(posedge clk) begin
//here we can add delay
end

In reply to rushabhmangukiya27:
Update: AFTER MORE THOUGHTS MY ATTEMPTED SOLUTION /APPROACH IS NOT GOING TO WORK.
MY FIRST APPROACH OF USING A SEPARATE SIGNAL FOR THE DELAYED CLOCK SEEMS OK.

PS:I am leaving this post for discussion, as this was an attempt that at first looked promising.

This is the concept, it needs tuning.
Basically you have a process that is in sync with the clock, wakes up 1ps before the expected clk transition, computes the delay and drive after 1ps the drive extension and then afterthe delay goes to Z. The current code has a bug, but it is conceptually correct.


module m;
    timeunit 1ps;  timeprecision 100fs;    
    `include "uvm_macros.svh"   import uvm_pkg::*;
    logic clk0, clk1;
    wire clk;
    int rand_val;
    initial begin 
        clk0 = 0; 
        forever begin 
          #640 clk0=1;
          #640 clk0=0;
        end
    end
    assign clk=clk0;
    assign clk=clk1;
   
  initial forever begin
    #639; // clk will go to 1 in 1ps 
    rand_val = $urandom_range(0,128);
    `uvm_info("DELTA", $sformatf("Randomized delta: %d", rand_val), UVM_NONE);
    if(rand_val>0) begin 
        #1 clk1 = 1; // to be in sync with the clk 
        #rand_val clk1 =1'bZ; // Hold the 1 for rand_val ps 
    end 
    else #1; // to be in sync 
    $display("t=%t, clk=%b", $realtime, clk);
    #639; // clk will go to 0 in 1ps 
    rand_val = $urandom_range(0,128);
    `uvm_info("DELTA", $sformatf("Randomized delta: %d", rand_val), UVM_NONE);
    if(rand_val>0) begin 
        #1 clk1 = 0; // to be in sync with the clk 
        #rand_val clk1 =1'bZ; // Hold the 1 for rand_val ps 
    end 
    else #1; // to be in sync 
    $display("t=%t, clk=%b", $realtime, clk);
  end  
   
   
   initial begin 
     repeat(10) begin 
       @(posedge clk); 
       $display("t2=%t", $realtime);
     end 
    $finish;
   end
   endmodule