![]() |
![]() |
XC4000E/EX/XL/XLA and Spartan FPGAs provide distributed on-chip RAM or ROM. CLB function generators can be configured as ROM (ROM16X1, ROM32X1); level-sensitive RAM (RAM16X1, RAM 32X1); edge-triggered, single-port (RAM16X1S, RAM32X1S); or dual-port (RAM16x1D) RAM. Level sensitive RAMs are not available for the Spartan family. The edge-triggered capability simplifies system timing and provides better performance for RAM-based designs. This distributed RAM can be used for status registers, index registers, counter storage, constant coefficient multipliers, distributed shift registers, LIFO stacks, latching, or any data storage operation. The dual-port RAM simplifies FIFO designs.
Note: For more information on XC4000 family RAM, refer to the Xilinx Web site (http://support.xilinx.com) or the current release of The Programmable Logic Data Book.
ROMs can be implemented as follows.
VHDL and Verilog examples of an RTL description of a ROM follow.
--
-- Behavioral 16x4 ROM Example
-- rom_rtl.vhd
--
library IEEE;
use IEEE.std_logic_1164.all;
entity rom_rtl is
port (ADDR: in INTEGER range 0 to 15;
DATA: out STD_LOGIC_VECTOR (3 downto 0));
end rom_rtl;
architecture XILINX of rom_rtl 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'("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'("1011"),
ROM_WORD'("1111"));
begin
DATA <= ROM(ADDR); -- Read from the ROM
end XILINX;
/*
* ROM_RTL.V
* Behavioral Example of 16x4 ROM
*/
module rom_rtl(ADDR, DATA) ;
input [3:0] ADDR ;
output [3:0] DATA ;
reg [3:0] DATA ;
// A memory is implemented
// using a case statement
always @(ADDR)
begin
case (ADDR)
4'b0000 : DATA = 4'b0000 ;
4'b0001 : DATA = 4'b0001 ;
4'b0010 : DATA = 4'b0010 ;
4'b0011 : DATA = 4'b0100 ;
4'b0100 : DATA = 4'b1000 ;
4'b0101 : DATA = 4'b1000 ;
4'b0110 : DATA = 4'b1100 ;
4'b0111 : DATA = 4'b1010 ;
4'b1000 : DATA = 4'b1001 ;
4'b1001 : DATA = 4'b1001 ;
4'b1010 : DATA = 4'b1010 ;
4'b1011 : DATA = 4'b1100 ;
4'b1100 : DATA = 4'b1001 ;
4'b1101 : DATA = 4'b1001 ;
4'b1110 : DATA = 4'b1101 ;
4'b1111 : DATA = 4'b1111 ;
endcase
end
endmodule
When using an RTL description of a ROM, the synthesis tool creates ROMs from random logic gates that are implemented using function generators.
Another method for implementing ROMs is instantiating the 16x1 or 32x1 ROM primitives. To define the ROM value, use the Set Attribute or equivalent command to set the INIT property on the ROM component.
Note: Refer to your synthesis tool documentation for the correct syntax.
This type of command writes the ROM contents to the netlist file so the Xilinx tools can initialize the ROM. The INIT value should be specified in hexadecimal values. See the VHDL and Verilog RAM examples in the following section for examples of this property using a RAM primitive.
Do not use RTL descriptions of RAMs in your code because they do not compile efficiently and can cause combinatorial loops. The exception to this is if your synthesis tool can infer memory. In this case, you must follow a strict coding style. Refer to your vendor's documentation for more information.
You can implement RAMs as follows.
When implementing RAM in XC4000 and Spartan designs, Xilinx recommends using the synchronous write, edge-triggered RAM (RAM16X1S, RAM32X1S, or RAM16X1D) instead of the asynchronous-write RAM (RAM16X1 or RAM32X1) to simplify write timing and increase RAM performance.
Examples of an instantiation of edge-triggered RAM primitives are provided in the following VHDL and Verilog designs. As with ROMs, initial RAM values can be specified from the command line. The INIT property value is specified in hexadecimal values. Refer to your synthesis tool documentation for the correct command and syntax.
An Exemplar™ example of a RAM inference (ram.vhd) is also included in this section. Check with your synthesis tool vendor for the availability of this feature.
------------------------------------------
-- RAM_PRIMITIVE.VHD --
-- Example of instantiating 4 --
-- 16x1 synchronous RAMs --
-- HDL Synthesis Design Guide for FPGAs --
-- May 1997 --
------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity ram_primitive is
port ( DATA_IN, ADDR : in STD_LOGIC_VECTOR(3 downto 0);
WE, CLOCK : in STD_LOGIC;
DATA_OUT : out STD_LOGIC_VECTOR(3 downto 0));
end ram_primitive;
architecture STRUCTURAL_RAM of ram_primitive is
component RAM16X1S
port (D, A3, A2, A1, A0, WE, WCLK : in STD_LOGIC;
O : out STD_LOGIC);
end component;
begin
RAM0 : RAM16X1S port map (O => DATA_OUT(0), D => DATA_IN(0),
A3 => ADDR(3), A2 => ADDR(2),
A1 => ADDR(1), A0 => ADDR(0),
WE => WE, WCLK => CLOCK);
RAM1 : RAM16X1S port map (O => DATA_OUT(1), D => DATA_IN(1),
A3 => ADDR(3), A2 => ADDR(2),
A1 => ADDR(1), A0 => ADDR(0),
WE => WE, WCLK => CLOCK);
RAM2 : RAM16X1S port map (O => DATA_OUT(2), D => DATA_IN(2),
A3 => ADDR(3), A2 => ADDR(2),
A1 => ADDR(1), A0 => ADDR(0),
WE => WE, WCLK => CLOCK);
RAM3 : RAM16X1S port map (O => DATA_OUT(3), D => DATA_IN(3),
A3 => ADDR(3), A2 => ADDR(2),
A1 => ADDR(1), A0 => ADDR(0),
WE => WE, WCLK => CLOCK);
end STRUCTURAL_RAM;
//////////////////////////////////////////
// RAM_PRIMITIVE.V //
// Example of instantiating 4 //
// 16x1 Synchronous RAMs //
// HDL Synthesis Design Guide for FPGAs //
// August 1997 //
//////////////////////////////////////////
module ram_primitive (DATA_IN, ADDR, WE, CLOCK, DATA_OUT);
input [3:0] DATA_IN, ADDR;
input WE, CLOCK;
output [3:0] DATA_OUT;
RAM16X1S RAM0 (.O(DATA_OUT[0]), .D(DATA_IN[0]), .A3(ADDR[3]),
.A2(ADDR[2]), .A1(ADDR[1]), .A0(ADDR[0]),
.WE(WE), .WCLK(CLOCK));
RAM16X1S RAM1 (.O(DATA_OUT[1]), .D(DATA_IN[1]), .A3(ADDR[3]),
.A2(ADDR[2]), .A1(ADDR[1]), .A0(ADDR[0]),
.WE(WE), .WCLK(CLOCK));
RAM16X1S RAM2 (.O(DATA_OUT[2]), .D(DATA_IN[2]), .A3(ADDR[3]),
.A2(ADDR[2]), .A1(ADDR[1]), .A0(ADDR[0]),
.WE(WE), .WCLK(CLOCK));
RAM16X1S RAM3 (.O(DATA_OUT[3]), .D(DATA_IN[3]), .A3(ADDR[3]),
.A2(ADDR[2]), .A1(ADDR[1]), .A0(ADDR[0]),
.WE(WE), .WCLK(CLOCK));
endmodule
library ieee;
use ieee.std_logic_1164.all;
library exemplar;
use exemplar.exemplar_1164.all;
library exemplar;
use exemplar.exemplar.all;
package my_pkg is
type MEM_WORD is array (6 downto 0) of elbit_vector (1 downto 0);
end my_pkg;
=20
library exemplar;
use exemplar.exemplar.all;
use work.my_pkg.all;
entity mem is
port (dio : inout elbit_vector (1 downto 0);=20
meme, we, inclk, outclk : in bit;
addr : integer range 6 downto 0;
ro : out bit);
attribute clock_node : boolean;
attribute clock_node of inclk : signal is TRUE;
attribute clock_node of outclk : signal is TRUE;
=20
end mem;
architecture behav of mem is
signal mem : MEM_WORD;
signal d_int : elbit_vector (1 downto 0);
begin
process (inclk)
begin
if (inclk'event and inclk =3D '1') then
if (meme =3D '1' and we =3D '1') then
mem(addr) <=3D dio;
end if;
end if;
end process;
process (outclk)
begin
if (outclk'event and outclk =3D '1') then
d_int <=3D mem (addr);
end if;
end process;
dio <=3D d_int when (meme =3D '1' and we =3D '0') else "ZZ";
end behav;
If you must instantiate memory, use LogiBLOX to create a memory module larger than 32X1 (16X1 for Dual Port). Implementing memory with LogiBLOX is similar to implementing any module with LogiBLOX except for defining the Memory initialization file. Use the following steps to create a memory module.
Note: Refer to the Using LogiBLOX in HDL Designs section for more information on using LogiBLOX.
Note: Xilinx recommends (this is not a requirement) that you select a memory depth value that is a multiple of 16 because this is the memory size of one lookup table.
Note: Some memory modules can only be initialized to zero. Refer to the Xilinx Programmable Logic Data Book for more information.
depth 16
default 5
data 6,4,
4: 2, 7,
7: 3
Note: If you do not use this type of command, the netlist file may be empty. If this occurs, the Xilinx software will trim this module/component and all connected logic. Refer to your synthesis tool documentation for the correct syntax.
Note: For more information on simulation, refer to the Simulating Your Design chapter.