vhdlmojo

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


Please Help me

I was trying to do ALU for 4 bit with selector. I'm getting errors like this:

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

I wrote this code:

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;

Solution

  • As has been stated in the comments, you don't assign a value to all your output signals from the Case statement for each case. As the extract from the language standard can use language that is bit technical and opaque, I will try to write an explanation that is beginner friendly.

    You case statement has seven outputs, Z(0..2) and Znot(0..3). Your process is of a type known as combinatorial (i.e. it is not clocked). The standard description of this structure would be to assign all outputs, for all cases. If you look at your first evaluation (when = "000") you can see that you are only assigning values to Z. This implies that you want Znot to retain its previous value, which implies a memory element. A non-clocked memory element is called a Latch.

    The reason you get a warning is that Latches violate synchronous design practices. FPGAs are designed to work synchronously. The tools know this, and since in 99% of cases a latch is unintended, will raise a warning. The reason they don't raise an error is that there are some corner cases where a latch is intended, but this is for expert use only.

    The correct way to imply a memory element is to use a register. In this case, to imply this would be to drive your process with a clock. If that is not desirable then explicitly state the desired value for every output in every case.