Resolving Race Condition

Hi,
I am trying to understand behaviour of simulation and resolve the race condition for following code snippet:


	
wire pclk;
wire [31:0] reg_check;
reg [31:0] reg_check_ref = 32'h0;
wire reg_check_en;
	   	
assign reg_check = {PWDATA_FROM_DESIGN}  //Concatenation of some signals to compare

always @ (posedge pclk) begin
	if ( SOME_TRIGGER_SIGNAL == 32'h123) begin
		reg_check_ref <= pwdata;        // LINE-X
	end 	
end

property myproperty;
    @(posedge pclk) disable iff (~reg_check_en)
        reg_check == reg_check_ref;             // LINE-Y
endproperty

myproperty_assert : assert property(myproperty) else begin
   $warning("myproperty failed");
end


myproperty_assert is failing due to the fact that when LINE-Y is executed, assignment of reg_check_ref in LINE-X is not executed prior to it, given SOME_TRIGGER_SIGNAL was 'h123 in previous clock cycle. I want to make sure that “reg_check_ref” is updated before LINE-Y is executed. Any suggestions to resolve this?

I am learning SV and any help much be appreciated.

Thanks.

In reply to stupidkris1010:

You can end up in race conditions, if you are mixing up signals from TB & DUT and using them in assertions.

Could you give more details of what reg_check_en, SOME_TRIGGER_SIGNAL, pclk are? Are you also assigning the DUT values like you did for reg_check? Or, are they generated with in testbench?

In reply to S.P.Rajkumar.V:

Hi, thanks for feedback. Sorry for not providing entire code. Here’s the explanation for these signals:

  • pclk: reference clock of APB interface from DUT
  • reg_check_en : trigger signal from TB, this is getting high for one clock cycle after every 7 posedge of pclk
  • SOME_TRIGGER_SIGNAL: combination of APB interface signals from DUT to catch write transaction

Thanks.

In reply to stupidkris1010:

Why dont you disable property when SOME_TRIGGER_SIGNAL != 32’h123?


property myproperty;
    @(posedge pclk) disable iff (~reg_check_en || (SOME_TRIGGER_SIGNAL != 32’h123))
        reg_check == reg_check_ref;
endproperty
 

In reply to cuonghl:

Hi Chris,
I think that would not resolve the problem. Let’s say, LINE-X would get executed in cycle N. Simulator would schedule this NBA event for cycle N+1. Now considering that “reg_check_en” is scheduled to be high in cycle N+1 before “reg_check_ref” is schedule, then this would not work. Cheers.

In reply to stupidkris1010:

In reply to cuonghl:
Hi Chris,
I think that would not resolve the problem. Let’s say, LINE-X would get executed in cycle N. Simulator would schedule this NBA event for cycle N+1. Now considering that “reg_check_en” is scheduled to be high in cycle N+1 before “reg_check_ref” is schedule, then this would not work. Cheers.

I’m not sure I fully understand this explaination. I guess you were talking the delay of reg_check_ref 1 cycle after SOME_TRIGGER_SIGNAL equal 32’h123, right?

Here is some updates:


wire trigger_en;
reg trigger_en_dly;

assign trigger_en = (SOME_TRIGGER_SIGNAL == 32'h123);

/* The trigger_en_dly will delay 1 cycle after trigger
   That mean reg_check_ref is updated at same clock as trigger_en_dly */

always @(posedge pclk or negedge presetn) begin
  if(!presetn) 
    trigger_en_dly <= 1'b0;
  else 
    trigger_en_dly <= trigger_en;
end

/* The propery is enable when trigger_en_dly asserted */
property myproperty;
  @(posedge pclk) disable iff (~reg_check_en || ~trigger_en_dly)
  reg_check == reg_check_ref;
endproperty

In reply to cuonghl:

Thanks, this suggestion was helpful.