1
\$\begingroup\$

The code in the figure below creates an unnecessary latch. a) What statement(s) should be written and where to remove it?

signal next_p, p: std_logic_vector(1 downto 0);
signal a, b, c, d, q, next_q: std_logic;

process(select,a,b,c,d)
begin
  if (select=”00”) then
    next_q<=a;
    next_p<=”00”;
  elsif (select=“01”) then
    next_q<=b;
    next_p<=”10”;
  elsif (select=“10”) then
    next_q<=c;
                      <------- next_P isnt assigned here (latch?)
  else
    next_q<=d;
                      <------- next_P isnt assigned here (latch?)
  end if;
end process;

process(clk)
begin
  if (clk’event and (clk=’1’)) then
    q<=next_q;
    p<=next_p;
  end if;
end process;

I cant really find the latch at this code.. But i have some thought that next_p in the if-else statement isn't defined which leads to a latch ? But I'm not 100 percent sure if that is the answer, can someone help me to understand where the latch occurs?

regards

a student.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Your comments are exactly correct — if you don't assign to a signal in every branch of a conditional statement, the logic synthesizer must create a latch in order to remember the previous assignment to that signal, wherever it might have been.

\$\endgroup\$
3
  • \$\begingroup\$ ok, do you think i should remove something else from this code or is this code 100% synthesizeable ? \$\endgroup\$
    – draaknar
    Oct 1, 2013 at 16:44
  • \$\begingroup\$ It's definitely sythesizable, but it will suffer from race conditions, since the latching/nonlatching behavior of next_p depends on two input signals. If you really want a latch there, it would be better to create an explicit synchronous process for it. \$\endgroup\$
    – Dave Tweed
    Oct 1, 2013 at 17:36
  • \$\begingroup\$ Ok i think i start gettingtthe idea of how to implement and latches and flip-flops, thx for the help dave , i really appreciate it! \$\endgroup\$
    – draaknar
    Oct 1, 2013 at 17:41
2
\$\begingroup\$

Your comments are correct.

You could improve the current code, until the fragile combinational process actually does what you intend, or you could replace the lot with a single synchronous process:

process(clk)
begin
  if rising_edge(clk) then
    case select is
    when "00" =>
      q <= a;
      p <= "00";
    when "01" =>
      q <= b;
      p <= "10";
    when "10" =>
      q <= c;
    when others =>
      q <= d;
    end case;
  end if;
end process;

a bit simpler... not prone to sensitivity list errors, and because the missing assignments are in the clocked process, the old value of p will be stored in a register.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.