Vivado VHDL锁存器去除

huangapple go评论57阅读模式
英文:

Vivado VHDL latch removal

问题

在综合项目时,Vivado指出除了W_FILTER进程使用的internal_regChannelinternal_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)

huangapple
  • 本文由 发表于 2023年5月10日 20:04:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218187.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定