如何修复 case-when 中的“锁存器可能由不完整的 case 或 if 语句生成”消息?

How do I fix “Latches may be generated from incomplete case or if statements” messages in a case-when?

请帮帮我

我正在尝试使用选择器对 4 位进行 ALU。 我收到这样的错误:

**WARNING:Xst:737 - Found 1-bit latch for signal <Z<1>>. 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 1-bit latch for signal <Z<0>>. 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 1-bit latch for signal <Znot<3>>. 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 1-bit latch for signal <Znot<2>>. 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 1-bit latch for signal <Znot<1>>. 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 1-bit latch for signal <Znot<0>>. 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 1-bit latch for signal <Z<2>>. 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;

entity Multiplexor is
    Port ( A, B, C, D : in  STD_LOGIC;
           S : in  STD_LOGIC_VECTOR (2 downto 0);
           Z : out  STD_LOGIC_VECTOR (2 downto 0);
           Znot : out  STD_LOGIC_VECTOR (3 downto 0));
end Multiplexor;

architecture tabla of Multiplexor is

begin

process(S, A, B, C, D)

begin

   case (S) is 
      when "000" => --Suma--
         Z(2) <= ((A and C) or (B and C and D) or (A and B and D));
            Z(1) <= (((not(A))and (not (B))and C) or ((not(A)) and C and (not(D))) or (A and (not (B)) and (not (C))) or (A and (not (C)) and (not (D))) or ((not (A)) and B and (not (C)) and D) or (A and B and C and D));
            Z(0) <= (((not(B)) and D) or (B and (not(D))));
      when "001" => --Resta--
         Z(2) <= (((not(A)) and C) or ((not(A)) and C and D) or (A and (not(C)) and (not(D))) or (A and B and (not(C))));
            Z(1) <= (((not(A)) and (not(B)) and C) or ((not(A)) and C and D) or (A and (not(C)) and (not(D))) or (A and B and (not(C))));
            Z(0) <= (((not(B)) and D) or (B and (not(D))));
      when "010" => --Comparación--
         Z(2) <= (((not(A)) and C) or ((not(A)) and (not(B)) and D) or ((not(B)) and C and D));
            Z(1) <= ((A and (not(C))) or (B and (not(C)) and (not(D))) or (A and B and (not(D))));
            Z(0) <= (((not(A)) and (not(B)) and (not(C)) and (not(D))) or ((not(A)) and B and (not(C)) and D) or (A and (not(B)) and C and (not(D))) or (A and B and C and D));
      when "011" => --AND--
         Z(2) <= '0';
            Z(1) <= (A and C);
            Z(0) <= (B and D);
      when "100" => --OR--
         Z(2) <= '0';
            Z(1) <= (C or A);
            Z(0) <= (D or B);
      when "101" => --XOR--
         Z(2) <= '0';
            Z(1) <= (((not(A)) and C) or (A and (not(C))));
            Z(0) <= (((not(B)) and D) or (B and ((not(D)))));
      when "110" => --NOT--
            Znot(3) <= (not(A));
         Znot(2) <= (not(B));
            Znot(1) <= (not(C));
            Znot(0) <= (not(D));
        when others =>
            Znot(3) <= '0';
         Znot(2) <= '0';
            Znot(1) <= '0';
            Znot(0) <= '0';
            Z(2) <= '0';
            Z(1) <= '0';
            Z(0) <= '0';
   end case;
end process;
end tabla;

如评论中所述,您不会为每个案例的 Case 语句的所有输出信号分配一个值。由于语言标准的摘录可以使用有点技术性和不透明的语言,我会尽量写一个初学者友好的解释。

你的 case 语句有七个输出,Z(0..2) 和 Znot(0..3)。您的过程是一种称为组合的类型(即它没有计时)。这种结构的标准描述是为所有情况分配所有输出。如果您查看您的第一次评估(when = "000"),您会发现您只是为 Z 赋值。这意味着您希望 Znot 保留其先前的值,这意味着一个记忆元素。非时钟存储元件称为锁存器。

您收到警告的原因是闩锁违反了同步设计实践。 FPGA 被设计为同步工作。这些工具知道这一点,并且由于在 99% 的情况下闩锁是无意的,因此会发出警告。他们不引发错误的原因是在某些极端情况下需要使用闩锁,但这仅供专家使用。

隐含内存元素的正确方法是使用寄存器。在这种情况下,暗示这将是用时钟驱动您的过程。如果这是不可取的,则在每种情况下明确说明每个输出的所需值。