1

* 我在 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.

现在,我收到了一些其他错误,因为一些信号没有被使用并且一大块被注释掉等等......但我的代码还没有到那里,现在这不是问题。

那么,为什么当每条路径都设置每个输出时,我仍然会在这段代码中获得锁存器?

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;
4

2 回答 2

3

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

并且不要只删除“else”,将其替换为DR <= (others => '0');或类似的,并且闩锁应该消失。有 2 种方法可以创建锁存器:DR <= DR;以及通过过程使 DR 未分配的路径。因此,仅删除或评论它不会完成这项工作。

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

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

于 2012-12-06T09:02:56.523 回答
2

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

于 2012-12-05T19:42:12.980 回答