Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

inferred latches in state machine \ general VHDL

hi all

the state machine below is part of a windowing function.

It all builds OK, but I get a lot of..

Warning (10631): VHDL Process Statement warning at window.vhd(103): inferring latch(es) for signal or variable "PacketIndex", which holds its previous value in one or more paths through the process

..

is it just a matter of having an assignment in every state? even when there's nothing to do? like PacketIndex<=PacketIndex ? would things like that get optimised out by the synthesiser?

main : process (StateMachine,StartWindow,TheInput,HannTable,PacketIndex,result,resultlv)

begin

case StateMachine is

when newpacket =>

PacketIndex <= 0;

NextState <= idle;

when idle =>

if (StartWindow = '1') then

NextState <= load;

else

NextState <= idle;

end if;

when load => --another surplus state

NextState <= math1;

when math1 =>

result <= TheInput*HannTable(PacketIndex);

NextState <= math2;

when math2 =>

resultlv <= std_logic_vector(to_signed(result,22));

NextState <= math3;

when math3 =>

realout <= resultlv(21 downto 6);

NextState <= math3;

PacketIndex <= PacketIndex+1;

when strobehigh =>

realoutstrobe <= '1';

NextState <= wait1;

when wait1 =>

NextState <= wait2;

when wait2 =>

NextState <= strobelow;

when strobelow=>

NextState <= waitend;

realoutstrobe <= '0';

when waitend =>

if (PacketIndex = 64) then

PacketIndex <= 0;

NextState <= idle;

elsif (StartWindow = '0') then

NextState <= idle;

PacketIndex <= PacketIndex;

else

NextState <= waitend;

PacketIndex <= PacketIndex;

end if;

when others =>

NextState <= idle;

PacketIndex <= 0;

end case;

end process;

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You should avoid latches. If you have to keep a value then use clocked register for that.

    In your case you can add default statement at start e.g.

    packet_index <= '1'; -- default

    case state is

    ......
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I assume this is the asynchronous process from a 2 process state machine? the easiest way to avoid latches is to add defaults like kaz suggested or even better, move to a single process state machine as its impossible to get latches.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Kaz,Tricky

    thanks again for that, great help,

    so an assignment at top, outside of the case would fix that,

    but I do need to keep the value/s

    so, as always seems to be the answer, wrapping the whole thing in the clock edge will be best ?

    I can't help thinking in software and want to use a variable to back up and restore! will I ever be free of that mind set?

    the phrase '2 process state machine' directed further study, I found this paper

    http://users.utcluj.ro/~baruch/media/ssce/labor/state-machines.pdf

    which covers state machines in general, but very much in the context of VHDL . I would reccomend a read for beginners looking at state machines

    Thanks again for your help

    Pete B.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    so just to close this thread off,

    A single process version is this:

    --*****************************************************

    main : process (clock,StateMachine,StartWindow,TheInput,HannTable,PacketIndex,result,resultlv)

    begin

    if rising_edge(clock) then

    if(reset='1') then

    StateMachine <= idle;

    else

    case StateMachine is

    when newpacket =>

    PacketIndex <= 0;

    StateMachine <= idle;

    when idle =>

    if (StartWindow = '1') then

    StateMachine <= load;

    else

    StateMachine <= idle;

    end if;

    when load => --another surplus state

    StateMachine <= math1;

    when math1 =>

    result <= TheInput*HannTable(PacketIndex);

    StateMachine <= math2;

    when math2 =>

    resultlv <= std_logic_vector(to_signed(result,22));

    StateMachine <= math3;

    when math3 =>

    realout <= resultlv(21 downto 6);

    StateMachine <= math3;

    PacketIndex <= PacketIndex+1;

    when strobehigh =>

    realoutstrobe <= '1';

    StateMachine <= wait1;

    when wait1 =>

    StateMachine <= wait2;

    when wait2 =>

    StateMachine <= strobelow;

    when strobelow=>

    StateMachine <= waitend;

    realoutstrobe <= '0';

    when waitend =>

    if (PacketIndex = 64) then

    PacketIndex <= 0;

    StateMachine <= idle;

    elsif (StartWindow = '0') then

    StateMachine <= idle;

    PacketIndex <= PacketIndex;

    else

    StateMachine <= waitend;

    PacketIndex <= PacketIndex;

    end if;

    when others =>

    StateMachine <= idle;

    PacketIndex <= 0;

    end case;

    end if;

    end if;

    end process;

    --*****************************************************

    --

    so thanks again Kaz and Tricky

    It all seems obvious once you know
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thats much better, but to fully tidy it up, you now only need clock in the process sensitivity list.