Synthesizing combinational logic from a VHDL process is generally a piece of cake. Occasionally, though - and the more complex the process in terms of nested control structures, the more often it seems to happen - D-type latches are synthesized on the output signals of the combinational logic.
Let's nip this problem in the bud once and for all. In the combinational process below, all seems well. next_state transitions from IDLE to INITIAL providing a is logic 0 and then passes through states SCANNING, LOCKED, TIME_OUT and RELEASE before passing back to IDLE.
-- next state logic for a FSM process (state, a, b, c, d, e) begin case state is when IDLE => if a = '0' then next_state <= INITIAL; end if; when INITIAL => if a = '1' then next_state <= ERROR_FLAG; else next_state <= SCANNING; end if; when SCANNING => if b = '1' then next_state <= LOCKED; elsif b = '0' then if c = '0' then next_state <= TIME_OUT; else next_state <= RELEASE; end if; else next_state <= CAPTURE; end if; when CAPTURE => next_state <= ... when LOCKED => next_state <= ... when TIME_OUT => next_state <= ... when RELEASE => next_state <= ... when ERROR_FLAG => next_state <= some_function(a, d, e); end case; end process;
The problem is that if a is not logic 0 when state is IDLE, then the next_state output must hold onto its previous value, implying a latch. In synthesis jargon, this scenario is referred to as incomplete assignment.
OK, that's the problem. Here's the simple solution...
Create a default assignment to every variable and signal in the process before any of the normal functional code in the process. This ensures that even if you miss out an assignment because you get ‘lost' in the depth of your nested control structure jungle, you won't get any unexpected latches. In the example above, the fix is easily applied.
-- next state logic for a FSM process (state, a, b, c, d, e) begin next_state <= IDLE; case state is when IDLE => if a = '0' then next_state <= INITIAL; end if; when INITIAL => ... ...
Now, the macho solution is to make sure you always write code in combinational processes with default assignments by always implementing conditional code structures with default branches (else for if statements, when others for case statements). This can be made easier (and thus less macho?) by structuring the process in the first place, using subprograms to alleviate complex control structures and also adopting the destination assignment design philosophy. Well, that's three tips in one!
Your e-mail comments are welcome - send email
Copyright 1995-2002 Doulos