我有一组向量,我希望使用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
。我可以一直驱动输出,但我不想,这会浪费电力。还有其他想法吗?
答案 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的默认行为,但也可以设置其他样式。
或者,这些工具可能会被sel
和enable
以及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。