What pitfalls are there in putting my rising_edge check within a case/when block?

I have VHDL that uses code similar to the first example below and simulates correctly and is synthesizable. However, it is not behaving in accordance with the simulation.

process ( clk_in, rx0_busy, reset_n, spi_cs_n, spi_sclk, tx_state )

begin   
    case tx_state is
        when ( RESET )=>
            if ( rising_edge( clk_in ) ) then 
...

Is it better form to write VHDL more like below, with the clock edge driving the case/when? If so, why?

process ( clk_in, rx0_busy, reset_n, spi_cs_n, spi_sclk, tx_state )

begin   
    if ( rising_edge( clk_in ) ) then 
        case tx_state is
             when ( RESET )=>
...
  • Synthesis is based on pattern matching. If you don't use the right pattern, the "compiler" can not translate to the right hardware primitives like registers with synchronous reset. Alternatively, the synthesizer might translate strange conditions to gated clocks, which are not intended in most cases. – Paebbels Nov 10 at 13:18
up vote 2 down vote accepted

These are two different circuit description:

In the first assume the mux1 gets an asynchronous tx_state signal in the first and then evaluated with a synchronous system(REG1)

The second, in rising edge of the clock every input evaluated, then feed to a multiplexer. In this case, mux4 has ~1/clock_speed time to evaluate the output.

schematic

simulate this circuit – Schematic created using CircuitLab

The implementation difference!

if you implement the first one, for instance, assume you have a "data_from_pin" then the compiler should care about delay(delay between data_from_pin and tx_state and ...), The compiler knows the tx_state pin is asynchronous and may change before clock edges multiple of time, the timing of system should be exactly true.

The first circuit generates many timing constraints and warning for mapping and place and route,

But the second circuit knows every timing of output is based on an old clock and all inputs are stable for evaluation of new state machine.

  • I saw condition, even a signal is asynchronous, but if the compiler knows that the signal generated from a synchronous system, evaluate it as the second circuit.(Xilinx ISE). But it's better to describe the circuit carefully. – M KS Nov 8 at 21:58

While the first example may be syntactically correct, I have never seen clock logic enclosed within anything other than an IF/ELSE that selects between reset and clock.

It is far better from a readability standpoint to have an "if rising_edge" enclosing all of the synchronous logic for the process, so that you can immediately tell that it is indeed synchronous.

Also, your sensitivity list only needs to include the clock input, since if it's truly a synchronous system all of the other variables only matter when the clock changes. If the process needs an asynchronous reset, then the reset must also be in the sensitivity list.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.