Infer dual-clock block RAM for Xilinx

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

Reply to
Amal
Loading thread data ...

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.

Reply to
John_H

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

formatting link
Cheers, Syms.

Reply to
Symon

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

Reply to
Amal

Reply to
Symon

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

Reply to
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)) )

Reply to
Amal

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

Reply to
Mike Treseler

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.