I have an array of vectors that I want to be stored in Block RAM on a Virtex-5 using ISE 13.4. It is 32Kb which should fit in 1 BRAM but it is all being stored in logic. My system uses an AMBA APB bus so I check for a select line and an enable line. Please help me understand why this code isn't inferring a BRAM. Note: this is a dummy example which is simpler to understand and should help me with my other code.
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;
I declare the ram_style
of the array as block
but the XST report says: WARNING:Xst:3211 - Cannot use block RAM resources for signal <Mram_memory>. Please check that the RAM contents is read synchronously.
It appears that the problem lies in a read_enable condition, but the Virtex 5 User Guide makes it sound like there is an enable
and a write_enable
on the BRAM hard blocks. I could drive the output all the time, but I don't want to and that would waste power. Any other ideas?
I tried many different combinations and here is the only one I got to work:
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;
So I think the enable needs to be on the whole RAM and it can only be 1 signal. Then the write enable can also only be 1 signal and the read has to be only an else
statement (not if/elsif
). This instantiates a BRAM according to XST in ISE 13.3 on Windows 7 64-bit.