FPGA-FAQ    0031

How to initialize Block RAM

Vendor Xilinx
FAQ Entry Author Brian Philofsky
FAQ Entry Editor Philip Freidin
FAQ Entry Date 4/9/2002     updated  10/13/2003

Q. How to initialize BRAM


When you initialize block RAMs, in a synthesis flow, you need to specify the initialization twice,
once for synthesis to pass on to the place and route software, and once for the simulation software. 

When using VHDL, in order to pass INIT information during synthesis, VHDL attributes are used
in the VHDL code in which the RAMs have been instantiated.  The attributes are  placed after the
architecture definition but before the BEGIN keyword: 

-- The attribute needs to be only defined once for each attribute name 

attribute INIT_00: string; 
attribute INIT_01: string; 

-- The label for an attribute (the assigned value) will need to be done for each instance of 
-- the block RAM 

attribute INIT_00 of U1 : label is "f0c33cf0f0f00f0ff0f00f0f0f3cc30ffc03fcc003fc033ffcc03fc0033fc03f"; 
attribute INIT_01 of U1 : label is "000000000000000000000000000000006a52a92aaa6aa5a995a5565554954a56"; 

For Verilog synthesis, the attribute is generally embedded in a comment.  The format for the
attributes passed by synthesis tools are different for each synthesis program so you must
consult the synthesis tool documentation for the correct syntax. 

For simulation, the INIT information must be passed by a defparam if you are using Verilog
or a generic if using VHDL.  Since most synthesis tools do not properly understand the
defparams and generics, they typically need the be isolated from the synthesis tool by
using translate_off and translate_on synthesis directives. 

The user must ensure that values passed for simulation match that for implementation or else
the front-end simulation may not match the results given after place and route. 

The reason for the need to specify this information twice is an unfortunate disconnect
between passing attributes for synthsis and passing attributes for simulation.  Simulators
can not parse VHDL or Verilog attributes by definition of the language and Synthesis
tools generally do not recognize generics and defparams.

                Verilog       VHDL
Simulation      defparam      generic
Synthesis       attribute     attribute

For more information, try this:  go to http://www.xilinx.com/support/support.htm and
search for the following article numbers (or click these links):

    10073            FPGA express info
    10076            FPGA express info
    10695            XST info
      2104            Synplicity

Starting with the 4.1i release, XST can now understand generics and use them for
passing INIT attributes.  This means when using this synthesis tool, you no longer
need or are encouraged to use attributes to pass this information.  In order for XST
to be able to "see" the generics, translate_off and translate_on directives should not
be used in the code to mask this information.  Below is an example using this technique.

-- Sample code using XST passing INITs via generics -- 

library IEEE; 
use IEEE.std_logic_1164.all; 

library unisim; 
use unisim.vcomponents.all; 

entity Ram is 
       clk : in std_ulogic; 
       ADDR : in STD_LOGIC_VECTOR(11 downto 0); 
       dout : out STD_LOGIC_VECTOR(11 downto 0) 
end Ram; 

architecture Ram of Ram is 

---- Component declarations ----- 

component RAMB4_S1 
       INIT_00 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_01 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_02 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_03 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_04 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_05 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_06 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_07 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_08 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_09 : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0A : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0B : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0C : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0D : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0E : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000"; 
       INIT_0F : BIT_VECTOR := X"0000000000000000000000000000000000000000000000000000000000000000" 
  port ( 
       ADDR : in STD_LOGIC_VECTOR(11 downto 0); 
       CLK : in std_ulogic; 
       DI : in STD_LOGIC_VECTOR(0 downto 0); 
       EN : in std_ulogic; 
       RST : in std_ulogic; 
       WE : in std_ulogic; 
       DO : out STD_LOGIC_VECTOR(0 downto 0) 
end component; 

----     Constants     ----- 
constant VCC_CONSTANT   : STD_LOGIC := '1'; 
constant GND_CONSTANT   : STD_LOGIC := '0'; 

---- Signal declarations used on the diagram ---- 

signal GND : STD_LOGIC; 
signal VCC : STD_LOGIC; 

---- Configuration specifications for declared components  


----  Component instantiations  ---- 

U1 : RAMB4_S1 
  generic map ( 
       INIT_00 => X"f0c33cf0f0f00f0ff0f00f0f0f3cc30ffc03fcc003fc033ffcc03fc0033fc03f", 
       INIT_01 => X"000000000000000000000000000000006a52a92aaa6aa5a995a5565554954a56", 
       INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_04 => X"ffcccc33f3cccc33cc3333cfcc3333ffcf30f30cf30c00ffff0030cf30cf0cf3", 
       INIT_05 => X"73733939ccccc7c7e3e333339c9ccecefcc0033ff0030ffc3ff0c00ffcc0033f", 
       INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_08 => X"f030300c000f0fcff3f0f000300c0c0ffff00ff30ff0300ff00c0ff0cff00fff", 
       INIT_09 => X"f81ffa07fa05fa05a05fa05fe05ff81ff300cff3cff3300ff00ccff3cff300cf", 
       INIT_0A => X"ff00abd5ff002addbb5400ffabd500ff4df3df3004ff4df3cfb2ff200cfbcfb2", 
       INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", 
       INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000" 
  port map( 
       ADDR => ADDR, 
       CLK => CLK, 
       DI(0) => GND, 
       DO(0) => dout(0), 
       EN => VCC, 
       RST => GND, 
       WE => GND 

---- Power , ground assignment ---- 


end Ram; 


UPDATE:  4/9/2002

A reader of C.A.F was having problems with Sim and Synth of the 16X1 ROMs, and I pointed him
at this page. It solved his problems, and he posted the following:


Thank you very much, Philip.  I tried the suggested approach, and modified it
for the ROM16X1 as shown below, and successfully synthesized it using Xilinx
WebPack V4.1 and simulated it using ModelSimXE V5.5b:
library IEEE, unisim; 
use IEEE.std_logic_1164.all;
use unisim.vcomponents.all;

entity rom is 
   port (clk : in std_logic;
      addr: in std_logic_vector(3 downto 0);
      dout: out std_logic); 
   end rom; 

architecture rom of rom is 

-- component declarations --
component ROM16X1
   generic(init : bit_vector := x"0000");
   port (O : out std_logic; 
         A0: in std_logic; 
         A1: in std_logic; 
         A2: in std_logic; 
         A3: in std_logic);
end component;
-- constant declarations --

-- signal declarations --
signal tout : std_logic;

-- configuration specifications for declared components --


-- component instantiations --
   U1 : ROM16X1
      generic map(init => x"5123")
      port map (O => tout, 
                A0 => addr(0), 
                A1 => addr(1),
                A2 => addr(2),
                A3 => addr(3)); 

-- processes -- 
   process(clk) begin
      if clk'event and clk = '1' then
         dout <= tout;
      end if;
   end process;
end rom;

It's my understanding that as of ISE4.1i, we can now use generics to initialize
the memory, instead of having to use attributes.  So I left out the attribute
statements.  I haven't tested this in hardware, so I'm assuming that it
synthesizes correctly.  I get no synthesizer errors.


UPDATE:  10/13/2003

If you are using Synplify Pro, the 7.3.3 release now supports
passing the INIT values using generics or defparams. This allows
the INIT values and other component attributes to be entered only
once for synthesis and simulation as a generic or defparam. It
should be less error prone than remembering to change both
the attribute for synthesis and the generic/defparam for simulation.

Synplicity FAE - Colorado/Utah