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.