为什么我的VHDL代码有锁存器?

时间:2012-12-05 19:02:56

标签: vhdl xilinx

*我正在Xilinx 14.3中编写VHDL代码并且正在针对Nexys 2主板。*

从我读过的内容来看,锁存器来自于if / case语句不完整或者没有在所有可能的路径中设置输出。

我多次查看我的代码,但仍然有两个锁存器。

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.

现在,我得到了一些其他的错误,因为没有使用某些信号而且有一大块被注释掉等等......但是我还没有使用我的代码,现在这不是问题。< / p>

那么,当每个路径设置每个输出时,为什么我仍然在此代码中获取锁存器?

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;

2 个答案:

答案 0 :(得分:3)

您是否删除了DR <= DR;的两个副本?摆脱开始时的默认值和“else”值。

并且不要只删除“else”,将其替换为DR <= (others => '0');或其他一些,并且闩锁应该消失。有两种创建锁存器的方法:DR <= DR;和通过该过程的路径,使DR保持未分配状态。因此,删除或评论它将无法完成任务。

如果您不想要锁存器,但是在某些情况下您希望DR保持其先前的值,则需要一个时钟进程,在这种情况下,您可以将DR保存在寄存器中。

在这种情况下,如果读取保持异步,通常只需要灵敏度列表中的时钟和复位,以及读取访问所需的任何信号。但完全时钟设计是更好的做法。

答案 1 :(得分:2)

因为在各种条件下DR和P信号被分配给它们自己(即:DR&lt; = DR;)所以它们不会改变,或者换句话说保持它们的最后值。这是一个闩锁。