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.
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".
5. Now we want to test whether the bram is correctly initialized. I have written the following testbench file for this.
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.
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.
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.
How to write the contents of BRAM in a text file, without using textio?
ReplyDeletehttps://www.youtube.com/watch?v=zX4tZPBL9oY
ReplyDeleteJigar Mori's link is dead.
ReplyDelete