Infer dual-clock block RAM for Xilinx

Apr 07, 2006 7 Replies

Anyone has code templates for infering a dual-port, dual-clock, block RAM (RAMB16) for Xilinix using Synplicity and VHDL?



Xilinx XST supports this using shared variable for memory and two processes for each write port. But I can't seem to find anything for Synplicity.


-- Amal



Have you tried to infer it yourself? It's something that's easy to do with Synplicity's tools in Verilog, I imagine they do as good a job with VHDL. You have an array, a write, and a read. You have your choice of a registered read from a combinatorial address or an asynchronous read from a registered address (which they translate back to the former, native arrangement). They do a great job of taking care of the other control signals as well.

The Synplify(Pro) online manual should also give you some guidance or at least a description of what they expect to provide for support.

Amal, I guess your Google access is broken? ;-)

formatting link
Cheers, Syms.

Google is not broken, but it's not quite what I need. A dual-clock, dual-port block memory mapped to RAMB16 using VHDL!

A dual write port RAM template would have to include a description of the arbitration of simultaneous writes to the same address. Lacking this, there is no guarantee that simulation and synthesis would match.

Your choices are

  1. Use a vendor-specific instance or
  2. Use a supported RAM template and add separate logic to cover all the required cases.

-- Mike Treseler

Finally I could map to RAMB16 on Xilinx Virtex and Synplify using the followig:

library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.math_real.all;

entity DualPortMemory is generic ( DEPTH : positive; WIDTH : positive ); port ( -- port a (read/write) clka : in std_logic; ena : in std_logic; wea : in std_logic; addra : in std_logic_vector(integer(ceil( log2(real(DEPTH))))-1 downto 0); dia : in std_logic_vector(WIDTH-1 downto 0); doa : out std_logic_vector(WIDTH-1 downto 0); -- port b (read/write) clkb : in std_logic; enb : in std_logic; web : in std_logic; addrb : in std_logic_vector(integer(ceil( log2(real(DEPTH))))-1 downto 0); dib : in std_logic_vector(WIDTH-1 downto 0); dob : out std_logic_vector(WIDTH-1 downto 0) ); end entity DualPortMemory;

architecture rtl of DualPortMemory is

type MEM_TYPE is array(0 to DEPTH-1) of std_logic_vector(WIDTH-1 downto 0); signal memory : MEM_TYPE;

attribute syn_ramstyle : string; attribute syn_ramstyle of memory : signal is "block_ram"; attribute syn_ramstyle of memory : signal is "no_rw_check";

begin

-------------------------------------- -- Port A (read/write) -------------------------------------- p_Port_A: process( clka ) begin if ( rising_edge(clka) ) then

if ( ena = '1' ) then if ( wea = '1' ) then memory( conv_integer(unsigned(addra)) )

I don't have Synplify, so I can't verify this. I like your idea of using math_real functions for synthesis constants, however, I am unconvinced that this a useful simulation model since the signal _memory_ is driven by both processes.

And you may have a typo one one of these duplicated attribute specifications:

True, but a vhdl simulator knows nothing about Synplify attributes declarations.

-- Mike Treseler

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required