0
votes

I wrote a piece of code to assert a signal (val_changed) synchronously when another 64-bit signal (val) changes value by more than a threshold. Later this signal need to be de-asserted based on a third signal's (adj_in_prog) negedge.

Here clk and val are inputs to the block.

logic [63:0] val_reg;

 always @(posedge clk) begin
    val_reg <= val;
 end

 always @(posedge clk) begin
    if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
          val_changed <= 1'b1;
    @(negedge adj_in_prog);
    val_changed <= 1'b0;
 end

I understand that the above method is not the cleanest of ways to do it, but since this is test-bench code and so I don't need to synthesis this, thought of experimenting. But this code is not working as val_changed is not going 1. I would like to know why the if loop won't execute. As per me, val_changed should have gone high at the clock edge where marker is positioned in the waveform attached. Can someone please help? (waveform values are in hex)

waveform (values in hex)

1
@(negedge adj_in_prog) is outside the if statement. Not sure why you have that statement as it is not synthesizable and blocks detection of future posedge clk - Greg
can you add the trace of the adj_in_prog? now remember that the second always block will not execute second time till you get the negedge of adj_in_prog. it will stay there and will not re-enter. - Serge
@Greg adj_in_prog is a signal I know for sure would go up and come down atleast once after val_changed becomes 1, hence it is outside if loop. What I want to achieve is : Diff goes above threshold-> val_changed gets 1-> wait till negedge of adj_in_prog -> val_changed gets 0. I don't mind missing furture posedge clk once val_changed is 1. In fact, I don't want posedge clk detection when val_changed is 1. - thorondor1990
@Serge adj_in_prog remains low through out the waveform window I pasted above. This signal goes high sometime later in the simulation, once the abrupt change in val signal reaches a block inside design after a few cycles. Thanks for pointing out about control not re-entering always block till negedge of adj_in_prog, but that is exactly what I intent. - thorondor1990
@thorondor1990 so, at the very first posedge of clk it started waiting for the adk_in_prog to become 0 after it was non-zero. But this is not happening during your window. So, val_changed will never become '1'. Actually the 'if' statement will be executed only once at the first time. It will be ignored for all clock cycles till you get the negedge of the signal. - Serge

1 Answers

1
votes

in your case at the very first posedge of clk the second always block starts executing and processes the 'if' statement. Then it sticks at the @(negedge adj_in_prog) statement, waiting for the event. On the next clock edge it will continue waiting and will not re-enter and evaluate the 'if' statement, and so on. So, this explains why it is not progressing.

so, assuming that the adj_in_prog is turned on at val_changed changing to one, the following should work for you.

always @(posedge clk) begin
    if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
      val_changed <= 1'b1;
    else if (!adj_in_prog);
      val_changed <= 1'b0;
end