Answers Database


SYNPLIFY: How to infer synchronous (single-port/dual-port) RAM in HDL (Verilog/VHDL)?


Record #4075

Problem Title:
SYNPLIFY: How to infer synchronous (single-port/dual-port) RAM in HDL (Verilog/VHDL)?


Problem Description:
Urgency: Standard

General Description: How to infer RAM in HDL using
Synplicity's Synplify?

A RAM structure can be modeled as a 2-dimensional array of
registers. Each element of the array is known as a word.
Each word can be one or more bits. Synplify automatically
detects the RTL description of a synchronous RAM. The RAM
is mapped to applicable technology specific RAM cells.

When a RAM block is recognized, Synplify will automatically
implement a single-port circuit using RAM16x1S and a dual-port
circuit using RAM16x1D primitives.

Note: Use Synplify 5.0 or greater.

See (Xilinx Solution #4409) to disable RAM inference




Solution 1:

/*
Verilog Example

This example shows how to create a 32x8 (32 words
8 bits per word) synchronous, dual-port RAM.
*/

module ram_32x8d_infer (o, we, d, raddr, waddr, clk);
parameter d_width = 8, addr_width = 5;

output [d_width - 1:0] o;
input we, clk;
input [d_width - 1:0] d;
input [addr_width - 1:0] raddr, waddr;

reg [d_width - 1:0] o;
reg [d_width - 1:0] mem [(1 << addr_width) - 1:0];

always @(posedge clk)
   if (we)
     mem[waddr] = d;

always @(mem or raddr)
     o = mem[raddr];

endmodule



Solution 2:

/*
Verilog Example

This example shows how to create a 32x8 (32 words
8 bits per word) synchronous, single-port RAM.
*/

module ram_32x8s_infer (o, we, d, addr, wclk);
parameter d_width = 8, addr_width = 5;

output [d_width - 1:0] o;
input we, wclk;
input [d_width - 1:0] d;
input [addr_width - 1:0] addr;

reg [d_width - 1:0] mem [(1 << addr_width) - 1:0];

always @(posedge wclk)
   if (we)
     mem[addr] = d;

assign o = mem[addr];

endmodule



Solution 3:

-- VHDL Example
-- This example shows how to create a 32x8 (32 words
-- 8 bits per word) synchronous, dual-port RAM

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity ram_32x8d_infer is
  generic( d_width : integer := 8;
        addr_width : integer := 5;
        mem_depth : integer := 32);
  port (o : out STD_LOGIC_VECTOR(d_width - 1 downto 0);
        we, clk : in STD_LOGIC;
        d : in STD_LOGIC_VECTOR(d_width - 1 downto 0);
        raddr, waddr : in STD_LOGIC_VECTOR(addr_width - 1 downto 0));
end ram_32x8d_infer;

architecture xilinx of ram_32x8d_infer is
   type mem_type is array (mem_depth - 1 downto 0) of
       STD_LOGIC_VECTOR (d_width - 1 downto 0);

   signal mem : mem_type;

begin

   process(clk, we, waddr)
     begin
       if (rising_edge(clk)) then
      if (we = '1') then
        mem(conv_integer(waddr)) <= d;
      end if;
       end if;
   end process;

   process(raddr)
     begin
       o <= mem(conv_integer(raddr));
   end process;

end xilinx;



Solution 4:

-- VHDL Example
-- This example shows how to create a 32x8 (32 words
-- 8 bits per word) synchronous, single-port RAM

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity ram_32x8s_infer is
  generic( d_width : integer := 8;
        addr_width : integer := 5;
        mem_depth : integer := 32);
  port (o : out STD_LOGIC_VECTOR(d_width - 1 downto 0);
        we, wclk : in STD_LOGIC;
        d : in STD_LOGIC_VECTOR(d_width - 1 downto 0);
        addr : in STD_LOGIC_VECTOR(addr_width - 1 downto 0));
end ram_32x8s_infer;

architecture xilinx of ram_32x8s_infer is
   type mem_type is array (mem_depth - 1 downto 0) of
       STD_LOGIC_VECTOR (d_width - 1 downto 0);

   signal mem : mem_type;

begin

   process(wclk, we, addr)
     begin
       if (rising_edge(wclk)) then
      if (we = '1') then
        mem(conv_integer(addr)) <= d;
      end if;
       end if;
   end process;

   o <= mem(conv_integer(addr));

end xilinx;




End of Record #4075 - Last Modified: 04/01/99 09:15

For the latest news, design tips, and patch information on the Xilinx design environment, check out the Technical Tips!