Solutions Database
Foundation XVHDL: Using RAM and ROM in XC4000 devices
Record #1485
Product Family: Software
Product Line: Metamor
Problem Title:
Foundation XVHDL: Using RAM and ROM in XC4000 devices
Problem Description:
The information in this Solution Record assumes the use of XVHDL v2.4 or later.
Please note that this is NOT the version that is included with
Foundation version 6.0.1. Also, this solution and others like it are
contained in the Foundation Documentation Update Pack. XVHDL v2.4.4 and
the Documentation Update Pack are available from Xilinx:
(Xilinx File ftp://ftp.xilinx.com/pub/swhelp/foundation/spxv.exe)
(Xilinx File ftp://ftp.xilinx.com/pub/swhelp/foundation/fnddoc1a.exe)
The XC4000 family has the capability to implement on-chip RAM and ROM efficientl
y using CLB function generators.
Using RAM
There are 2 ways to implement RAM using Foundation VHDL.
1. Use Memory Generator to generate an XNF file for the memory,
and then instantiate the XNF file.
2. Instantiate 16x1 and 32x1 RAM primitives.
*Note: Do NOT describe RAM behaviorally in VHDL, as this results in combinatori
al loops.
Using ROM
There are 3 ways to implement ROM using Foundation VHDL.
1. Use the Memory Generator to generate an XNF file for the memory,
and then instantiate the XNF file.
2. Instantiate ROM primitives.
3. Describe ROM behaviorally.
Solution 1:
Using ROM
---------
1. Use Memory Generator to generate an XNF file for the
memory, and then instantiate the XNF file.
Option 1 follows the same procedure as described for RAM in
the resolution titled "Using RAM".
When using ROM, be sure that there is a .MEM file in your
project directory describing the contents of the ROM. More
detail on the format of the .MEM file can be found in the
'MEMGEN' chapter of the Xilinx Development Systems Reference
Guide, Vol. 1.
2. Instantiating ROM primitives.
ROM 16x1 or 32x1 primitives may be instantiated using the
following method. An INIT attribute must be added to the
instantiated ROM component to describe the contents of the
ROM. The INIT attribute is a HEX value: 4 digits for a 16x1
ROM, and 8 digits for a 32x1 ROM. Note that the name of the
component is just ROM, and the 'SCHNM' attribute determines
whether it is a 16x1 ROM or a 32x1 ROM.
A 'DEF' attribute must also be attached to the instantiated
component, with the value 'ROM'. See example below.
--Example of instantiating a ROM primitive
library IEEE;
use IEEE.std_logic_1164.all;
library METAMOR;
--Package attributes contains declarations of the Metamor
--specific synthesis attributes.
use METAMOR.attributes.all;
entity ROM_INST is
port (ADDR0, ADDR1, ADDR2, ADDR3: in std_logic;
OUTPUT: out std_logic);
end ROM_INST;
architecture INST of ROM_INST is
component ROM --NOTE: component is declared as just ROM
port (A0, A1, A2, A3: in std_logic;
O: out std_logic);
end component;
attribute INIT: string;
attribute DEF: string;
attribute SCHNM: string;
attribute INIT of U1: label is "1A11";
attribute DEF of U1: label is "ROM";
attribute SCHNM of U1: label is "ROM16X1"; --Determines
--whether component is ROM16x1 or ROM32x1
begin
U1: ROM port map (A0=>ADDR0, A1=>ADDR1, A2=>ADDR2,
A3=>ADDR3, O=>OUTPUT);
end inst;
*Note: When compiling the design with the XACTStep Design
Manager, you must copy the appropriate XNF file (in this case
ROM16X1.XNF) from the \ACTIVE\VHDL\XLNX_LIB\<family> directory
into your project directory, or add the following line to the
XDM.PRO file found in your project directory:
Options XNFMERGE -D \ACTIVE\VHDL\XLNX_LIB\<family>
where <family> is either XC4000 or XC4000E.
3. Describing a ROM behaviorally
--Example of how to describe a 16x4 ROM behaviorally in VHDL.
library IEEE;
use IEEE.std_logic_1164.all;
entity ROM16X4_4K is
port (ADDR: in integer range 0 to 15;
DATA: out std_logic_vector (3 downto 0));
end ROM16X4_4K;
architecture BEHAV of ROM16X4_4K is
subtype ROM_WORD is std_logic_vector (3 downto 0);
type ROM_TABLE is array (0 to 15) of ROM_WORD;
constant ROM: ROM_TABLE := ROM_TABLE'(
ROM_WORD'("0000"),
ROM_WORD'("0001"),
ROM_WORD'("0010"),
ROM_WORD'("0100"),
ROM_WORD'("1000"),
ROM_WORD'("1000"),
ROM_WORD'("1100"),
ROM_WORD'("1010"),
ROM_WORD'("1001"),
ROM_WORD'("1001"),
ROM_WORD'("1010"),
ROM_WORD'("1100"),
ROM_WORD'("1001"),
ROM_WORD'("1001"),
ROM_WORD'("1101"),
ROM_WORD'("1111"));
begin
DATA <= ROM(ADDR);
end BEHAV;
Solution 2:
Using RAM
---------
1. Using the Memory Generator with instantiation
a) From the Foundation Project Manager, select Applications ->
Memory Generator
b) Choose the type and size of RAM you want, give it a name,
and click 'Generate'. This will create an XNF file for the
RAM component.
c) Instantiate the XNF file in the VHDL code.
The names of the pins on the RAM follow the same naming
convention as the RAM components in the Xilinx Libraries Guide,
so you really only need to be concerned with the number of
inputs, addresses, and outputs, which is dependent on the size
of the RAM. If there is any doubt as to the names of the ports,
the names of the pins on the RAM component can be found in the
XNF file which was produced by the Memory Generator.
The following is an example of this method. Note also the use
of the 'macrocell' attribute. This attribute allows for the
use of vector pins as opposed to single-bit pins. If this
attribute is not used, the pin expansion of the vectors will be
incompatible, and the resulting XNF netlist will not compile
correctly. Declare the Metamor library when using this
attribute.
The second example of instantiating RAM uses single-bit pins,
and thus the 'macrocell' attribute is not necessary.
--Example of Instantiating XNF file Created with the Memory --Generator
--This is an example of a 16x2 Dual-Port RAM
library IEEE;
use IEEE.std_logic_1164.all;
library METAMOR;
--Package attributes contains declarations of the Metamor
--specific synthesis attributes.
use METAMOR.attributes.all;
entity DUAL_PORT is
port(ADD, DPRADD: in std_logic_vector (3 downto 0);
WR_EN, WR_CLK, DATA0, DATA1: in std_logic;
SPOUT, DPOUT: out std_logic_vector (1 downto 0));
end DUAL_PORT;
architecture FROM_MEMGEN of DUAL_PORT is
component MEMGEN_M --memgen_m.xnf is the XNF file created
-- by Memory Generator
port(A,DPRA: in std_logic_vector (3 downto 0);
WE,WCLK,D0,D1: in std_logic;
SPO,DPO: out std_logic_vector (1 downto 0));
end component;
attribute macrocell of MEMGEN_M: component is true;
begin
U1: MEMGEN_M port map (A=>ADD, DPRA=>DPRADD,
WE=>WR_EN, WCLK=>WR_CLK, D0=>DATA0,
D1=>DATA1, SPO=>SPOUT, DPO=>DPOUT);
end FROM_MEMGEN;
2. Instantiating RAM primitives.
RAM 16x1 and 32x1 primitives from the XC4000 Unified Library
may be instantiated directly into a VHDL file as shown below.
--Example of instantiating a RAM16X1D primitive.
library IEEE;
use IEEE.std_logic_1164.all;
entity DP_RAM is
port (WR, DATA, CLK: in std_logic;
ADDR0, ADDR1, ADDR2, ADDR3: in std_logic;
DPRA0, DPRA1, DPRA2, DPRA3: in std_logic;
SPOUT, DPOUT: out std_logic);
end DP_RAM;
architecture INST of DP_RAM is
component RAM16X1D
port (D, WE, WCLK, A3, A2, A1, A0,
DPRA3, DPRA2, DPRA1, DPRA0: in std_logic;
SPO,DPO: out std_logic);
end component ;
begin
U1: RAM16X1D port map (D=>DATA, WE=>WR, WCLK=>CLK, A3=>ADDR3,
A2=>ADDR2, A1=>ADDR1, A0=>ADDR0,
DPRA3=>DPRA3, DPRA2=>DPRA2,
DPRA1=>DPRA1, DPRA0=>DPRA0,
SPO=>SPOUT, DPO=>DPOUT);
end INST;
*Note: When compiling the design with the XACTStep Design
Manager, you must copy the appropriate XNF file (in this case
RAM16X1D.XNF) from the \ACTIVE\VHDL\XLNX_LIB\<family> directory
into your project directory, or add the following line to the
XDM.PRO file found in your project directory:
Options XNFMERGE -D \ACTIVE\VHDL\XLNX_LIB\<family>
where <family> is either XC4000 or XC4000E.
End of Record #1485