I'm using VHDL and Vivado for a sort of clocked filter that reads one bit at a time from an i_w
channel when an input i_start
is given and stays active, converting it into a memory address from which it then reads, and finally it loads the value inside of the address in one of four different registers, also depending on the first two bits read of the i_w
signal, and outputs a "done" signal to notify that it has finished.
I've created an internal counter that keeps track of how many clock cycles have elapsed from the reading start.
architecture rtl of project is
--Counter
signal internal_counter: std_logic_vector(4 downto 0);
signal internal_done: std_logic := '0';
--Addresses
signal internal_regChannel: std_logic_vector(1 downto 0);
signal internal_memAddress: std_logic_vector(15 downto 0);
--Registry Bank
signal internal_regValue0: std_logic_vector(7 downto 0);
signal internal_regValue1: std_logic_vector(7 downto 0);
signal internal_regValue2: std_logic_vector(7 downto 0);
signal internal_regValue3: std_logic_vector(7 downto 0);
begin
COUNTER: process(i_clk)
begin
if i_rst ='1' then
--reset the counter
internal_counter <= (others => '0');
internal_done <= '0';
else
if i_clk = '1' and i_start = '1' then
--start counting
internal_counter <= internal_counter + 1;
internal_done <= '0';
else
internal_counter <= internal_counter;
end if;
if i_clk = '1' and internal_counter /= "00000" then
--keep counting
internal_counter <= internal_counter + 1;
internal_done <= '0';
end if;
if i_clk = '1' and internal_counter = "10100" then
--the counter has finished
--count for one more cycle so then the done signal can be put back to 0
internal_counter<= internal_counter + 1;
internal_done <= '1';
end if;
if i_clk = '1' and internal_counter = "10101" then
internal_counter <= "00000";
internal_done <= '0';
end if;
end if;
end process;
W_FILTER: process(i_clk)
begin
if i_rst ='1' then
internal_memAddress <= (others => '0');
internal_regChannel <= (others => '0');
else
if i_clk = '1' and i_clk'event then
if i_start = '1' and internal_counter < "00010" then
--generate the registry Flag
internal_regChannel <= internal_regChannel(0) & i_w;
else if i_start = '1' and internal_counter >= "00010" then
--generate the memory Address
internal_memAddress <= internal_memAddress(14 downto 0) & i_w;
end if;
end if;
if i_start = '0' and internal_counter > "00000" then
--memory address is safe to output
o_mem_addr <= internal_memAddress;
end if;
if internal_done = '1' then
internal_memAddress <= (others => '0');
internal_regChannel <= (others => '0');
end if;
end if;
end if;
end process;
REG_BANK: process(i_clk)
begin
if i_rst = '1' then
internal_regValue0 <= (others => '0');
internal_regValue1 <= (others => '0');
internal_regValue2 <= (others => '0');
internal_regValue3 <= (others => '0');
else
if internal_counter = "10100" then
case internal_regChannel is
when "00" =>
internal_regValue0 <= i_mem_data;
when "01" =>
internal_regValue1 <= i_mem_data;
when "10" =>
internal_regValue2 <= i_mem_data;
when "11" =>
internal_regValue3 <= i_mem_data;
when others =>
--placeholder; others condition can never occur
internal_regValue0 <= i_mem_data;
end case;
end if;
end if;
end process;
o_done <= internal_done;
end rtl;
However, when synthesizing the project, Vivado signals 6 inferred latches on all the signals, except for the one used by the W_FILTER
process, internal_regChannel
and internal_memAddress
.
WARNING: [Synth 8-327] inferring latch for variable 'internal_done_reg' [C:/.../project.vhd:57]
WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue0_reg' [C:/.../project.vhd:114]
WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue1_reg' [C:/.../project.vhd:115]
WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue2_reg' [C:/.../project.vhd:116]
WARNING: [Synth 8-327] inferring latch for variable 'internal_regValue3_reg' [C:/.../project.vhd:117]
WARNING: [Synth 8-327] inferring latch for variable 'internal_counter_reg' [C:/.../project.vhd:56]
I tried looking at the lines of code listed in the warnings, and I tried to follow what little guidance I could find online, but I still fail to understand what I should be doing to fix this issue.