Pergunta

Wondering about the behavior of event control statements in an always block:

always @(posedge clk) begin: TEST
    ...
    @(wait_for_signal_from_subsystem);
    ... 
    @(wait_for_another_signal_from_subsystem);
    ...
end

Will the process be "stuck" until the event signals come in, or will it restart every time a clk edge comes in ?

Also is this synthesizable (Quartus II says yes, but not simulated yet...) ? and is this a good practice or is there an alternative better approach to this problem ?

Foi útil?

Solução

Yes, it is 'stuck' as you would say. Only one 'loop' of the block can be active at a time, it will not reenter if it has not completed the loop.

The thing you are trying to do there is likely not synthesizable, due to the wait operations inside the block.

I don't know the exact specifics of your design, but I would approach this with a small finite state machine. I assume that the signals from your subsystem are not faster than the clock, so it would look something like:

always @* begin
  if(state_f == `WAIT_FOR_FIRST) 
       state_nxt = got_first_signal ? `WAIT_FOR_SECOND : `WAIT_FOR_FIRST;
  else if(state_f == `WAIT_FOR_SECOND)
       state_nxt = got_second_signal ? `DONE_STATE : `WAIT_FOR_SECOND;
  else if(state_f == `DONE_STATE) 
       state_nxt = `WAIT_FOR_FIRST;
  else
       state_nxt = 2'bxx;
end

always @(posedge clk) begin
    state_f <= state_nxt;
end

Outras dicas

Assuming you are designing hardware and not non-synthesized testbench code, this not a good practice and likely won't do what you want anyways.

From a language perspective, this will compile and simulate. It will block waiting on the events within the always blocks and NOT restart on each posedge of the clock. I could not find a spec reference for this but it's what I observed in simulation. I'm curious what this would synthesize to if you even get it to synthesize with no errors.


If the signal from the other subsystem is already in the same clock domain (synchronous to clk), then you can just check the state of it on each clock edge, and use this do something.

always @(posedge clk) begin: TEST
  if (the_other_signal == 1'b1) begin
    ...
  end
end

Some other things to consider:

  • Maybe you only care about when the signal assert/deasserts. In that case you need to do an edge detection.
  • If the signal is asynchronous to clk, then you have a clock domain crossing and you need to synchronize the incoming signal before you look at it.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top