Mulitple clock domain

Hello all,
In my design I have 2 clocks where frequency ratio of both clock is clk2:clk1 = 2:1

For following blocks ,

always@(posedge clk2)
begin
   .....
   a<=1'b1;
   .......
end

always@(posedge clk1)
begin
   ........
  if(a==1'b1)
   ........
   ........
end

If signal A is driven non blocking on time “0” at posedge of CLK2; at the same time posedge of CLK1 is triggered ; is it possible that CLK1 module will read updated value of A ; as although their posedge matches, both are working on different clock domain?
Is it race condition for simulator ? If yes can you explain why?

There are no race conditions when you use non-blocking assignments. Depending on how the clock generators are coded, you will either always get the previous value, or always get the updated value. As long the edges of the two clocks are scheduled in the same event region, you will always read the previous. That means there can be no delays (procedural or structural) or NBA updates between them. That is why we recommend using only blocking assignment in clock generator for pure RTL simulation.

The rule for when to use non-blocking assignments should is more clear stated as

To avoid race conditions, always use an NBA to write to a signal when another process is reading that signal synchronized to events in the same active region.

As long as no other process will try to read the value of clk1 on the posedge of clk2, you can use a blocking assignment to clk1.

always @(posedge clk2)
     clk1 = !clk1; // do not use NBA

However, if you did use an NBA to assign to clk1, you will always get the updated value of ‘a’.

In reply to dave_59:

Hi Dave,
Thank you for the explanation.

However i have a doubt regarding the last point that you mentioned that if i use NBA for clock generation;
i.e.
always@(posedge clk2)
clk1 <= ~clk1;

& the other always block which is driving a;
i.e.
always@(posedge clk2)
a<=1’b1;

Also
i.e.
always@(posedge clk1)
if(a==1)

as both blocks will be triggered at same time ; is it not possible that one always block may execute early which leads to unexpected outcome?
read block
if two events that are being executed parallel at same time(as clk1 generation is in NBA region , always block with @(posedge clk1) will be triggered in NBA region, also value of a is scheduled in NBA region) so one block is driving a signal that is read in other block in that region ; will it be not on simulator to decide to execute which block first? (although when i tried the NBA i always got updated value, but i didn’t get it why!)

In reply to ridham:

Hi Ridham,

Let me explain you why you will always get updated value.

  1. “clk1” is updated in nba region of 1st time slot.
  2. “a” is also being updated in nba region of 1st time slot.
  3. “if” statement comes in active region set.
    Now as “if” statement got hit in nba because of waiting on nba event(clk1).
    So as per 3rd point one need to reiterate to active region of 1st time slot.
    By that time nba region value of variable “a” is updated and hence you will get always updated value.

I would like Dave to comment if my understanding is wrong.