英文:
Vivado VHDL latch removal
问题
在综合项目时,Vivado指出除了W_FILTER
进程使用的internal_regChannel
和internal_memAddress
外,所有信号上都存在6个隐含的锁存器。这可能是由于逻辑不完整或条件不明确导致的。要解决这个问题,你需要确保在所有可能情况下,信号都有明确定义的值。
另外,确保在所有条件分支中,所有的信号都有被赋值。根据你提供的代码,你可能需要在适当的条件下为这些信号提供默认值,以避免综合工具推断锁存器。最好的方式是在每个条件下都明确地赋值,确保所有的分支都被覆盖。
希望这能帮到你解决问题!
英文:
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.
答案1
得分: 2
To properly synthesize clocked registers, make the process sensitive to the rising clock edge. You don't have this issue for the second process because there you use i_clk = '1' and i_clk'event
.
But in the first process you use:
else
if i_clk = '1' and i_start = '1' then
Change it to
elsif i_clk = '1' and i_clk'event then
if i_start = '1' then
or better
elsif rising_edge(i_clk) then
if i_start = '1' then
(see: https://stackoverflow.com/questions/15205202/clkevent-vs-rising-edge)
英文:
To properly synthesize clocked registers, make the process sensitive to the rising clock edge. You don't have this issue for the second process because there you use i_clk = '1' and i_clk'event
.
But in the first process you use:
> else
> if i_clk = '1' and i_start = '1' then
Change it to
elsif i_clk = '1' and i_clk'event then
if i_start = '1' then
or better
elsif rising_edge(i_clk) then
if i_start = '1' then
(see: https://stackoverflow.com/questions/15205202/clkevent-vs-rising-edge)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论