0
\$\begingroup\$

I have tried many ways but to no avail. It keeps having this warning: inferring latch for variable 'count_reg'.

    begin
process (control)
   variable count : std_logic_vector (3 downto 0) := "0000"; 
    begin
        if control = "001" or control = "010" then 
            address <= count;         
            count :=  count + "0001";
        elsif control = "000" or control = "011" then
            address <= count; 
            --count :=  count; 
        else 
            count := (others => '0'); 
            address<= count;
        end if;           
end process;
\$\endgroup\$
3
  • \$\begingroup\$ How could it possibly work without a latch? \$\endgroup\$
    – venny
    Sep 13, 2015 at 8:54
  • 3
    \$\begingroup\$ There is no count_reg in your code. Secondly, you are describing a counter without a clock. Counters are registered circuits which need a clock signal. \$\endgroup\$
    – Paebbels
    Sep 13, 2015 at 8:54
  • \$\begingroup\$ An unclocked process for a counter is a very bad idea... \$\endgroup\$
    – user16324
    Sep 13, 2015 at 10:45

1 Answer 1

1
\$\begingroup\$

As others have pointed out in the comments, you should use a synchronous (clocked) process for a counter. The fact that your message references count_reg leads me to believe that you have not included all the relevant code.

Any asynchronous process such as the one described by your code will infer a latch for a signal that does not have an assignment in every branch of that process. In your example, the signal count is not assigned in the second branch (elsif control = "000" ...).

In some cases, there may be only one branch that assigns a value other than 'not asserted', usually '0'. In these cases, instead of cluttering every branch with assignments to '0', you can make this assignment right at the start of the process (before the first if), which will serve as a 'default', unless contradicted in one of the branches.

Your counter process should more conventionally look like this:

process (clk)
  variable count : std_logic_vector (3 downto 0) := (others => '0'); 
begin
  if (rising_edge(clk)) then
    if control = "001" or control = "010" then 
      address <= count;         
      count := count + "0001";
    elsif control = "000" or control = "011" then
      address <= count; 
      --count := count; 
    else 
      count := (others => '0'); 
      address <= count;
    end if;           
  end if;           
end process;

It is also clear that you are using the package std_logic_arith. This non-standard package should not be used. Instead, use numeric_std, and declare your count to have type unsigned.

\$\endgroup\$

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.