We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 7929

EXEMPLAR - How do I infer Virtex Block RAM in HDL? (Verilog/VHDL)


Keywords: block RAM, select RAM, single, dual, port, block_ram, Leonardo, init

Urgency: Standard

General Description:
Leonardo Spectrum can map memory statements in Verilog or VHDL to the block RAMs on all Virtex devices.

The following is a list of details for block RAMs in Leonardo Spectrum:

- Virtex Block RAMs are completely synchronous. Both read and write operations are synchronous.

- Leonardo Spectrum infers the following Block RAM configuration:
1. Single-port RAMs or RAMs with both read and write on the same address.
2. Dual-port RAMs - RAMs with separate read and write addresses. (Write from Port A, Read from Port B)

- Leonardo Spectrum does not infer the following configurations:
1. Dual-port RAMs that read and write from both A and B ports.
2. Block RAMs that use the functionality of the RST and ENA pins.

Set the following variable to "false" if you do not want RAM extraction: (The default is TRUE.)

set extract_ram false

By default, RAMs that are mappable to block RAMs are mapped to block RAMs. You can disable mapping to block RAMs by setting the attribute block_ram to "false," as follows:

set_attribute -name block_ram -value false

In this case, the RAM is implemented using select RAMs if possible.

- The variant of single-port RAM that is implemented using block RAMs cannot be implemented using select RAMs.

- For dual-port Block RAM inference, please see (Xilinx Answer 10728).

- Initializing inferred RAM in the HDL code is currently not supported. To do this, obtain the instance name of the RAM from Leonardo Spectrum's schematic viewer or from the EDIF netlist, and apply the INIT attribute in the UCF file. (The inferred RAMs are initialized to "0" (zero) by default.)



Verilog Example:
(Tested in Leonardo Spectrum 1999.1f)

module ram(din, we, addr, clk, dout);
parameter data_width=7, address_width=6,mem_elements=64;
input [data_width-1:0] din;
input [address_width-1:0] addr;
input we, clk;
output [data_width-1:0] dout;

reg [data_width-1:0] mem[mem_elements-1:0];
// Exemplar attribute mem block_ram FALSE

/* Use the directive above ONLY if you want to disable Block RAM extraction.
Set the block_ram attribute to FALSE on the signal memory.
The block_ram attribute must be set on the memory signal. */

reg [address_width - 1:0] addr_reg;

always @(posedge clk)
addr_reg <= addr;
if (we)
mem[addr] <= din;

assign dout = mem[addr_reg];



VHDL Example of Block RAMs
(Tested in Leonardo Spectrum 1999.1f)

library ieee, exemplar;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ram_example1 is
generic(data_width: integer:= 8;
address_width:integer := 8;
mem_depth: integer:= 256);

port (data: in std_logic_vector(data_width-1 downto 0);
address: in unsigned(address_width-1 downto 0);
we, clk: in std_logic;
q: out std_logic_vector(data_width-1 downto 0));
end ram_example1;

architecture ex1 of ram_example1 is

type mem_type is array (mem_depth-1 downto 0) of std_logic_vector (data_width-1 downto 0);
signal mem: mem_type;
signal raddress : unsigned(address_width-1 downto 0);

l0: process (clk, we, address)
if (clk = '1' and clk'event) then
raddress <= address;
if (we = '1') then
mem(to_integer(raddress)) <= data;
end if;
end if;
end process;

l1: process (clk, address)
if (clk = '1' and clk'event) then
q <= mem(to_integer(address));
end if;
end process;

end ex1;
AR# 7929
Date Created 10/25/1999
Last Updated 04/24/2007
Status Archive
Type General Article