Dual Port RAM

Free-RAM Home

Introduction

The dual port RAM core is a basic dual ported RAM.  It is designed to be the most common denominator of several FPGA's-- and hence the most portable.

Component Declaration

The basic component declaration of the Free-RAM dual port module is:

component ram_dp
  generic (addr_bits :integer;
           data_bits :integer;
           register_out_flag :integer := 0;
           block_type :integer := 0);
  port (reset :in std_logic;
        wr_clk :in std_logic;
        wr_en :in std_logic;
        wr_addr :in std_logic_vector (addr_bits-1 downto 0);
        wr_data :in std_logic_vector(data_bits-1 downto 0);
        rd_clk :in std_logic;
        rd_addr :in std_logic_vector (addr_bits-1 downto 0);
        rd_data :out std_logic_vector(data_bits-1 downto 0)
        );
end component;
 

Generic Map

The generic portion of the component has parameters for the number of address and data bits, plus flags to specify read modes and optimization hints.  The parameters are:

addr_bits -- The number of bits on the address bus (same for reads and writes).

data_bits -- The number of bits on the data bus (same for reads and writes).

register_out_flag -- If set to 0, all reads are asynchronous.  If set to 1, the reads will be synchronous.  Writes are always synchronous.

block_type -- Signals to the RAM core what type of RAM should be used.  
    0 = Automatic, the RAM core decides what is most appropriate.
    1 = Small RAM blocks (I.E., LUT's in a Xilinx Device)
    2 = Large RAM blocks (I.E., Select Block RAM in a Xilinx Virtex)

Port Map

The port mapping uses the following signals:

reset -- An asynchronous reset signal.

wr_clock -- The clock used for the write port.

wr_en -- The write enable signal (1=enabled).

wr_addr -- The write port address bus.

wr_data -- Input data for the write port.

rd_clk -- The clock used for synchronous reads (feed it the wr_clk if using asynchronous reads).

rd_addr -- The read port address bus.

rd_data -- Data output for the read port.

 

Example Instantiation

A typical VHDL use would be:

library work;
use work.ram_lib.all;

entity ....

architecture ...
    signal wr_addr :std_logic_vector (7 downto 0);
    signal wr_data :std_logic_vector (4 downto 0);
    ...
begin

    U1: ram_dp
  	  generic map (addr_bits => wr_addr'high+1,
  	               data_bits => wr_data'high+1,
  	               register_out_flag => 1,
  	               block_type => 0)
  	  port map (reset, clk, write_enable, wr_addr, 
                    wr_data, clk, rd_addr, rd_data);

...
 

Write Timing

The write port is always a synchronous port.  WR_EN, WR_ADDR, and WR_DATA must be valid on the rising edge of the clock.  If WR_EN is '1' on the rising edge then the contents described on WR_ADDR and WR_DATA will be written to the RAM.  The following diagram shows this:

In this diagram, data is written to RAM at the end of the second clock cycle.  

 

Read Timing

The read port can be async or sync, depending on the value of the register_out_flag.  If this flag is a '0', then the read port is asynchronous.  The timing for an async read port is simple:

When you put a valid read address, the corresponding read data is returned a short time later.  The exact delay is device dependant.

When register_out_flag is '1', the read port is synchronous.  The timing for this is:

RD_ADDR is driven with a valid address on one clock cycle, and the corresponding data is returned on the following clock cycle.

 

© 1999-2000, The Free-IP Project.  This page was last updated on May 02, 2000 11:25 PM.