Not understanding what makes my code turn to latches.

L

laserbeak43

Hello,
I'm writting some code(lab 6 part 1 of the Altera DE2 VHDL exercises)
and i keep getting this warning, that some of my signals and I/O are
going to be latched. I don't understand what makes
this happen, could someone please explain?
************************************************ warning
*************************************************

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

same for LEDG8 and LEDR
**************************************************************************************************************

all of this is happening in the process at the bottom of the code.

Thanks,
Malik

--------------------------------------------- top-level.vhd
----------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity Lab1_6 is
port(
SW : in unsigned(15 downto 0);
KEY : in unsigned(1 downto 0);
LEDR : out unsigned(15 downto 0);
LEDG8 : out std_logic;
HEX7, HEX6,
HEX5, HEX4,
HEX1, HEX0 : out unsigned(6 downto 0)
);
end Lab1_6;

architecture behavior of Lab1_6 is
signal ci0 : unsigned(7 downto 0);
signal co0 : unsigned(7 downto 0);
signal S : unsigned(7 downto 0);
signal R : unsigned(7 downto 0);
signal sigSW : unsigned(15 downto 0);
begin

ci0 <= "00000001";
fa : work.full8bitadder port map(ci0, sigSW(15 downto 8), sigSW(7
downto 0), co0(7 downto 0), R);

h7 : work.HEX port map(sigSW(15 downto 12), HEX7);
h6 : work.HEX port map(sigSW(11 downto 8), HEX6);
h5 : work.HEX port map(sigSW(7 downto 4), HEX5);
h4 : work.HEX port map(sigSW(3 downto 0), HEX4);
h1 : work.HEX port map(S(7 downto 4), HEX1);
h0 : work.HEX port map(S(3 downto 0), HEX0);

process(KEY, R, S, sigSW, co0)
begin
if(KEY = "00") then
S <= to_unsigned(0,8);
elsif(KEY = "01") then
S <= R;
LEDG8 <= co0(7);
LEDR(15 downto 8) <= sigSW(15 downto 8);
LEDR(7 downto 0) <= sigSW(7 downto 0);
end if;
end process;
sigSW <= SW;
end behavior;
 
Joined
Jan 29, 2009
Messages
152
Reaction score
0
I suppose it is because, when KEY is neither "00" or "01", S is not updated.
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
Code:
process(KEY, R, S, sigSW, co0)
begin

[I]-- Removed implied Latches with default output values[/I]
[COLOR="Red"]S <= "00000000";
LEDG8 <= '0';
LEDR(15 downto 8)  <= "00000000" ;
LEDR(7 downto 0)   <= "00000000";[/COLOR]

if(KEY = "00") then
S <= to_unsigned(0,8);
elsif(KEY = "01") then
S <= R;
LEDG8 <= co0(7);
LEDR(15 downto 8) <= sigSW(15 downto 8);
LEDR(7 downto 0) <= sigSW(7 downto 0);
end if;
end process;


The extra lines should remove the warning - hopefully
 
Last edited:
A

Andy

Avoiding latches comes from understanding what causes them. Anytime a
process is required to remember the value of a signal through an
execution of that process, that implied memory becomes a storage
element in synthesis. A signal that is not assigned any value during
an execution of the process must "remember" it's previous value, thus
that creates a memory element. If the process is clocked, then the
memory element is an edge-triggered flip-flop. If the process is
combinatorial, then the memory element is a latch, or combinatorial
feedback creating a latch out of gates.

The easiest, surest way to avoid latches is to, for all combinatorial
processes, include default assignments to all outputs ever driven by
the process, right up front, before anything else. That way there are
no execution paths through the process that avoid the assignments.

Of course, if you can avoid combinatorial processes altogether, then
you won't get latches in the first place. But sometimes you just
can't avoid a combinatorial process.

This same "remembering" analogy also governs whether a reference to a
variable in a clocked process causes a register, or just combinatorial
logic.

Andy
 
J

Jeff Cunningham

On 8/18/10 5:11 PM, laserbeak43 wrote:
....
process(KEY, R, S, sigSW, co0)
begin
if(KEY = "00") then
S<= to_unsigned(0,8);
elsif(KEY = "01") then
S<= R;
LEDG8<= co0(7);
LEDR(15 downto 8)<= sigSW(15 downto 8);
LEDR(7 downto 0)<= sigSW(7 downto 0);
end if;
end process;

In addition to the latch problem due to not covering all cases of KEY,
you really should not have S in the sensitivity list. You are telling
the model to run the process again when S changes. But because you
change it in the process itself, it sort of doesn't make sense and will
cause wasteful rerunning of the process whenever you update S. This
doesn't affect your synthesis result - it just slows the simulation.

-Jeff
 
M

MBodnar

Avoiding latches comes from understanding what causes them. Anytime a
process is required to remember the value of a signal through an
execution of that process, that implied memory becomes a storage
element in synthesis. A signal that is not assigned any value during
an execution of the process must "remember" it's previous value, thus
that creates a memory element. If the process is clocked, then the
memory element is an edge-triggered flip-flop. If the process is
combinatorial, then the memory element is a latch, or combinatorial
feedback creating a latch out of gates.

The easiest, surest way to avoid latches is to, for all combinatorial
processes, include default assignments to all outputs ever driven by
the process, right up front, before anything else. That way there are
no execution paths through the process that avoid the assignments.

Of course, if you can avoid combinatorial processes altogether, then
you won't get latches in the first place. But sometimes  you just
can't avoid a combinatorial process.

This same "remembering" analogy also governs whether a reference to a
variable in a clocked process causes a register, or just combinatorial
logic.

Andy

This was a very good, thorough, and correct explanation.

In every possible execution path through a combinatorial process, the
outputs of that process MUST be assigned to avoid latches. Like Andy
said, the easiest is to initialize everything upfront:

process(KEY, R, sigSW, co0)
begin
-- all outputs assigned regardless of 'KEY'
S <= (others => '0');
LEDG8 <= '0';
LEDR <= (others => '0');

-- conditional assignments now do not have to be exhaustive
if(KEY = "00") then
S <= to_unsigned(0,8);
elsif(KEY = "01") then
S <= R;
LEDG8 <= co0(7);
LEDR(15 downto 8) <= sigSW(15 downto 8);
LEDR(7 downto 0) <= sigSW(7 downto 0);
end if;
end process;
 
L

laserbeak43

Thanks for all of the advice, I've read this about twice so far and
it's starting to become a bit more clear.
My process has become more stable and I've made a minor adjustment to
my 8bit adder.
everything seems to be working but,

1 - R is supposed to be sent to S when KEY(1) is high,
but nothing happens when I press KEY(1). But Key(0) does
what KEY(1) is supposed to do.

2 - When KEY(1) and KEY(0) are pressed together, everything is
cleared,
the way that KEY(0) is supposed to behave when pressed by itself

3 - LEDG never lights up.

I don't see why this is happening, do you? If anyone is using quartus,
are there any tools that could help me figure out this problem? Like
maybe a schematic of my design?


************************************** top-level.vhd
********************************************

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity Lab1_6 is
port(
SW : in unsigned(15 downto 0);
KEY : in unsigned(1 downto 0);
LEDR : out unsigned(15 downto 0);
LEDG8 : out std_logic;
HEX7, HEX6,
HEX5, HEX4,
HEX1, HEX0 : out unsigned(6 downto 0)
);
end Lab1_6;

architecture behavior of Lab1_6 is
signal ci0 : std_logic;
signal co0 : std_logic;
signal S : unsigned(7 downto 0);
signal R : unsigned(7 downto 0);
begin

ci0 <= '0';

fa : work.full8bitadder port map(ci0, SW(15 downto 8), SW(7 downto
0), co0, R);

h7 : work.HEX port map(SW(15 downto 12), HEX7);
h6 : work.HEX port map(SW(11 downto 8), HEX6);
h5 : work.HEX port map(SW(7 downto 4), HEX5);
h4 : work.HEX port map(SW(3 downto 0), HEX4);
h1 : work.HEX port map(S(7 downto 4), HEX1);
h0 : work.HEX port map(S(3 downto 0), HEX0);

process(KEY, SW)
begin

if(KEY(0) = '1') then
S <= (others => '0');
LEDR <= (others => '0');
elsif(KEY(1) = '1') then
S <= R;
LEDG8 <= co0;
LEDR(15 downto 8) <= SW(15 downto 8);
LEDR(7 downto 0) <= SW(7 downto 0);
else
S <= (others => '0');
LEDG8 <= '0';
LEDR <= (others => '0');
S <= (others => '0');
end if;

end process;

end behavior;

********************************************************************************************8

Thanks,
Malik
 
L

laserbeak43

It turns out my KEYs are logic low. I'll have to test it when I have a
chance. I'll let you know what happens!
Thanks,
Malik
 
L

laserbeak43

It turns out that i did need some latches, but not in the
configuration I had originally used.

****************** process block ****************************

process(KEY, SW)
begin

if(KEY(1) = '0') then
S <= R;
LEDG8 <= co0;
LEDR(15 downto 8) <= SW(15 downto 8);
LEDR(7 downto 0) <= SW(7 downto 0);
elsif(KEY(0) = '0') then
S <= (others => '0');
LEDR <= (others => '0');
else
LEDR(15 downto 8) <= SW(15 downto 8);
LEDR(7 downto 0) <= SW(7 downto 0);
end if;

end process;

*****************************************************************************

Thanks a lot for your help guys. You're life savers :)
Malik
 
T

Tricky

It turns out that i did need some latches, but not in the
configuration I had originally used.

****************** process block ****************************

        process(KEY, SW)
        begin

                if(KEY(1) = '0') then
                        S <= R;
                        LEDG8 <= co0;
                        LEDR(15 downto 8) <= SW(15 downto 8);
                        LEDR(7 downto 0) <= SW(7 downto 0);
                elsif(KEY(0) = '0') then
                        S <= (others => '0');
                        LEDR <= (others => '0');
                else
                        LEDR(15 downto 8) <= SW(15 downto 8);
                        LEDR(7 downto 0) <= SW(7 downto 0);
                end if;

        end process;

*****************************************************************************

Thanks a lot for your help guys. You're life savers :)
Malik

You're missing co0 and R from the sensitivity list!

So simulation wont match real hardware.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top