我正在使用 VHDL 和 Vivado 作为一种时钟滤波器,当输入
i_w
被给定并保持活动状态时,它一次从 i_start
通道读取一位,将其转换为内存地址,然后从中读取,最后它加载四个不同寄存器之一的地址内的值,也取决于读取i_w
信号的前两位,并输出“完成”信号以通知它已完成。
我创建了一个内部计数器,用于跟踪从读取开始已经过去了多少个时钟周期。
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;
但是,在综合项目时,Vivado 会在所有信号上发出 6 个推断锁存器,除了
W_FILTER
过程使用的信号,internal_regChannel
和 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_clk = '1' and i_clk'event
.
但是在您使用的第一个过程中:
else if i_clk = '1' and i_start = '1' then
改成
elsif i_clk = '1' and i_clk'event then
if i_start = '1' then
或更好
elsif rising_edge(i_clk) then
if i_start = '1' then