xilinxsynthesisvirtex

Why isn't this VHDL inferring BRAM in XST?


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?


Solution

  • 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.