Inferring block RAMs

Inferring Block RAMs

Block RAMs are frequently utilized in FPGA circuits. The usual way to insert a block ram module in the design is to instantiate a component from a vendor-specific library. This solution is often not very desirable because of the lack of portability.

Another way that is possible with modern synthesis tools is to write a behavioral description of a RAM module so that a synthesizer can infer that it can be implemented as a block RAM.

This behavioral description must be written carefully, otherwise it is possible that a synthesizer won't recognize it.

The following example was tested with XST and Synplify synthesizers.

Consider a dual-port block RAM with 16-bit data words, 6-bit address, one write port and one read port. Here's its VHDL description:


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity mem1 is
 port (
  CLK : in std_logic;
  WE : in std_logic;
  WADDR : in std_logic_vector(5 downto 0);
  RE: in std_logic;
  RADDR : in std_logic_vector(5 downto 0);
  DIN : in std_logic_vector(15 downto 0);
  DOUT : out std_logic_vector(15 downto 0)
 );
end mem1;

architecture behavioral of mem1 is
type ram_type is array (63 downto 0) of std_logic_vector (15 downto 0);
signal RAM : ram_type;
signal read_addr : std_logic_vector(5 downto 0);

attribute syn_ramstyle : string;
attribute syn_ramstyle of RAM : signal is "block_ram";

begin

process (CLK)
begin
 if rising_edge(CLK) then
  if WE='1' then
   RAM(conv_integer(WADDR))<=DIN;
  end if;
 end if;
end process;

process (CLK)
begin
 if rising_edge(CLK) then
  if RE='1' then
   read_addr<=RADDR;
  end if;
 end if;
end process;

DOUT<=RAM(conv_integer(read_addr));
end behavioral;

A Verilog description of the same module:


module mem1 (clk,re,we,waddr,raddr,din,dout);
 input clk;
 input re;
 input we;
 input [5:0] waddr;
 input [5:0] raddr;
 input [15:0] din;
 output [15:0] dout;

reg [15:0] ram [63:0];

/* synthesis syn_ramstyle="block_ram" */
reg [5:0] read_addr;

always @(posedge clk) begin
 if (we) ram[waddr] <= din;
end

always @(posedge clk) begin
 if (re) read_addr <= raddr;
end

assign dout = ram[read_addr];
endmodule

syn_ramstyle attribute is intended for Synplify, but XST also recognises it.

Using behavioral block RAM descriptions is recommended when possible, since it increases portability and facilitates design reuse.

The FPGA tutorial has been created by 1-CORE Technologies, an FPGA design services provider.

1-CORE Technologies logo

Facebook  Twitter  Linkedin  YouTube      RSS

 

Check out FPGA related videos

Find Us On Facebook