Reputation: 447
* I'm coding VHDL in Xilinx 14.3 and am targeting the Nexys 2 board.*
From what I've read, latches come from there being incomplete if/case statements or when an output isn't set in all possible paths.
I've looked over my code multiple times and am still getting two latches.
WARNING:Xst:737 - Found 8-bit latch for signal <DR>. 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 8-bit latch for signal <P>. 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.
Now, I am getting a few other errors because some signals aren't used and a large chunk is commented out, etc... but I'm not there yet with my code and it's not a problem right now.
So, why am I still getting latches in this code when every path sets each output?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity project2vhd is
Port ( CE_s : in STD_LOGIC;
A0 : in STD_LOGIC;
RD_s : in STD_LOGIC;
WR_s : in STD_LOGIC;
RESET : in STD_LOGIC;
ACK_s : inout STD_LOGIC;
Y1, Y2, Y3 : inout STD_LOGIC;
-- Din : in STD_LOGIC_VECTOR (7 downto 0);
-- Dout : out STD_LOGIC_VECTOR (7 downto 0);
D : inout STD_LOGIC_VECTOR (7 downto 0);
EN_s : out STD_LOGIC;
P : inout STD_LOGIC_VECTOR (7 downto 0));
end project2vhd;
architecture Behavioral of project2vhd is
signal CR : STD_LOGIC_VECTOR (1 downto 0);
signal SR : STD_LOGIC_VECTOR (2 downto 0);
signal DR : STD_LOGIC_VECTOR (7 downto 0);
begin
process (WR_s, ACK_s, RESET, A0, RD_s)
begin
if (RESET = '1') then --if reset is high
Y1 <= '0';
Y2 <= '0';
Y3 <= '0';
D <= "ZZZZZZZZ";
EN_s <= '0'; --check EN_s's value at reset
P <= P;
DR<= DR;
else
D <= D;
DR <= DR;
P <= P;
-- if (CR(0) = '1') then --Mode 1
--
-- Y1 <= ((Y1 and (not Y2) and Y3) or
-- (WR_s and ACK_s and (not Y2) and Y3));
-- Y2 <= '0';
-- Y3 <= (((not Y1) and (not Y2) and Y3) or
-- (WR_s and ACK_s and (not Y2) and Y3) or
-- ((not Y1) and (not Y2) and (not WR_s) and ACK_s) or
-- ((not WR_s) and (not Y2) and Y3));
-- SR(2) <=(((not ACK_s) and (not Y2) and (not Y3)) or --obf
-- (WR_s and (not ACK_s) and (Y1) and (not Y2)) or
-- (WR_s and (not ACK_s) and (not Y2) and Y3) or
-- (WR_s and (not Y1) and (not Y2)));
-- SR(0) <= (((not Y2) and (not Y3)) or --INTR_enable
-- (WR_s and (not Y1) and (not Y2)) or
-- ((not WR_s) and (not ACK_s) and (not Y1) and (not Y2) and Y3));
--
--
-- if (CE_s = '1') then
-- D <= "ZZZZZZZZ";
--
-- else
-- if (WR_s = '0' and A0 = '0') then --Write Data (MODE 1)
-- EN_s <= '0'; -- enable buffer
--
-- DR <= D;
-- P <= D;
--
-- elsif (WR_s = '0' and A0 = '1') then --control Reg Mode (MODE 1 and 0)
-- EN_s <= '0'; -- enable buffer
--
-- CR(0) <= D(0);
-- CR(1) <= D(1);
---- SR(0)
---- SR(1)
---- SR(2)
--
--
-- elsif (RD_s = '0' and A0 = '1') then -- Read Status (MODE 1)
-- EN_s <= '1'; -- disable buffer
--
-- D <= DR;
---- D <= "10101010"
--
-- else
-- EN_s <= '0'; -- enable buffer
-- D <= "ZZZZZZZZ";
--
-- end if;
-- end if;
-- else --Mode 0
SR <= "111";
if (CE_s = '0' and WR_s = '0' and A0 = '1') then
EN_s <= '0'; -- enable buffer
DR <= D;
CR(1) <= D(1);
CR(0) <= D(0);
P <= P;
elsif (CE_s = '0' and WR_s = '0' and A0 = '0') then
EN_s <= '1'; -- disable buffer
P <= DR;
DR <= DR;
else
EN_s <= '0'; -- enable buffer
D <= "ZZZZZZZZ";
DR <= DR;
P <= P;
end if;
-- end if;
end if;
end process;
end Behavioral;
Upvotes: 1
Views: 6740
Reputation:
Did you remove both copies of DR <= DR;
? Get rid of both the default one at the start AND the "else" one.
And don't just delete the "else" one, replace it with DR <= (others => '0');
or some such, and the latch should go away. There are 2 ways of creating a latch : DR <= DR;
and a path through the process that leaves DR unassigned. So just deleting or commenting it out won't do the job.
If you don't want a latch, but you DO want DR to hold its previous value under some circumstances, you need a clocked process, in which case you can hold DR in a register.
In that case, you would normally just have clock and reset in the sensitivity list, plus any signals required for read accesses if the Reads were to stay asynchronous. But fully clocked designs are better practice.
Upvotes: 3
Reputation: 3375
Because under various conditions the DR and P signals are assigned to themselves (ie: DR <= DR;) so they don't change, or in other words keep their last value. That is a latch.
Upvotes: 2