Setting reset using repeat or delay

what’s the difference between implementing reset these two way. Are events scheduled differently in timeslot?

initial begin
    rst_n = 0;
    #55 rst_n = 1;
end

or

initial begin
    rst_n = 0;
    repeat(55) @clk;
    rst_n = 1;
  end

In reply to ankitks79:

Without seeing how you generate your clk, we cannot know when rst_n is set relative to the clk. They could both have race conditions if it happens the clk changes at the same time rst_n.
It is usually best to make sure reset changes away from any clock edge.

In reply to dave_59:

Hi Dave,
Thanks for the comment.
My clock looks like this:
//instantiate clk and reset
initial begin
clk = 0;
forever #1 clk = !clk;
end

I want to understand race condition (in fact want to understand how events are scheduled in a given timeslot), hence I was asking that question. With above logic, clock and reset both will be triggered in same timeslot. and I do have flipflop code in design - always @(posedge clk or negedge rst_n). Will this trigger flipflop code twice?

Thanks

In reply to ankitks79:

It won’t trigger te flipflop twice because it’s only waiting for a negedge rst_n, but you do have a race condition with reading the value of rst_n. If your code is

always  @(posedge clk or negedge rst_n) 
        if (rst_n)
          $display("posdege clk");
        else
          $display("reset active");

There’s no way to know if rst_n has been updated and you are reading the new or old value of rst_n. If you change assigning rst_n to a non-blocking assignment, or away from the posedge of clk, you are guaranteed to be reading the old value.

Hi Dave,
In my TB, there is no program, which means there is no re-xxx region in timeslot.
I control rst_n duration with interface.cb. The code is like below:

intial begin
  rst_n = 0;
  repeat(5)
    @vif.cb;
  rst_n <= 1;
end

And in my driver, I use vif.rst_n to judge if drop current item. The code is like below:

forever begin
  try_get_next_item(tmp_item);
  if(tmp_item != null) drv_if;
  else begin
    @vif.cb;
    drv_idle();
  end
end

In drv_if, before driving signals, rst_n is used to judge if dropping or not. And in my simulation, if driver gets an item in the same clk edge with rst_n recover. Even I used the non blocking for rst_n <= 1, driver still gets rst_n === 1 other than rst_n === 0 and I do not know why.

We would need to see a lot more details in order to help you. When is the first edge of the clocking block? Is it after time zero? What are the blocking statements inside drv_if?

Hi Dave,
The logic inside drv if is like below.

task drv_if;
  bit rst_triggered;
  fork begin
    process p = process::self();
    fork
      begin
        if(vif.rstn === 1'b0) p.kill();
        @(vif.cb);
      end
      begin
        repeat(item.delay) @vif.cb;
        vif.cb.xxx <= xxx;
        @(vif.cb);
      end
    join_any
    p.kill();
  end join
endtask

The clocking block is default input #1step and output #0

clocking cb(@posedge clk);
  default input #1step output #0;
  ....
endclocking