‘when others=>’ is a beast by itself. As VHDL was not designed specifically for synthesis of binary logic but for behavior simulation of hardware, ‘when others=>’ just means: any of the official states not yet mentioned. There is no notion of: any unencoded state the implemented registers might take. I would call this a ‘when unencoded_state =>’ – a feature of VHDL still to be specified.
So, currently, if you have an enumerated type with, say, 5 states, and the state is encoded as 3 registers, and you have all 5 states already checked with matching ‘when s1|s2|s3|s4|s5 =>’, then a final ‘when others =>’ will formally be a NOP. And, although formally allowed, this superfluous statement will typically raise a warning when compiling for simulation. Remember: Superfluous warnings are *bad*.
There are, however, synthesis tools which do their own special interpretation of ‘when others =>’ for the developer’s good, trying to mimic the missing ‘when unencoded_state =>’ feature. Set up for this behavior, they take a written ‘when others =>’ as an unwritten ‘when others | unencoded_state =>’. So they would decode the 3 unencoded states – or even the 27 unencoded states if one-hot encoding was used – and help mitigating such detected soft errors.
Contrary, the coding style, which I adhere to, states:
never use a ‘when others=>’. This is for requiring the programmer to always decode all (official) states explicitly in the case’s when list. If any element from the enumerated type is missing, simulation and synthesis will error out. This is *good*. Hiding an actually missing element by using ‘when others=>’ is *bad*. It will take you ages to find out why one case was missing the new
when check, while in absence of ‘when others=>’ you are quickly pointed to code that still needs adaption. This is no silver bullet, though.
So what I’d like to see is the ‘when unencoded_state =>’ feature added to VHDL. This way I could write code like the following, assuming state is of an enumerated type (s1, s2, s3, s4, s5):
case state is
when s1 => something;
when s2|s3 => something_different;
when s4|s5 => also_needed;
-- fallback for invalid/unexpected states, request reset. no when others needed.
when unencoded_state => state <= s1; request_reset <= '1';
end case;
BTW: Most applications might be happy by just detecting an invalid transition into an
invalid state. But if you consider carefully, there are most likely quite some invalid transitions possible that lead to another
valid state. Still, the transition is invalid and, by no means, ‘when others=>’ will be able to help you with those. You can only detect them by some register duplication or checksumming, and mitigation might require something like register-based TMR. Still one should consider that most faults in digital design are
designed-in, like inter-statemachine race conditions and faults propagating into the design from the external interfaces. Once you have done your best to avoid design-time faults, you can think over long-term stability and handling of unadvertantly entered states. Taking ‘when others=>’ as a silver bullet just hides the fact that you have no clue how to deal with inadvertant state changes to valid states.
About the reset: Have you mentioned that register initialization actually works with some current FPGA synthesis tools? So even without a reset pin your design will start in a defined state, without the assumption of an initial ripple state initialization. It’s just the case that sometimes the synthesis tool is just not able to initialize the register in the requested way, so you have to watch out for related warnings.
Not including signals on the sensitivity list will typically not harm your design at all, but this depends on the ‘intelligence’ of the synthesis tool. Only simulation will show the behavior of a latch, while synthesis tools assume all signals to be on the sensitivity list. But I agree, it is best practice to put all related signals on the sensitivity list if you want to have the same behavior in simulation and after synthesis. Just found that (
http://vhdlguru.blogspot.com/2010/04/process-sensitivity-list-vs-synthesis.html). BTW, huge numbers of discrete signals within a single architecture and on its entity’s interfaces sooner or later lead to this missing signal problem. The answer to this problem space is, again, coding style, and I would strongly recommend reading (and adhering to) this (
http://www.gaisler.com/doc/vhdl2proc.pdf).
OTOH, here is a theoretical counter example: if there’ll ever be a synthesis tool capable of synthesizing something like a dual-edged flip-flop – which could already exist if the functionality was mitigated over some added logic and two alternately-clocked flip-flops per register – one could write code like the following:
process(clk)
r_prsnt <= r_next;
end process;
This code is perfectly describing a dual-edge triggered flip-flop. If the synthesis tool would not honor the sensitivity list – especially when adding r_next to it – the result would be a straight wire connection. In this case one would be able to restore the behavior by explicitly requiring rising/falling edges:
process(clk)
if rising_edge(clk) or falling_edge(clk) then
r_prsnt <= r_next;
end if;
end process;
– Matthias
Edit:fixed link