Question

Iam making the code for a secuential tail lights for a mustang, but iam getting a latch with Llights and Rlights. According to my logic there should be no problem.

----------------------------------------------------------------------------------
-- Company:        Pony incorporated
-- Engineer:       Pony
-- 
-- Create Date:    17:41:27 10/23/2013 
-- Design Name: 
-- Module Name:    Mustang_FSM - Behavioral 
-- Project Name: 
-- Target Devices: Spartan 6 (Nexys 3 Digilent board)
-- Tool versions:  ISE Webpack v14.6
-- Description:    Using a Moore FSM, define the sequential tail
--                 lights found on a Ford Mustang. Look at the
--                 following video:
--                 https://www.youtube.com/watch?v=KVFA-HuikfY
-- Dependencies:   None
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: The realization of the Moore FSM is based
--                      on the template described by your teacher
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Mustang_FSM is
    Port ( Lturn     : in   STD_LOGIC;
           Rturn     : in   STD_LOGIC;
           Hazard    : in   STD_LOGIC;
           Rst       : in   STD_LOGIC;
              Break     : in   STD_LOGIC;
           Clk100MHz : in   STD_LOGIC;
           Llights   : out  STD_LOGIC_VECTOR (2 downto 0);
           Rlights   : out  STD_LOGIC_VECTOR (0 to 2));
end Mustang_FSM;

architecture Behavioral of Mustang_FSM is
  -- Definition of embedded signals and constants
  -- Constants used for frequency division
  constant Fosc    : integer := 100000000;   --Frecuencia del oscilador de tabletas NEXYS 3
  constant Fdiv    : integer := 4;           --Frecuencia deseada del divisor
  constant CtaMax  : integer := Fosc / Fdiv; --Cuenta maxima a la que hay que llegar
  -- Signal used by the frequency division process
  signal Cont      : integer range 0 to CtaMax;
  signal Clk_En    : STD_LOGIC;

  -- State definition for the FSM
  -- Binary encoding (default) will be used 
  -- Equivalent of enumeration types in programming languages  
   type state_values is (ST0,ST1,ST2,ST3,ST4,ST5,ST6,ST7, ST8);
   signal pres_state, next_state: state_values;

  -- One hot state coding
  -- ONE HOT ENCODED state machine: Sreg0
--  subtype Sreg0_type is std_logic_vector(7 downto 0);
--  constant ST0: Sreg0_type := "00000001";
--  constant ST1: Sreg0_type := "00000010";
--  constant ST2: Sreg0_type := "00000100";
--  constant ST3: Sreg0_type := "00001000";
--  constant ST4: Sreg0_type := "00010000";
--  constant ST5: Sreg0_type := "00100000";
--  constant ST6: Sreg0_type := "01000000";
--  constant ST7: Sreg0_type := "10000000";
--  signal pres_state, next_state: Sreg0_type;

  -- Used to concatenate Lturn, Rturn and Hazard for easier
  -- handling
  signal LRH       : STD_LOGIC_VECTOR (3 downto 0);

begin
  -- Frequency divider to obtain a 2Hz signal from
  -- the 100 MHz board oscillator
  FreqDiv: process (Rst, Clk100MHz)
  begin
    if Rst = '1' then
       Cont <= 0;
     elsif (rising_edge(Clk100MHz)) then
       if Cont = CtaMax - 1 then
        Cont      <= 0;
        Clk_En    <= '1';
      else        
         Cont      <= Cont + 1;
          Clk_En    <= '0';
        end if;
    end if;
  end process FreqDiv;

  -- The FSM definition begins next

  -- "Current State Register" (StateReg) description
  StateReg: process (Clk100MHz,Clk_En,Rst)
  begin
    if (Rst = '1') then 
      pres_state <= ST0;
    elsif (rising_edge(Clk100MHz) and Clk_En = '1') then
      pres_state <= next_state;
    end if;
  end process StateReg;

  -- "Next State Logic" (FSM) description
  LRH <= Break & Lturn & Rturn & Hazard;
  FSM: process (pres_state, LRH)
  begin
    case pres_state is

      when ST0 => 
        case LRH is
          when "0000"   => next_state <= ST0; -- All off
          when "0110"   => next_state <= ST0; -- All off
          when "0100"   => next_state <= ST2; -- Left Turn
          when "0010"   => next_state <= ST5; -- Right Turn
          when "1000"   => next_state <= ST8; -- Break

          when others  => next_state <= ST1; -- Hazard
        end case;

      when ST1         => next_state <= ST0;
      when ST2         => next_state <= ST3;
      when ST3         => next_state <= ST4;
      when ST4         => next_state <= ST0;
      when ST5         => next_state <= ST6;
      when ST6         => next_state <= ST7;    
      when ST7         => next_state <= ST0;

        when ST8 =>
            case LRH is 
                when "1000" => next_state <= ST8;
                when others  => next_state <= ST0;
        end case;



      -- Include when others to avoid latches  
      when others      => next_state <= ST0;
    end case;
  end process FSM;

  -- "Output Logic" (Outputs) description
  Outputs: process (pres_state)
  begin
    case pres_state is

      when ST0 => Llights <= "000"; Rlights <= "000";
      when ST1 => Llights <= "111"; Rlights <= "111";   
      when ST2 => Llights <= "001"; Rlights <= "000";
      when ST3 => Llights <= "011"; Rlights <= "000";
      when ST4 => Llights <= "111"; Rlights <= "000";
      when ST5 => Llights <= "000"; Rlights <= "001";
      when ST6 => Llights <= "000"; Rlights <= "011";
      when ST7 => Llights <= "000"; Rlights <= "111";   
      when ST8 => Llights <= "111"; Rlights <= "111";
      when others => null;
   end case;
  end process Outputs;

end Behavioral;

The description of the warning:

WARNING:Xst:737 - Found 3-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

WARNING:Xst:737 - Found 3-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

Thanks for the help. :D

Was it helpful?

Solution

Instead of this:

  Outputs: process (pres_state)
  begin
    case pres_state is
      when ST0 => Llights <= "000"; Rlights <= "000";
      when ST1 => Llights <= "111"; Rlights <= "111";   
      when ST2 => Llights <= "001"; Rlights <= "000";
      when ST3 => Llights <= "011"; Rlights <= "000";
      when ST4 => Llights <= "111"; Rlights <= "000";
      when ST5 => Llights <= "000"; Rlights <= "001";
      when ST6 => Llights <= "000"; Rlights <= "011";
      when ST7 => Llights <= "000"; Rlights <= "111";   
      when ST8 => Llights <= "111"; Rlights <= "111";
      when others => null;
   end case;
  end process Outputs;

Do This:

  Outputs: process (pres_state)
  begin
    case pres_state is
      when ST0 => Llights <= "000"; Rlights <= "000";
      when ST1 => Llights <= "111"; Rlights <= "111";   
      when ST2 => Llights <= "001"; Rlights <= "000";
      when ST3 => Llights <= "011"; Rlights <= "000";
      when ST4 => Llights <= "111"; Rlights <= "000";
      when ST5 => Llights <= "000"; Rlights <= "001";
      when ST6 => Llights <= "000"; Rlights <= "011";
      when ST7 => Llights <= "000"; Rlights <= "111";   
      when ST8 => Llights <= "111"; Rlights <= "111";
      when others => Llights <= "000"; Rlights <= "000";
   end case;
  end process Outputs;

The question your compiler is asking you is: "What is the value of Llights when pres_state is ST9?" I'm aware that ST9 doesn't exist, but the compiler doesn't care. Which is annoying.

OTHER TIPS

Do not use a case statement inside a combinational process. If you add a clock to your output process it will work. Or you can use a VHDL SELECT signal assignment. The case statement inside the combinational process is generating the latch.

You could solve it like this: (this will add 1 clock cycle delay)

Outputs: process (Clk100MHz)
begin
  if (rising_edge(Clk100MHz) then

  case pres_state is

  when ST0 => Llights <= "000"; Rlights <= "000";
  when ST1 => Llights <= "111"; Rlights <= "111";   
  when ST2 => Llights <= "001"; Rlights <= "000";
  when ST3 => Llights <= "011"; Rlights <= "000";
  when ST4 => Llights <= "111"; Rlights <= "000";
  when ST5 => Llights <= "000"; Rlights <= "001";
  when ST6 => Llights <= "000"; Rlights <= "011";
  when ST7 => Llights <= "000"; Rlights <= "111";   
  when ST8 => Llights <= "111"; Rlights <= "111";
  when others => null;
 end case;
 end if;

end process Outputs;

You could also do this:

Llights <= "000" when pres_state = ST0 else
           "111" when pres_state = ST1 else
           etc etc

Or you can use a VHDL select signal assignment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top