Search code examples
embeddedvhdlfpgaxilinx

BRAM_INIT in VHDL


I am simulating a processor based design where the program memory contents are held in a BRAM. I am realizing the program memory using VHDL (inferring BRAMs). I am trying to avoid CoreGen because I want to keep the design portable. Eventually this design will go to an FPGA.

I am looking to see if there is a way to initialize memory contents of the BRAMs using VHDL generics ? I understand that Coregen uses COE file to initialize the BRAM but do we have a VHDL code based way to do this ?

Let me know your alternate suggestions as well.


Solution

  • Yes it is certainly possible. Take a look at the Xilinx Synthesis Tool (XST) User guide, specifically page 187.

    The code they recommend to do this is reproduced below. They have notes in the user guide regarding the formatting of the file that will be read. Note that this code doesn't directly use generics, but I could imagine that you could possibly set a constant or generic to hold the name of the filename...

    --
    -- Initializing Block RAM from external data file
    --
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use std.textio.all;
    
    entity rams_20c is
    port(clk : in std_logic;
       we : in std_logic;
       addr : in std_logic_vector(5 downto 0);
       din : in std_logic_vector(31 downto 0);
       dout : out std_logic_vector(31 downto 0));
    end rams_20c;
    architecture syn of rams_20c is
       type RamType is array(0 to 63) of bit_vector(31 downto 0);
       impure function InitRamFromFile (RamFileName : in string) return RamType is
          FILE RamFile : text is in RamFileName;
          variable RamFileLine : line;
          variable RAM : RamType;
       begin
          for I in RamType’range loop
             readline (RamFile, RamFileLine);
             read (RamFileLine, RAM(I));
          end loop;
          return RAM;
       end function;
    signal RAM : RamType := InitRamFromFile("rams_20c.data");
    begin
       process (clk)
       begin
          if clk’event and clk = ’1’ then
             if we = ’1’ then
                RAM(conv_integer(addr)) <= to_bitvector(din);
             end if;
             dout <= to_stdlogicvector(RAM(conv_integer(addr)));
          end if;
       end process;
    end syn;