Почему мой код VHDL имеет защелки?

* Я кодирую VHDL в Xilinx 14.3 и ориентируюсь на плату 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;

person twbbas    schedule 05.12.2012    source источник


Ответы (2)


Вы удалили обе копии DR <= DR; ? Избавьтесь как от стандартного в начале, так и от «другого».

И не просто удаляйте "else", а замените его на DR <= (others => '0'); или что-то в этом роде, и защелка должна исчезнуть. Существует 2 способа создания защелки: DR <= DR; и путь через процесс, который оставляет DR неназначенным. Так что просто удалить или закомментировать это не поможет.

Если вам не нужна защелка, но вы хотите, чтобы DR сохранял свое предыдущее значение при некоторых обстоятельствах, вам нужен синхронизируемый процесс, и в этом случае вы можете хранить DR в регистре.

В этом случае у вас обычно будут просто часы и сброс в списке чувствительности, а также любые сигналы, необходимые для доступа на чтение, если чтение должно оставаться асинхронным. Но лучше использовать полностью синхронизированные конструкции.

person user_1818839    schedule 06.12.2012

Потому что при различных условиях сигналы DR и P присваиваются самим себе (т.е.: DR ‹= DR;), поэтому они не изменяются, или, другими словами, сохраняют свое последнее значение. Это защелка.

person Charles Steinkuehler    schedule 05.12.2012
comment
Я на самом деле добавил их в надежде, что это исправит защелки. Чтобы проверить это снова, я удалял каждый раз, когда он назначает его себе, и я все еще получаю ту же самую защелку. Знаете ли вы о каких-либо других исправлениях? - person twbbas; 06.12.2012
comment
Если вы не назначаете какой-либо сигнал в одном из ваших случаев if, это означает то же самое, что присваивать сигнал самому себе или запоминать последнее значение, что означает, что вы создали защелку. Если вам не нужны защелки, вы должны явно присвоить значение, основанное на ТОЛЬКО ВХОДАХ, каждому из ваших выходов в каждом пути кода вашего условного оператора. - person Charles Steinkuehler; 06.12.2012