VHDL coding tips and tricks: How to Initialize a Block RAM IP in Xilinx Vivado? (With Testbench)

Sunday, October 31, 2010

How to Initialize a Block RAM IP in Xilinx Vivado? (With Testbench)

THIS ARTICLE WAS UPDATED on 19-04-2024. OLD ARTICLE USED XILINX ISE INSTEAD OF VIVADO.

    This article is a continuation of my earlier post, How to use Xilinx Vivado's IP Catalog to create a BRAM? (With Testbench), where I explained the steps to create a Block RAM IP in Xilinx Vivado tool.

    In there, I initialized the bram contents to zero on power up. But you can initialize it with non-zero values as well. How do we do that? It can be done with a special file, which has an extension coe.

    Let me show you how this can be done with few screenshots. Note that you should first follow the instructions from the old article to set up a BRAM as per the settings given there, before proceeding with the rest of this article.

1. In the "Other options" tab in the IP settings, check the checkbox "Load Init File". To add the coe file, click on "Edit" option. Click on "Yes" when the following dialogue box opens up.

create ceo file for bram xilinx vivado

2. Type a filename. I gave the name as "bram_contents.coe". Click on "Save".

3. The following window shows up. Enter the radix of the values. Add the list of values as shown in the screenshot. Click on "Save" and then click on "Close".

how to edit coe file in xilinx vivado

4. Now click on "Ok" and then on "Generate" to generate the IP core.

5. Now we want to test whether the bram is correctly initialized. I have written the following testbench file for this.

library ieee;
use ieee.std_logic_1164.all;

--empty entity for testbench
entity tb_bram is
end tb_bram;

architecture Behavioral of tb_bram is

--copy paste the port declaration of the bram from the xilinx generated file.
component bram_test is
  PORT (
    clka : IN STD_LOGIC;
    ena : IN STD_LOGIC;
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
  );
end component;

--port signals for connecting with the bram
signal clka, ena : std_logic := '0';
signal wea : std_logic_vector(0 downto 0) := "0";
signal addra, dina, douta : std_logic_vector(7 downto 0) := (others => '0');
constant clk_period : time := 10 ns; --clock period.

begin

--componenent instantiation using named association.
bram : bram_test port map(
    clka => clka,
    ena => ena,
    wea => wea,
    addra => addra,
    dina => dina,
    douta => douta);

--generate the clock for bram
clk_generation: process
begin
    wait for clk_period/2;
    clka <= not clka;
end process;

--this is where we generate the inputs to apply to the bram
stimulus: process
begin
    wait for clk_period;
    ena <= '1';
    wea <= "0";
    addra <= x"00"; wait for clk_period;
    addra <= x"01"; wait for clk_period;
    addra <= x"02"; wait for clk_period;
    addra <= x"03"; wait for clk_period;
    addra <= x"04"; wait for clk_period;
    addra <= x"05"; wait for clk_period;
    addra <= x"06"; wait for clk_period;
    wait;
end process;

end Behavioral;

6. Once we simulate it, we will get the following simulation waveform. You can see that the first 5 memory locations(addresses 0 to 5) are correctly initialized from 1 to 5, and the rest with zeros.

simulation waveform of bram xilinx vivado


Note :- coe file has different uses. Here we used it to initialize the contents of a BRAM. For an FIR filter, we can use it to specify the filter coefficients.

I have used Xilinx Vivado 2023.2 tool for this article.

If you prefer to see this in action, watch this Youtube video I have created.



3 comments:

  1. How to write the contents of BRAM in a text file, without using textio?

    ReplyDelete
  2. https://www.youtube.com/watch?v=zX4tZPBL9oY

    ReplyDelete