Cant find the latch in my state machine - Page 1
Forum section: electronics / general

author: Dmeads
author_rank: Regular Contributor
timestamp: October 10, 2020, 12:45:07 am
content: Happy friday from the US!I am coding this moore machine for an input sequence of buttons on my board. if the correct sequence is entered, and you hit the "enter" button, a blue LED will light for 0.5 seconds, if the incorrect sequence is entered, or if midway through entering the sequence the "enter" button is hit, a red LED will light for 0.5 seconds.Vivado synthesis is inferring latches for both the rLED_time_EN and bLED_time_EN, which allow the lights to come on for 0.5 seconds. When i program this down to the board, the lights just stay on forever (not surprising because they are latched).Can anyone identify how I can fix this please? I have tried many different if and else statements within the state, but I cannot get it to work! (code in zip file)Thanks,-Dominic

author: Dmeads
author_rank: Regular Contributor
timestamp: October 10, 2020, 02:28:10 am
content: I found it!this link helped me understand latches in state machines better even though my code is verilog and the link is vhdlhttps://stackoverflow.com/questions/33279873/why-am-getting-inferred-latchesI rewrote the always block that defines the case statements for the FSM and clocked the block. works great now

author: rstofer
author_rank: Super Contributor
timestamp: October 11, 2020, 06:21:15 pm
content: This is part of a much larger issue: All output signals from an FSM must be defined under all conditions. Even when the selected case doesn't even involve the signal.Well, it just isn't possible to define 50 or 60 signals in each of 100+ states. So, right ahead of the 'case' statement, you provide default output values for every signal. And when you add another signal, you will forget to provide the default value until you once again get warned about latches.There's a reason I know this...Here is a short sample of defining default values before the case statement:Code:process(State, BEN, IR,MemReady, Immediate, PSR, Interrupt)begin-- set default values for all signalsGateBusSelect <= GatePC;MIOenable <= '0';LD_MAR <= '0';Later on in the state machine, various states may manipulate those signals:Code:case State is......when 2 => -- LD InstructionAddr1Select <= Addr1PC;Addr2Select <= Addr2Sext9;MARselect <= MARadder;GateBusSelect <= GateMARmux;LD_MAR <= '1';NextState <= 25;Other states that don't involve LD_MAR need not mention it.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 25, 2020, 04:27:27 pm
content: Remember that these "unwanted latch" issues only pertain to non-clocked processes.In a purely clocked process, any signal that is not assigned a value under some condition will just hold its previous value - in a register. Registers in this context are not made of latches, and they cause no particular issue (as long as holding the previous value is indeed what was intended of course.)In a non-clocked process, that's different and yes, it will infer latches. That's an interesting, and often overlooked topic.Typical examples:Code:process (Clk)beginif rising_edge(Clk) thenif En = '1' thenQ <= D;end if;end if;end process;Code:process (En, D)beginif En = '1' thenQ <= D;end if;end process;The first one causes no issues and infers no latch. It's even pretty common. It will just infer a register.The second one will infer a latch, and can cause all sorts of timing issues, especially on FPGAs.So back to FSMs, inferred latches can only happen if you use the typical 2-process (or more) style (which I personally don't like, but there was another thread about this all, so let's not start it all over again, you can refer to it instead), with typically the states handled in a non-clocked process (or several), and one clocked process that handles state change.

author: Dmeads
author_rank: Regular Contributor
timestamp: October 27, 2020, 04:55:53 am
content: Yep, I rewrote the code using a "single process style" because I like that better as well, and it went away. Thanks

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 27, 2020, 03:36:53 pm
content: Quote from: Dmeads on October 27, 2020, 04:55:53 amCool, but I still want to emphasize the issue, because it's much more general than just applied to FSMs. And whereas I personally prefer the one-process style for FSMs, I do not like silver bullets. I do this because I find it easier to read and easier to maintain, not to avoid potential inferred latches. I guess you were mostly looking for a fix for your problem, but this raised an issue that, I think, is interesting and worthwhile to understand.It's much more general than with just FSMs. Non-clocked processes have their uses, and the potential issue is still the same.Actually, it can happen OUTSIDE of processes as well. Any conditional concurrent statement can lead to inferred latches if not all cases are covered, and this happens more often that one may think, especially when the number of conditions goes over 2 or 3.Example (concurrent statement outside of a process):Code:Q <= A when EnA = '1' else B when EnB = '1';You get an inferred latch, because Q must hold its value if neither EnA or EnB is '1'.Another worthy note (IMO) is that, it may be unintentional - which means you just forgot to cover a case - but it may also be intentional. You may actually WANT Q to retain its state if neither EnA or EnB is '1'. Problem is, if you do this outside of a clocked process, you'll get a latch, as this can't be implemented any other way. And latches can cause nasty issues, especially again on FPGAs.You may think the "fix" would just be to do this in a clocked process. Sure, but the behavior would NOT be the same. Assuming all signals *are* in the same clock domain, by putting this in a clocked process, you get a 1-cycle delay. Definitely not the same. And If all signals are NOT in the same clock domain, you'd get metastability issues. Crap. So if you were in the former case and didn't want a 1-cycle delay, you'd have to take another approach for implementing this reliably. Or master the tricky art of latches, which uh... is tricky.A final note: sometimes you can hear of "synchronous" vs "asynchronous" processes when I prefer to say "clocked" and "non-clocked". My rationale is that the former isn't quite right IMHO. A non-clocked process can actually be fully synchronous if all signals in it are synchronous AND there is no inferred latch (latches are, per nature, not synchronous). Likewise, a clocked process using some signals that are in a different clock domain is NOT fully synchronous, and you should usually avoid doing this, except strictly for resynchronizing signals. Yet another topic. Hence why I prefer "clocked" and "non-clocked".And to illustrate this, back to the original topic, as long as all cases are covered and there is not inferred latch, in the two-process approach for FSMs, the non-clocked process is not per se "asynchronous". At least this is how I see it.