Electronic – preferred order VHDL case/when and rising/falling_edge statements in processes

vhdl

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 )=>
...

Best Answer

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.