2
\$\begingroup\$

My circuit is based on a state-machine. I checked it and it's working fine, the only issue is that it's inferring one latch per flip-flop (The state machine has 11 states and the circuit is one-hot so it has 11 flip-flops, but also 11 unwished latches) I have checked everything but I cant find what it causing these unexpected latches. My code is in spanish, I think this shouldnt be a problem, but if you need me to translate it, I can do it. The only important note is that "estado" means "state" and "estaprox" means "next state". Many thanks for your help

library IEEE;
use IEEE.std_logic_1164.all;

entity ej13 is 

port (
        clk_i   :   in std_logic;
        y_i :   in std_logic;
        sr_i    :   in std_logic;
        z_o :   out std_logic);

end entity ej13;

architecture EstaNoAsig of ej13 is
    type tipo_estado is (a,b,c,d,e,f,g,h,i,j,k);
    signal estado, estaprox : tipo_estado;
begin

Secuencial:
process (clk_i)
begin
    if rising_edge (clk_i) then
        if  sr_i = '1' then
            estado <= a;
        else
            estado <= estaprox;
        end if;
    end if;
end process Secuencial;

Combinacional:
process (y_i, estado)
begin
    case estado is
        when a =>
            if y_i = '1' then
                estaprox <= c;
                z_o <= '1';
            else
                estaprox <= b;
                z_o <= '0';
            end if;

        when b =>
            if y_i = '1' then
                estaprox <= e;
                z_o <= '1';
            else
                estaprox <= d;
                z_o <= '0';
            end if;

        when c =>
            if y_i = '1' then
                estaprox <= e;
                z_o <= '0';
            else
                estaprox <= d;
                z_o <= '1';
            end if;

        when d =>
            if y_i = '1' then
                estaprox <= g;
                z_o <= '1';
            else
                estaprox <= f;
                z_o <= '0';
            end if;

        when e =>
            if y_i = '1' then
                estaprox <= g;
                z_o <= '0';
            else
                estaprox <= f;
                z_o <= '1';
            end if;

        when f =>
            if y_i = '1' then
                estaprox <= i;
                z_o <= '1';
            else
                estaprox <= h;
                z_o <= '0';
            end if;

        when g =>
            if y_i = '1' then
                estaprox <= i;
                z_o <= '0';
            else
                estaprox <= h;
                z_o <= '1';
            end if;

        when h =>
            if y_i = '1' then
                estaprox <= k;
                z_o <= '1';
            else
                estaprox <= j;
                z_o <= '0';
            end if;

        when i =>
            if y_i = '1' then
                estaprox <= k;
                z_o <= '0';
            else
                estaprox <= j;
                z_o <= '1';
            end if;

        when j =>
            if y_i = '1' then
                estaprox <= a;
                z_o <= '1';
            else
                estaprox <= a;
                z_o <= '0';
            end if;

        when k =>
            if y_i = '1' then
                estaprox <= a;
                z_o <= '0';
            else
                estaprox <= a;
                z_o <= '1';
            end if;

        when others =>
            z_o <= '0';
            estaprox <= a;

    end case;
end process Combinacional;
end architecture EstaNoAsig;
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You need to add some default assignments:

process (y_i, estado)
begin
  --default assignments
  estaprox <= estado;    -- stay in the current state, unless the case statement calculates a 'jump'
  z_o      <= '0';       -- assign all outputs with a default value to prevent latches

  -- next state calculations
  case estado is
    when a =>
      if y_i = '1' then
        estaprox <= c;
        z_o      <= '1';
  [...]
  end case;
end process Combinacional;

Three additional hints:

  • Some time in the future, you'll get into trouble with these short state names, if you decide to use these also as signal names: One solution could be a prefix "st_" for every state name.
  • Signal estado should have a default value (start-up value):
    signal estado : tipo_estado := a;
  • You can shorten some states, if you want to :)

    when j =>
      estaprox <= a;
      z_o      <= y_i;
    
    when k =>
      estaprox <= a;
      z_o      <= not y_i;
    
\$\endgroup\$
3
  • \$\begingroup\$ I added estaprox <= estado; and z_o <= '0', but it's still the same, not working. Thanks anyway. \$\endgroup\$
    – cventu
    Dec 15, 2014 at 23:29
  • \$\begingroup\$ That's strange I can find any other 'bug'. Adding these two lines should have solved the problem. Have you recompiled everything from scratch? -- One more question: do you have 11 latches in stead of 11 flip flops, or do you have 22 memory elements: 11x flip flop and 11x latch? Does Quartus report for which signal it infers the latches? \$\endgroup\$
    – Paebbels
    Dec 15, 2014 at 23:41
  • \$\begingroup\$ Yes, I recompile everything. I have 11 flip-flops + 13 logic elements. \$\endgroup\$
    – cventu
    Dec 15, 2014 at 23:58

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.