9
\$\begingroup\$

I want to design a block of combinational logic using VHDL, but occasionally the synthesized result contains an unintentional latch.

What coding guidelines do I need to follow in order to avoid the synthesizer from inferring latches?

Example : in small segment of code, should I use if-else statements?

\$\endgroup\$
  • \$\begingroup\$ If one could get what I try to ask, please inform me \$\endgroup\$ – user5140 Aug 11 '11 at 13:25
  • \$\begingroup\$ I wasn't sure what you meant from your example. Please check to make sure the rewording matches your original intent. \$\endgroup\$ – W5VO Aug 11 '11 at 14:30
  • \$\begingroup\$ @fatai, I already commented, there is a specific method to deleting your account available on meta.stackexchange.com. I linked on the last question I was flagged on. Moderators on site do not have this power, ever. This requires contacting the dev team. \$\endgroup\$ – Kortuk Jan 18 '12 at 13:41
13
\$\begingroup\$

To avoid latches, you need to make sure all of your outputs are assigned at all possible branches of the code.

for example,

if a = '1' then
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

would generate a latch, because in the first condition, the value of b(1) is not specified, so the compiler decided you wanted to keep the previous value of b(1) there. One way to write this that would not generate a latch is:

if a = '1' then
   b <= prev_b;
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

...

if rising_edge (clk)
    prev_b <= b;
end if;

Here you explicitly state that b should retain it's old value, and then overwrite b(0) with the new value.

Another way is to give b a default value, as in @TomiJ's answer.

If you post the code you are getting a latch on, we could help you find the specific reason.

\$\endgroup\$
  • \$\begingroup\$ I don't think your approach of b <= b will avoid a latch, as it still requires preserving the state of the signal. \$\endgroup\$ – Tomi Junnila Aug 11 '11 at 15:36
  • \$\begingroup\$ You may be right; I am too used to clocked logic. I will edit. \$\endgroup\$ – fbo Aug 11 '11 at 18:12
6
\$\begingroup\$

If you are using processes for combinational logic (and I advise against it for just this reason) then make sure every path through the process assigns something to every signal that the process drives. None of the outputs can be dependent on any of the outputs from "last time" the process ran.

Otherwise you infer a latch because the next time the process is scheduled it has to keep the value of the signal which didn't get a new value last time around.

I prefer to keep purely combinational logic as continuous assignments, and use processes for clocked logic, then I don't get latches.

\$\endgroup\$
5
\$\begingroup\$

Four rules to avoid latches:

  • Don't read from the signals to which you write.
  • Have a correct sensitivity list (all signals that you read should be in the sensitivity list)
  • Make sure that all signals to which your write are assigned in every path. (for example: in each branch of an if-else-statement)
  • For processes which use variable, make sure every variable is initialized a default value before reading it (in another variable or signal ).

Additionally, if you have several combinational processes, make sure you don't create a loop.

Several coding styles can help you stick to these rules, for example the style in @TomiJ's answer. As @Martin Thompson points out, it may be better to avoid combinational logic all together. Put everything in a clocked process instead.

\$\endgroup\$
  • \$\begingroup\$ +1 Nice set of rules. Would you agree that your rule #2 (about the sensitivity list) is actually important for ensuring consistent results between synthesis and simulations, but does not really make a difference about the inference of latches? \$\endgroup\$ – rick Nov 3 '14 at 6:57
  • \$\begingroup\$ @rick AFAIK, there is no guarantee of what a synthesis tool will do with incomplete sensitivity lists. The IEEE standard for VHDL Synthesis (1076.6-1999) states that: "The process sensitivity list shall contain all signals read within the process statement. Processes with incomplete sensitivity lists are not supported." That said, I know that certain synthesis tools (perhaps all?) accept incomplete sensitivity lists, but simply ignore the sensitivity list all together. If you would rely on that behavior instead of the stricter IEEE standard, I guess your statement would be correct. \$\endgroup\$ – Philippe Nov 4 '14 at 19:25
  • \$\begingroup\$ Thanks, that sounds right, it would make my model non-compliant with that standard. It just got my curiosity because all synthesis tools I've seen so far ignore the sensitivity list, but I've heard rumors that some could infer latches. \$\endgroup\$ – rick Nov 5 '14 at 6:32
3
\$\begingroup\$

As has been pointed out by @fbo and @Martin Thompson, you need to ensure every signal driven by the process is assigned some value in every branch of the process, and that value must not be dependent on the previous state of any of the outputs of the process.

The easiest way to ensure this is to assign some default value to each output at the very beginning of the process, for example (co-opting fbo's example):

COMBO: process(a)
begin
    b <= (others => '0'); -- Assign default value to b
    if a = '1' then
        b(0) <= '1';
    else
        b(1 downto 0) <= "00";
    end if;
end process COMBO;
\$\endgroup\$
  • 1
    \$\begingroup\$ This is a good method that I often use. Sometimes though, a latch warning can indicate to you that you forgot to assign some bits, whereas this method might make the bug harder to find. For example, if you were assigning all the bits of a wide signal separately, and accidently miscounted. \$\endgroup\$ – fbo Aug 11 '11 at 18:20
  • 2
    \$\begingroup\$ Only in a combinatorial process. In a clocked process, you infer a flipflop, which may be exactly what you want. \$\endgroup\$ – Martin Thompson Aug 16 '11 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy