Forum Discussion

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

Help with latches but can't figure out why after several checks

Hi all can someone figure out why this code gives the following error in Quartus II (vs 13):

It's about finite state machines with keys, ledG, ledR and 5 states (opened, closed, locked, unlocked, error):

Here comes the code:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

entity VHDL_uppgift_4c is

port (

clk : in std_logic; -- sync clock signal

reset_n: in std_logic; -- async reset signal

key_0 : in std_logic; -- door open input button

key_1 : in std_logic; -- door closing button

key_2 : in std_logic; -- button pressed and door locks

key_3 : in std_logic; -- button pressed and lock opens

LED_out: out std_logic_vector(1 downto 0);

LED_R: out std_logic_vector(2 downto 0)

);

end VHDL_uppgift_4c;

architecture final_syn of VHDL_uppgift_4c is

type state_type is (closed, opened, locked, unlocked, error); -- register to hold current state

signal current_state, next_state : state_type; -- defination of register of inner states

-- state register

begin

process (clk, reset_n)

begin

if reset_n = '1' then -- async reset of machine

current_state <= closed; -- default state after reset

elsif (rising_edge(clk))then -- sync part of machine

current_state <= next_state;

end if;

end process;

process(current_state, key_0, key_1, key_2, key_3)

begin

case current_state is

when closed =>

if key_0 = '1'then

next_state <= opened;

LED_out <= "00";

else

next_state <= closed;

LED_out <= "01";

end if;

when opened =>

if key_1 = '1' then

next_state <= locked;

LED_out <= "10";

else

next_state <= opened;

LED_out <= "11";

end if;

when locked =>

if key_2 = '1' then

next_state <= unlocked;

LED_R <= "000";

else

next_state <= locked;

LED_R <= "001";

end if;

when unlocked =>

if key_3 = '1' then

next_state <= unlocked;

LED_R <= "010";

else

next_state <= error;

LED_R <= "110";

end if;

when error =>

if key_3 = '1' and key_0 = '1' then

next_state <= error;

LED_R <= "101";

else

next_state <= opened;

LED_R <= "111";

end if;

--when others =>

--next_state <= error;

end case;

end process;

end final_syn;

--------------------------------------------------------------------------

Error message reads:

Warning (10631): inferring latch(es) for signal or variable "LED_out", which holds its previous value in one or more paths through the process

Warning (10631): inferring latch(es) for signal or variable "LED_R", which holds its previous value in one or more paths through the process

____---------------------------

Thanks for helping out

4 Replies

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

    There are cases in your code where LED_out retains the previous value.

    To avoid latches you need to always give LED_out a value that depends only on the process inputs (state, key*).

    If you need LED_out to have memory, make it a flip-flop.

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

    --- Quote Start ---

    There are cases in your code where LED_out retains the previous value.

    To avoid latches you need to always give LED_out a value that depends only on the process inputs (state, key*).

    If you need LED_out to have memory, make it a flip-flop.

    Same for LED_R

    --- Quote End ---

    ----------------------------------------

    Thanks for your quick reply rbugalho,

    I am a beginner to vhdl, please an example will help me understand what you mean better.

    Just one will do, thanks
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In an async process, all signs must be assigned in ALL branches. In your code, LED_out is only assigned in the closed and opened states - it must also be assigned in all of the other states.

    The way to avoid this is assign all signals in an asynchronous process a default value before the case statement. This way, if it is not assigned a specific value in a branch, it will take the default assignment.

    
    process(state)
    begin
      output <= '0';  --default assignment
      case state is
        when state1 =>
          --do something
          --no assignment to output means it will be '0';
       when state2 => 
         output <= '1';   --overrides default assignment
      
      when state3 =>
        --no output assignment, output is '0' again
      end case;
    end process;
    

    This way latches are avoided.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    In an async process, all signs must be assigned in ALL branches. In your code, LED_out is only assigned in the closed and opened states - it must also be assigned in all of the other states.

    The way to avoid this is assign all signals in an asynchronous process a default value before the case statement. This way, if it is not assigned a specific value in a branch, it will take the default assignment.

    
    process(state)
    begin
      output <= '0';  --default assignment
      case state is
        when state1 =>
          --do something
          --no assignment to output means it will be '0';
       when state2 => 
         output <= '1';   --overrides default assignment
      
      when state3 =>
        --no output assignment, output is '0' again
      end case;
    end process;
    

    This way latches are avoided.

    --- Quote End ---

    -------------------------------------------------------

    Hi Tricky, thanks for the tips it worked. Wow!! you guys are good, but i got another hitch can figure out what happened:

    Error message when i tried the second time to compile it:

    Error (125048): Error reading Quartus II Settings File C:/altera_trn/VHDL_uppgift_4e/VHDL_uppgift_4e.qsf, line 41

    Info (125063): set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME "VHDL_uppgift_4e_vhd_tst " -section_id "VHDL_uppgift_4e_vhd_tst "

    Error (125022): Section identifier missing or not required

    Info (125063): set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH "VHDL_uppgift_4e_vhd_tst -section_id eda_simulation"

    Info (125063): set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH "VHDL_uppgift_4e_vhd_tst " -section_id eda_simulation

    Error (125022): Section identifier missing or not required

    Info (125063): set_global_assignment -name EDA_TEST_BENCH_NAME "VHDL_uppgift_4e_vhd_tst -section_id eda_simulation"

    Info (125063): set_global_assignment -name EDA_TEST_BENCH_NAME "VHDL_uppgift_4e_vhd_tst " -section_id eda_simulation

    Error (125080): Can't open project -- Quartus II Settings File contains one or more errors

    Error: Quartus II 64-Bit Hierarchy Elaboration was unsuccessful. 4 errors, 0 warnings

    Error: Peak virtual memory: 381 megabytes

    Error: Processing ended: Thu Dec 12 12:47:21 2013

    Error: Elapsed time: 00:00:00

    Error: Total CPU time (on all processors): 00:00:00

    Is there a file i might not have added to settings > files > at the moment i just have the VHDL in place