2

我有一个向量数组,我想使用 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 硬块上有一个enable和一个write_enable。我可以一直驱动​​输出,但我不想这样做,那样会浪费功率。还有其他想法吗?

4

3 回答 3

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 的默认行为,尽管也可以设置其他样式。

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

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

于 2012-06-21T08:59:07.253 回答
1

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

于 2012-06-21T02:33:56.760 回答
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。

于 2012-06-21T18:36:01.273 回答