为什么这个VHDL不能在XST中推断BRAM?

时间:2012-06-21 02:25:05

标签: xilinx synthesis virtex

我有一组向量,我希望使用ISE 13.4将其存储在Virtex-5的Block RAM中。它是32Kb,应该适合1 BRAM,但它都存储在逻辑中。我的系统使用AMBA APB总线,因此我检查选择线和启用线。请帮助我理解为什么这段代码没有推断出BRAM。注意:这是一个虚拟的例子,它更容易理解,并且可以帮助我使用其他代码。

architecture Behavioral of top is
type memory_array is array (63 downto 0) of std_logic_vector(31 downto 0);
signal memory : memory_array;

attribute ram_style: string;
attribute ram_style of memory : signal is "block";

begin

process(Clk)
begin
    if(rising_edge(Clk)) then
        if(Sel and Wr_en and Enable) = '1' then
            memory(to_integer(Paddr(5 downto 0))) <= Data_in;
        elsif(Sel and not Wr_en and Enable) = '1' then
            Data_out <= memory(to_integer(Paddr(5 downto 0)));
        end if;
    end if;
end process;

end Behavioral;

我将数组的ram_style声明为block,但XST报告显示:WARNING:Xst:3211 - Cannot use block RAM resources for signal <Mram_memory>. Please check that the RAM contents is read synchronously.

问题似乎在于read_enable条件,但Virtex 5用户指南听起来像BRAM硬块上有enablewrite_enable。我可以一直驱动​​输出,但我不想,这会浪费电力。还有其他想法吗?

3 个答案:

答案 0 :(得分:2)

您的逻辑可能与设备的BRAM工作方式不匹配(根据设备的不同,存在各种限制)。通常,data_out会在启用RAM的每个时钟周期更新,而不仅仅是“不写时” - 试试这个:

process(Clk)
begin
    if(rising_edge(Clk)) then
        if(Sel and Enable) = '1' then
            Data_out <= memory(to_integer(Paddr(5 downto 0)));
            if wr_en = '1' then
                memory(to_integer(Paddr(5 downto 0))) <= Data_in;
            end if;
        end if;
    end if;
end process;

我将Data_out分配“向上”移动,以明确它获得“旧”值 - 这是BRAM的默认行为,但也可以设置其他样式。

或者,这些工具可能会被selenable以及write声明混淆在一个if语句中 - 这是因为它们主要是“模板匹配“推断BRAM时”而不是“功能匹配”。您可能会发现简单地拆分“enable if”和“write if”(如上所述),同时保持其余功能相同,足以使合成器完成所需的操作。

如果您正在使用Xilinx的XST,那么您可以在文档中阅读所有关于推断RAM的信息(我的XST用户指南第204页 - 该章称为“RAM HDL编码技术”)

答案 1 :(得分:1)

在设备上为BRAM块使用适当的宏?我发现要比依赖合成工具更好地工作,而不是愚蠢的。

答案 2 :(得分:1)

我尝试了很多不同的组合,这是我唯一能够工作的组合:

en_BRAM <= Sel and Enable;

process(Clk)
begin
    if(rising_edge(Clk)) then       
        if(en_BRAM = '1')then
                if(Wr_en = '1') then
                    icap_memory(to_integer(Paddr(5 downto 0))) <= Data_in;
                else
                    Data_out <= icap_memory(to_integer(Paddr(5 downto 0)));         
                end if;
        end if;
    end if;
end process;

所以我认为启用需要在整个RAM上,它只能是1个信号。然后写使能也只能是1信号,而读必须只是else语句(不是if/elsif)。这根据Windows 7 64位ISE 13.3中的XST实例化BRAM。