Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

" inferring latch(es)" vhdl error

Status
Not open for further replies.

INS-ANI

Full Member level 3
Joined
Feb 28, 2007
Messages
152
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,298
Activity points
2,377
hey guys,
I was writing a code to display something from a fpga(cyclone2, DE2) on a divided clock cycle of 500hz.
The following warnings have probably affected my final implementations.

I request you to please have a look at it and find the mistake i have been making.. as i have been getting the same error for many of my previous codes.

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

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

CODE(VJDL)
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;


entity lcd_driver is 
      port (
            clock_50mhz : in std_logic;
                    key : in std_logic; --sw[0]
             clock_500hz: inout std_logic;
               LCD_EN,LCD_RS,LCD_RW,LCD_ON,LCD_BLON :out std_logic;
               LCD_DATA :out  std_logic_vector (7 downto 0); 
                    ledg: out std_logic
           );
end entity lcd_driver;

architecture a_lcd_driver of lcd_driver is 
 signal  D0:std_logic;
 signal count_50mhz: std_logic_vector(27 downTO 0);
 type statetype is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17);
 signal state,nextstate : statetype;
 --------------------------------------------
 begin
  LCD_ON<='1';
  LCD_RW<='0';
  LCD_BLON<='1'; 
         
         
 
 ------------------------------------------------------------clock division---------
 process(clock_50mhz,key,D0)
  begin
       
        if (key='0') then
            count_50mhz<=X"0000000";
            D0<='0';
            
        elsif (clock_50mhz'event and clock_50mhz='1') then
            count_50mhz<= count_50mhz+1;
            
        if( count_50mhz < X"186A0" ) then
           ledg<='1';
           D0<= not D0;
           
        elsif (count_50mhz > X"186A0") then
           if (count_50mhz < X"30D40") then
               ledg<='0';
               
           else 
               count_50mhz <=X"0000000";
         end if;
         end if;
         end if;
         clock_500hz<=D0;
         
         end process;
         
 -------------------------------------------------state assignment----------- 
 process(state)
         begin
         case state is 
         
         when s0 => LCD_DATA  <=X"38";
                    LCD_RS    <='0';
                    LCD_EN    <='1';
                    nextstate <=s1;
                    
         when s1 => LCD_EN <= '0';
                    nextstate <=s2;
                    
         when s2 => LCD_DATA  <=X"38";
                    LCD_EN    <='1';
                    nextstate <=s3;
                    
         when s3 => LCD_EN <='0';
                    nextstate <=s4;
         
         when s4 => LCD_DATA  <=X"38";
                    LCD_EN    <='1';
                    nextstate <=s5;
                    
         when s5 => LCD_EN <='0';
                    nextstate <=s6;
                    
         when s6 => LCD_DATA  <=X"08";
                    LCD_EN    <='1';
                    nextstate <=s7;
                    
         when s7 => LCD_EN <='0';
                    nextstate <=s8; 
              
         when s8 => LCD_DATA  <=X"01";
                    LCD_EN    <='1';
                    nextstate <=s9;
                    
         when s9 => LCD_EN <='0';
                    nextstate <=s10;
                    
         when s10 => LCD_DATA  <=X"0F";
                     LCD_EN    <='1';
                     nextstate <=s11;
                    
         when s11 => LCD_EN <='0';
                     nextstate <=s12;
                    
         when s12 => LCD_DATA  <=X"84";
                     LCD_EN    <='1';
                     nextstate <=s13;
                    
         when s13 => LCD_EN <='0';
                     nextstate <=s14;
                    
          when s14 => LCD_DATA  <=X"80";
                      LCD_EN    <='1';
                      nextstate <=s15;
                    
         when s15 => LCD_EN <='0';
                     nextstate <=s16;
                     
         when s16 => LCD_DATA  <=X"22";
                     LCD_RS    <='1';
                     LCD_EN    <='1';
                     nextstate <=s17;
                    
         when s17 => LCD_EN <='0';
                     nextstate <=s0;
                     
     end case;
END process;
-----------------------------------------------------------
process (clock_500hz,key)
begin
     if key='0' then
        state<=s0;
     elsif rising_edge(clock_500hz) then
        state<=nextstate;
     end if;

end process;  
------------------------------------------------------------
         
--  LCD_ON<='1';
  --LCD_RW<='0';
  --LCD_BLON<='1';       
 end a_lcd_driver;
 

Those are warnings.

The issue is that, in a process, there is an implied LCD_DATA <= LCD_DATA.
thus when state = s1, LCD_DATA is based on the previous value LCD_DATA had. There is also no clock. This infers a latch -- the LCD_DATA must have some form of memory element, but doesn't use a clock edge.

The code could be rewritten to use a clocked process. alternatively, LCD_DATA, LCD_RS, LCD_EN can be defined in each case (and as something other than LCD_DATA <= LCD_DATA).

latches are typically undesirable, but can work. In some cases they can even be necessary. It shouldn't be difficult to update this code.
 

@permute
Thankyou for the reply. I have tried the changes you have adviced. However detailed simulation shows my clock division process is not active.
I have tried to troubleshoot it, but was unable to find error. Please have a look at it.
 

Hi,

Try below code

Code:
llibrary ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;


entity lcd_driver is 
      port (
            clock_50mhz : in std_logic;
                    key : in std_logic; --sw[0]
             clock_500hz: inout std_logic;
               LCD_EN,LCD_RS,LCD_RW,LCD_ON,LCD_BLON :out std_logic;
               LCD_DATA :out  std_logic_vector (7 downto 0); 
                    ledg: out std_logic
           );
end entity lcd_driver;

architecture a_lcd_driver of lcd_driver is 
 signal  D0:std_logic;
 signal count_50mhz: std_logic_vector(27 downTO 0);
 type statetype is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17);
 signal state,nextstate : statetype;
 --------------------------------------------
 begin
  LCD_ON<='1';
  LCD_RW<='0';
  LCD_BLON<='1'; 
         
         
 
 ------------------------------------------------------------clock division---------
  process (clock_50mhz,key)
  begin
    if (key='0') then
      count_50mhz<=X"0000000";
    elsif rising_edge(clock_50mhz) then
      if (count_50mhz = X"186A0") then
        count_50mhz <= X"0000000";
      else
        count_50mhz <= count_50mhz + "1";
      end if;
    end if;
  end process;

  process (clock_50mhz,key)
  begin
    if (key='0') then
      D0<='0';
    elsif rising_edge(clock_50mhz) then
      if (count_50mhz = X"186A0") then
        D0 <= not D0;
      end if;
    end if;
  end process;

  ledg <= D0 ;
  clock_500hz <= D0;

--=============================================================================
-- Sequential Logic of FSM
  process (clock_500hz,key)
  begin
    if key='0' then
      state<=s0;
    elsif rising_edge(clock_500hz) then
      state<=nextstate;
    end if;
  end process;
-------------------------------------------------------------------------------
--=============================================================================
-- Next State Decoder of FSM
  process (state)
  begin
    case state is 
      when s0     => nextstate <= s1;
      when s1     => nextstate <= s2;
      when s2     => nextstate <= s3;
      when s3     => nextstate <= s4;
      when s4     => nextstate <= s5;
      when s5     => nextstate <= s6;
      when s6     => nextstate <= s7;
      when s7     => nextstate <= s8; 
      when s8     => nextstate <= s9;
      when s9     => nextstate <= s10;
      when s10    => nextstate <= s11;
      when s11    => nextstate <= s12;
      when s12    => nextstate <= s13;
      when s13    => nextstate <= s14;
      when s14    => nextstate <= s15;
      when s15    => nextstate <= s16;
      when s16    => nextstate <= s17;
      when s17    => nextstate <= s0;
      when others => nextstate <= s0;
    end case;
  end process;
-------------------------------------------------------------------------------
--=============================================================================
-- Output Logic of FSM
  process (clock_500hz,key)
  begin
    if key='0' then
      LCD_DATA  <=X"00";
      LCD_RS    <='0';
      LCD_EN    <='0';
    elsif rising_edge(clock_500hz) then
      case (nextstate) is 
        when s0     => LCD_DATA  <=X"38";
                       LCD_RS    <='0';
                       LCD_EN    <='1';
        when s1     => LCD_EN <= '0';
        when s2     => LCD_DATA  <=X"38";
                       LCD_EN    <='1';
        when s3     => LCD_EN <='0';
        when s4     => LCD_DATA  <=X"38";
                       LCD_EN    <='1';
        when s5     => LCD_EN <='0';
        when s6     => LCD_DATA  <=X"08";
                       LCD_EN    <='1';
        when s7     => LCD_EN <='0';
        when s8     => LCD_DATA  <=X"01";
                       LCD_EN    <='1';
        when s9     => LCD_EN <='0';
        when s10    => LCD_DATA  <=X"0F";
                       LCD_EN    <='1';
        when s11    => LCD_EN <='0';
        when s12    => LCD_DATA  <=X"84";
                       LCD_EN    <='1';
        when s13    => LCD_EN <='0';
        when s14    => LCD_DATA  <=X"80";
                       LCD_EN    <='1';
        when s15    => LCD_EN <='0';
        when s16    => LCD_DATA  <=X"22";
                       LCD_RS    <='1';
                       LCD_EN    <='1';
        when s17    => LCD_EN <='0';
        when others => LCD_DATA  <=X"00";
                       LCD_RS    <='0';
                       LCD_EN    <='0';
      end case;
    end if;
  end process;
-------------------------------------------------------------------------------



         
--  LCD_ON<='1';
  --LCD_RW<='0';
  --LCD_BLON<='1';       
 end a_lcd_driver;

HTH,
Shitansh Vaghela
 
Last edited:

key is an async, active low reset. At one time, this was the preferred method, but is no longer so. Make sure your sim isn't simply holding everything in reset.

also, I don't think the code does what you want. the D0 <= not D0 when cnt < value just means D0 will toggle at (implied) 25MHz and then be gated off.
 

@shitansh
Thanks for your effort.. the later half of code is not giving any error, but it doesn't synthesize properly on DE2, however i have managed to troubleshoot my code, your and all other who posted advice.. it helped me learn something. Thankyou!
 

in this code you need to provide proper if and else condition..
in some places you are not using else.
 

@hitech are u referring to my code in first post of this thread?
 

no dude..i am refering the code given in the 4th post....
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top