Author Topic: Cant find the latch in my state machine  (Read 2589 times)

0 Members and 1 Guest are viewing this topic.

Offline DmeadsTopic starter

  • Regular Contributor
  • *
  • Posts: 164
  • Country: us
  • who needs deep learning when you have 555 timers
Cant find the latch in my state machine
« on: October 10, 2020, 12:45:07 am »
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
 

Offline DmeadsTopic starter

  • Regular Contributor
  • *
  • Posts: 164
  • Country: us
  • who needs deep learning when you have 555 timers
Re: Cant find the latch in my state machine
« Reply #1 on: October 10, 2020, 02:28:10 am »
I found it!

this link helped me understand latches in state machines better even though my code is verilog and the link is vhdl
https://stackoverflow.com/questions/33279873/why-am-getting-inferred-latches

I rewrote the always block that defines the case statements for the FSM and clocked the block. works great now :)
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: Cant find the latch in my state machine
« Reply #2 on: October 11, 2020, 06:21:15 pm »
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: [Select]
    process(State, BEN, IR,MemReady, Immediate, PSR, Interrupt)
    begin
        -- set default values for all signals
        GateBusSelect   <= GatePC;
        MIOenable       <= '0';
        LD_MAR          <= '0';

[/font]

Later on in the state machine, various states may manipulate those signals:

Code: [Select]
        case State is
...
...
            when  2     =>  -- LD Instruction
                            Addr1Select     <= Addr1PC;
                            Addr2Select     <= Addr2Sext9;
                            MARselect       <= MARadder;
                            GateBusSelect   <= GateMARmux;
                            LD_MAR          <= '1';
                            NextState       <= 25;
[/font]

Other states that don't involve LD_MAR need not mention it.

 
The following users thanked this post: Dmeads

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15275
  • Country: fr
Re: Cant find the latch in my state machine
« Reply #3 on: October 25, 2020, 04:27:27 pm »
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: [Select]
process (Clk)
begin
    if rising_edge(Clk) then
        if En = '1' then
            Q <= D;
        end if;
    end if;
end process;

Code: [Select]
process (En, D)
begin
    if En = '1' then
        Q <= 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.

« Last Edit: October 25, 2020, 04:49:26 pm by SiliconWizard »
 
The following users thanked this post: Dmeads

Offline DmeadsTopic starter

  • Regular Contributor
  • *
  • Posts: 164
  • Country: us
  • who needs deep learning when you have 555 timers
Re: Cant find the latch in my state machine
« Reply #4 on: October 27, 2020, 04:55:53 am »
Yep, I rewrote the code using a "single process style" because I like that better as well, and it went away. Thanks
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15275
  • Country: fr
Re: Cant find the latch in my state machine
« Reply #5 on: October 27, 2020, 03:36:53 pm »
Yep, I rewrote the code using a "single process style" because I like that better as well, and it went away. Thanks

Cool, 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: [Select]
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.
« Last Edit: October 27, 2020, 04:01:45 pm by SiliconWizard »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf