【问题标题】:Why does my VHDL code have latches?为什么我的 VHDL 代码有锁存器?
【发布时间】:2012-11-23 17:02:57
【问题描述】:

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

【问题讨论】:

    标签: vhdl xilinx


    【解决方案1】:

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

    不要只删除“else”,将其替换为DR &lt;= (others =&gt; '0'); 或类似的东西,闩锁应该会消失。有 2 种方法可以创建锁存器:DR &lt;= DR; 和通过进程的路径使 DR 未分配。所以仅仅删除或评论它是行不通的。

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

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

    【讨论】:

      【解决方案2】:

      因为在各种条件下,DR 和 P 信号都分配给它们自己(即:DR

      【讨论】:

      • 我实际上添加了那些希望它能修复闩锁。为了再次测试它,我每次将它分配给自己时都将其删除,但我仍然得到相同的确切锁存器。你知道其他修复方法吗?
      • 如果您在其中一个 if 情况下没有分配任何信号,这意味着与将信号分配给自身相同,或者“记住最后一个值”,这意味着您创建了一个锁存器。如果您不想要锁存器,则必须根据 INPUTS ONLY 为条件语句的每个代码路径中的每个输出显式分配一个值。
      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多