Return to previous page Advance to next page

RAMs


If you do not want to instantiate RAM primitives in order to keep your HDL code technology independent, XST offers an automatic RAM recognition capability. XST can infer distributed as well as Block RAM. It covers the following characteristics, offered by these RAM types:

The type of the inferred RAM depends on its description:

Here is the list of VHDL/Verilog templates that will be described below:

If a given template can be implemented using Block and Distributed RAM, XST will implement BLOCK ones. You can use the ram_style attribute to control RAM implementation and select a desirable RAM type. Please refer to the "Design Constraints" chapter for more details.

Please note that the following features specifically available with Block RAM are not yet supported:

Please refer to the "FPGA Optimization" chapter for more details on RAM implementation.

Log File

The XST log file reports the type and size of recognized RAM as well as complete information on its I/O ports during the macro recognition step:

...

Synthesizing Unit <raminfr>.

Related source file is rams_1.vhd.

Found 128-bit single-port distributed RAM for signal <ram>.

     ----------------------------------------------------------

     | aspect ratio   | 32-word x 4-bit              |        |

     | clock          | connected to signal <clk>    | rise   |

     | write enable   | connected to signal <we>     | high   |

     | address        | connected to signal <a>      |        |

     | data in        | connected to signal <di>     |        |

     | data out       | connected to signal <do>     |        |

     | ram_style      | Auto                         |        |

     ---------------------------------------------------------

INFO:Xst - For optimized device usage and improved timings, you       may take advantage of available block RAM resources by       registering the read address.

Summary:

inferred 1 RAM(s).

Unit <raminfr> synthesized.

====================================

HDL Synthesis Report

Macro Statistics

# RAMs                                : 1

128-bit single-port distributed RAM : 1

===================================

...

Related Constraints

Related constraints are ram_extract and ram_style.

Single-Port RAM with Asynchronous Read

The following descriptions are directly mappable onto distributed RAM only.


The following table shows pin descriptions for a single-port RAM with asynchronous read.
IO Pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Read/Write Address
di
Data Input
do
Data Output

VHDL

Following is the VHDL code for a single-port RAM with asynchronous read.

library ieee;   
use ieee.std_logic_1164.all;  
use ieee.std_logic_unsigned.all; 
 
entity raminfr is 
  port (clk : in std_logic;  
        we  : in std_logic;   
        a   : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;   
    end if;   
  end process;   
  do <= RAM(conv_integer(a));   
end syn; 

Verilog

Following is the Verilog code for a single-port RAM with asynchronous read.

module raminfr (clk, we, a, di, do);   
 
input clk;   
input we;   
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0]; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
  end   
  assign do = ram[a];   
endmodule 

Single-Port RAM with "false" Synchronous Read

The following descriptions do not implement true synchronous read access as defined by the Virtex block RAM specification, where the read address is registered. They are only mappable onto Distributed RAM with an additional buffer on the data output, as shown below:


The following table shows pin descriptions for a single-port RAM with "false" synchronous read.
IO Pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Read/Write Address
di
Data Input
do
Data Output

VHDL

Following is the VHDL code for a single-port RAM with "false" synchronous read.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is 
  port (clk : in std_logic; 
        we  : in std_logic;   
        a   : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do  : out std_logic_vector(3 downto 0));   
end raminfr;  
 
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
    of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;  
      do <= RAM(conv_integer(a));   
    end if;   
  end process;   
end syn; 

Verilog

Following is the Verilog code for a single-port RAM with "false" synchronous read.

module raminfr (clk, we, a, di, do); 
 
input        clk;   
input        we;   
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0];   
reg    [3:0] do; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
    do <= ram[a];   
  end   
 
endmodule 

The following descriptions, featuring an additional reset of the RAM output, are also only mappable onto Distributed RAM with an additional resetable buffer on the data output as shown in the following figure:


The following table shows pin descriptions for a single-port RAM with "false" synchronous read and reset on the output.
IO Pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
rst
Synchronous Output Reset (active High)
a
Read/Write Address
di
Data Input
do
Data Output

VHDL

Following is the VHDL code.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is   
  port (clk : in std_logic;   
        we  : in std_logic;   
        rst : in std_logic;   
        a   : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do  : out std_logic_vector(3 downto 0));   
end raminfr; 
 
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;   
      if (rst = '1') then   
        do <= (others => '0');   
      else   
        do <= RAM(conv_integer(a));   
      end if;   
    end if;   
  end process;   
end syn; 

Verilog

Following the Verilog code.

module raminfr (clk, we, rst, a, di, do); 
 
input clk;   
input we;   
input rst;  
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0];   
reg    [3:0] do; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
    if (rst)   
      do <= 4'b0;   
    else   
      do <= ram[a];   
  end   
endmodule 

Single-Port RAM with Synchronous Read (Read Through)

The following description implements a true synchronous read. A true synchronous read is the synchronization mechanism available in Virtex block RAMs, where the read address is registered on the RAM clock edge. Such descriptions are directly mappable onto Block RAM, as shown below (The same descriptions can also be mapped onto Distributed RAM).


The following table shows pin descriptions for a single-port RAM with synchronous read (read through).
IO pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Read/Write Address
di
Data Input
do
Data Output

VHDL

Following is the VHDL code for a single-port RAM with synchronous read (read through).

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is 
  port (clk : in std_logic;   
        we  : in std_logic;   
        a   : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;  
  signal read_a : std_logic_vector(4 downto 0);   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;   
      read_a <= a;   
    end if;   
  end process;   
  do <= RAM(conv_integer(read_a));   
end syn; 

Verilog

Following is the Verilog code for a single-port RAM with synchronous read (read through).

module raminfr (clk, we, a, di, do); 
 
input clk;   
input we;   
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0];   
reg    [4:0] read_a; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
    read_a <= a;   
  end   
  assign do = ram[read_a];   
endmodule 

Single-Port RAM with Enable

The following description implements a single-port RAM with a global enable.

The following table shows pin descriptions for a single-port RAM with enable.
IO pins
Description
clk
Positive-Edge Clock
en
Global Enable
we
Synchronous Write Enable (active High)
a
Read/Write Address
di
Data Input
do
Data Output

VHDL

Following is the VHDL code for a single-port block RAM with enable.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is 
  port (clk : in std_logic;   
        en    : in std_logic; 
        we  : in std_logic;   
        a   : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;  
  signal read_a : std_logic_vector(4 downto 0);   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (en = '1') then 
        if (we = '1') then   
          RAM(conv_integer(a)) <= di;   
        end if;   
        read_a <= a;   
      end if; 
    end if; 
  end process;   
  do <= RAM(conv_integer(read_a));   
end syn; 

Verilog

Following is the Verilog code for a single-port block RAM with enable.

module raminfr (clk, en, we, a, di, do); 
input clk; 
input en; 
input we;   
input  [4:0] a;   
input  [3:0] di;   
output [3:0] do;   
reg    [3:0] ram [31:0];   
reg    [4:0] read_a; 
 
  always @(posedge clk) begin 
    if (en) 
    begin 
      if (we)   
        ram[a] <= di;   
        read_a <= a;   
    end 
  end   
  assign do = ram[read_a];   
endmodule 
 

Dual-Port RAM with Asynchronous Read

The following example shows where the two output ports are used. It is directly mappable onto Distributed RAM only.


The following table shows pin descriptions for a dual-port RAM with asynchronous read.
IO pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Write Address/Primary Read Address
dpra
Dual Read Address
di
Data Input
spo
Primary Output Port
dpo
Dual Output Port

VHDL

Following is the VHDL code for a dual-port RAM with asynchronous read.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is  
  port (clk  : in std_logic;   
        we   : in std_logic;   
        a    : in std_logic_vector(4 downto 0);   
        dpra : in std_logic_vector(4 downto 0);   
        di   : in std_logic_vector(3 downto 0);   
        spo  : out std_logic_vector(3 downto 0);   
        dpo  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
    of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;  
      end if;   
    end if;   
  end process;   
  spo <= RAM(conv_integer(a));   
  dpo <= RAM(conv_integer(dpra));   
 end syn; 

Verilog

Following is the Verilog code for a dual-port RAM with asynchronous read.

module raminfr   
        (clk, we, a, dpra, di, spo, dpo); 
 
input clk;   
input we;   
input  [4:0] a;   
input  [4:0] dpra;   
input  [3:0] di;   
output [3:0] spo;   
output [3:0] dpo;   
reg    [3:0] ram [31:0]; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
  end   
  assign spo = ram[a];   
  assign dpo = ram[dpra];   
endmodule 

Dual-Port RAM with False Synchronous Read

The following descriptions will be mapped onto Distributed RAM with additional registers on the data outputs. Please note that this template does not describe dual-port block RAM.


The following table shows pin descriptions for a dual-port RAM with false synchronous read.
IO Pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Write Address/Primary Read Address
dpra
Dual Read Address
di
Data Input
spo
Primary Output Port
dpo
Dual Output Port

VHDL

Following is the VHDL code for a dual-port RAM with false synchronous read.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is 
  port (clk  : in std_logic;   
        we   : in std_logic;   
        a    : in std_logic_vector(4 downto 0);   
        dpra : in std_logic_vector(4 downto 0);   
        di   : in std_logic_vector(3 downto 0);   
        spo  : out std_logic_vector(3 downto 0);   
        dpo  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;   
      spo <= RAM(conv_integer(a));   
      dpo <= RAM(conv_integer(dpra));   
    end if;   
  end process;   
end syn; 

Verilog

Following is the Verilog code for a dual-port RAM with false synchronous read.

module raminfr   
        (clk, we, a, dpra, di, spo, dpo); 
 
input clk;   
input we;   
input  [4:0] a;   
input  [4:0] dpra;   
input  [3:0] di;   
output [3:0] spo;   
output [3:0] dpo;   
reg    [3:0] ram [31:0];   
reg    [3:0] spo;   
reg    [3:0] dpo; 
 
  always @(posedge clk) begin  
    if (we)   
      ram[a] <= di;   
    spo = ram[a];   
    dpo = ram[dpra];   
  end   
endmodule 

Dual-Port RAM with Synchronous Read (Read Through)

The following descriptions are directly mappable onto Block RAM, as shown in the following figure. (They may also be implemented with Distributed RAM.).


The following table shows pin descriptions for a dual-port RAM with synchronous read (read through).
IO Pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
a
Write Address/Primary Read Address
dpra
Dual Read Address
di
Data Input
spo
Primary Output Port
dpo
Dual Output Port

VHDL

Following is the VHDL code for a dual-port RAM with synchronous read (read through).

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is   
  port (clk  : in std_logic;   
        we   : in std_logic;   
        a    : in std_logic_vector(4 downto 0);   
        dpra : in std_logic_vector(4 downto 0);   
        di   : in std_logic_vector(3 downto 0);   
        spo  : out std_logic_vector(3 downto 0);   
        dpo  : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is  
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
  signal read_a : std_logic_vector(4 downto 0);   
  signal read_dpra : std_logic_vector(4 downto 0);   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(a)) <= di;   
      end if;   
      read_a <= a;   
      read_dpra <= dpra;   
    end if;   
  end process;   
  spo <= RAM(conv_integer(read_a));   
  dpo <= RAM(conv_integer(read_dpra));   
end syn; 

Verilog

Following is the Verilog code for a dual-port RAM with synchronous read (read through).

module raminfr   
        (clk, we, a, dpra, di, spo, dpo); 
 
input clk;   
input we;   
input  [4:0] a;   
input  [4:0] dpra;   
input  [3:0] di;   
output [3:0] spo;   
output [3:0] dpo;   
reg    [3:0] ram [31:0];   
reg    [4:0] read_a;   
reg    [4:0] read_dpra; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[a] <= di;   
    read_a <= a;   
    read_dpra <= dpra;   
  end   
  assign spo = ram[read_a];   
  assign dpo = ram[read_dpra];   
endmodule 

Note The two RAM ports may be synchronized on distinct clocks, as shown in the following description. In this case, only a Block RAM implementation will be applicable.

The following table shows pin descriptions for a dual-port RAM with synchronous read (read through) and two clocks.
IO pins
Description
clk1
Positive-Edge Write/Primary Read Clock
clk2
Positive-Edge Dual Read Clock
we
Synchronous Write Enable (active High)
add1
Write/Primary Read Address
add2
Dual Read Address
di
Data Input
do1
Primary Output Port
do2
Dual Output Port

VHDL

Following is the VHDL code.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is   
  port (clk1 : in std_logic;   
        clk2 : in std_logic;   
        we   : in std_logic;   
        add1 : in std_logic_vector(4 downto 0);   
        add2 : in std_logic_vector(4 downto 0);   
        di   : in std_logic_vector(3 downto 0);   
        do1  : out std_logic_vector(3 downto 0);   
        do2  : out std_logic_vector(3 downto 0));   
end raminfr;  
 
architecture syn of raminfr is
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
  signal read_add1 : std_logic_vector(4 downto 0);   
  signal read_add2 : std_logic_vector(4 downto 0);   
begin   
  process (clk1)   
  begin   
    if (clk1'event and clk1 = '1') then   
      if (we = '1') then   
        RAM(conv_integer(add1)) <= di;   
      end if;   
      read_add1 <= add1;   
    end if;   
  end process;   
  do1 <= RAM(conv_integer(read_add1)); 
 
  process (clk2)   
  begin   
    if (clk2'event and clk2 = '1') then   
      read_add2 <= add2;   
    end if;   
  end process;   
  do2 <= RAM(conv_integer(read_add2));   
end syn; 

Verilog

Following is the Verilog code.

module raminfr  
    (clk, en, we, addra, addrb, di, doa, dob);  
 
  input clk;  
  input en;  
  input we;  
  input [4:0] addra;  
  input [4:0] addrb;  
  input [3:0] di;  
  output [3:0] doa;  
  output [3:0] dob;  
  reg [3:0] ram [31:0];  
  reg [4:0] read_addra;  
  reg [4:0] read_addrb;  
 
  always @(posedge clk) begin  
      if (en)  
        begin  
          if (we)  
            ram[addra] <= di;  
            read_addra <= addra;  
            read_addrb <= addrb;  
        end  
  end  
  assign doa = ram[read_addra];  
  assign dob = ram[read_addrb];  
endmodule 

Dual-Port RAM with One Enable Controlling Both Ports

The following descriptions are directly mappable onto Block RAM, as shown in the following figure.

The following table shows pin descriptions for a dual-port RAM with synchronous read (read through).
IO Pins
Description
clk
Positive-Edge Clock
en
Primary Global Enable (active High)
we
Primary Synchronous Write Enable (active High)
addra
Write Address/Primary Read Address
addrb
Dual Read Address
di
Primary Data Input
doa
Primary Output Port
dob
Dual Output Port

VHDL

Following is the VHDL code for a dual-port RAM with one global enable controlling both ports.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is   
  port (clk  : in std_logic;   
        en     : in std_logic; 
        we     : in std_logic; 
        addra: in std_logic_vector(4 downto 0);  
        addrb: in std_logic_vector(4 downto 0);  
        di     : in std_logic_vector(3 downto 0);   
        doa     : out std_logic_vector(3 downto 0);   
        dob     : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is  
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
  signal read_addra : std_logic_vector(4 downto 0);   
  signal read_addrb : std_logic_vector(4 downto 0);   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (en = '1') then  
        if (we = '1') then   
          RAM(conv_integer(addra)) <= di;   
        end if; 
        read_addra <= addra; 
        read_addrb <= addrb; 
      end if; 
    end if;   
  end process;   
  doa <= RAM(conv_integer(read_addra));   
  dob <= RAM(conv_integer(read_addrb));   
end syn; 

Verilog

Following is the Verilog code for a dual-port RAM with one global enable controlling both ports.

module raminfr   
        (clk, en, we, addra, addrb,         di, doa, dob); 
 
input clk;  
input en; 
input we; 
input  [4:0] addra;   
input  [4:0] addrb;   
input  [3:0] di;  
output [3:0] doa;  
output [3:0] dob;   
 
reg    [3:0] ram [31:0];   
reg    [4:0] read_addra;   
reg    [4:0] read_addrb; 
 
  always @(posedge clk) begin   
    if (ena) 
      begin 
        if (wea)  
          ram[addra] <= di;  
        read_aaddra <= addra;      
        read_aaddrb <= addrb;   
      end 
  end   
  assign doa = ram[read_addra];   
  assign dob = ram[read_addrb];   
endmodule 

Dual-Port RAM with Enable on Each Port

The following descriptions are directly mappable onto Block RAM, as shown in the following figure.

The following table shows pin descriptions for a dual-port RAM with synchronous read (read through).
IO Pins
Description
clk
Positive-Edge Clock
ena
Primary Global Enable (active High)
enb
Dual Global Enable (active High)
wea
Primary Synchronous Write Enable (active High)
addra
Write Address/Primary Read Address
addrb
Dual Read Address
dia
Primary Data Input
doa
Primary Output Port
dob
Dual Output Port

VHDL

Following is the VHDL code for a dual-port RAM with global enable

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
entity raminfr is   
  port (clk  : in std_logic;   
        ena     : in std_logic; 
        enb     : in std_logic; 
        wea     : in std_logic; 
        addra: in std_logic_vector(4 downto 0);  
        addrb: in std_logic_vector(4 downto 0);  
        dia     : in std_logic_vector(3 downto 0);   
        doa : out std_logic_vector(3 downto 0);   
        dob : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is  
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
  signal read_addra : std_logic_vector(4 downto 0);   
  signal read_addrb : std_logic_vector(4 downto 0);   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (ena = '1') then  
        if (wea = '1') then   
            RAM (conv_integer(addra)) <= dia;   
        end if; 
        read_addra <= addra; 
      end if; 
      if (enb = '1') then   
          read_addrb <= addrb;   
        end if;   
    end if;   
  end process;   
  doa <= RAM(conv_integer(read_addra));   
  dob <= RAM(conv_integer(read_addrb));   
end syn; 

Verilog

Following is the Verilog code for a dual-port RAM with synchronous read (read through).

module raminfr  
    (clk,ena,enb,wea,addra,addrb,dia,doa,dob);  
 
  input clk;  
  input ena;  
  input enb;  
  input wea;  
  input [4:0] addra;  
  input [4:0] addrb;  
  input [3:0] dia;  
  output [3:0] doa;  
  output [3:0] dob;  
 
  reg [3:0] ram [31:0];  
  reg [4:0] read_addra;  
  reg [4:0] read_addrb;  
 
  always @(posedge clk) begin  
    if (ena)  
      begin  
        if (wea)  
          ram[addra] <= dia;  
          read_addra <= addra;  
      end  
    if (enb)  
      read_addrb <= addrb;  
  end  
  assign doa = ram[read_addra];  
  assign dob = ram[read_addrb];  
endmodule 
 

Multiple-Port RAM Descriptions

XST can identify RAM descriptions with two or more read ports that access the RAM contents at addresses different from the write address. However, there can only be one write port. The following descriptions will be implemented by replicating the RAM contents for each output port, as shown:


The following table shows pin descriptions for a multiple-port RAM.
IO pins
Description
clk
Positive-Edge Clock
we
Synchronous Write Enable (active High)
wa
Write Address
ra1
Read Address of the first RAM
ra2
Read Address of the second RAM
di
Data Input
do1
First RAM Output Port
do2
Second RAM Output Port

VHDL

Following is the VHDL code for a multiple-port RAM.

library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all; 
 
entity raminfr is   
  port (clk : in std_logic;   
        we  : in std_logic;   
        wa  : in std_logic_vector(4 downto 0);   
        ra1 : in std_logic_vector(4 downto 0);   
        ra2 : in std_logic_vector(4 downto 0);   
        di  : in std_logic_vector(3 downto 0);   
        do1 : out std_logic_vector(3 downto 0);   
        do2 : out std_logic_vector(3 downto 0));   
end raminfr;   
architecture syn of raminfr is   
  type ram_type is array (31 downto 0)   
        of std_logic_vector (3 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(wa)) <= di;   
      end if;   
    end if;   
  end process;   
  do1 <= RAM(conv_integer(ra1));   
  do2 <= RAM(conv_integer(ra2));   
end syn; 

Verilog

Following is the Verilog code for a multiple-port RAM.

module raminfr   
      (clk, we, wa, ra1, ra2, di, do1, do2); 
 
input clk;   
input we;   
input  [4:0] wa;   
input  [4:0] ra1;   
input  [4:0] ra2;   
input  [3:0] di;   
output [3:0] do1;   
output [3:0] do2;   
reg    [3:0] ram [31:0]; 
 
  always @(posedge clk) begin   
    if (we)   
      ram[wa] <= di;   
  end   
  assign do1 = ram[ra1];   
  assign do2 = ram[ra2];   
endmodule 

Return to previous page Advance to next page