Vivado VHDL 闩锁移除

问题描述 投票:0回答:1

我正在使用 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]

我试着查看警告中列出的代码行,并尝试遵循我能在网上找到的一些指导,但我仍然不明白我应该做什么来解决这个问题。

vhdl vivado
1个回答
0
投票

要正确合成时钟寄存器,请使过程对时钟上升沿敏感。第二个过程没有这个问题,因为你在那里使用

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

(参见:clk'event vs rising_edge()

© www.soinside.com 2019 - 2024. All rights reserved.