09-02-2023, 09:28 PM
(This post was last modified: 09-02-2023, 09:33 PM by ppppenguin.)
Synthesising memory can be a bit of a black art. I only know the tricks for Xilinx but other makes may be similar. For small memories that will be implemented in the logic cells it's easy. There are common constructs that will synthesise memory. When reading memory, if the read address generator gives you an SLV you will need to cast it to INTEGER to give the read address.
If you want to use block memory I would normally declare it using the primitive. Or alternatively use whatever tools are available to build it as a component. This latter approach works well if you want a memory that needs multiple block RAMs.
Here's a 2Kx9 dual port using a single RAM. Declaration and then instatiation. The RAM was built with Xilinx tools and declared as a component.
Here's a big RAM that used 6 BRAM blocks
Having to declare the write enables (WEA) as 1 bit SLV rather than std_logic is a quirk of the Xilinx memory generator.
If you want to use block memory I would normally declare it using the primitive. Or alternatively use whatever tools are available to build it as a component. This latter approach works well if you want a memory that needs multiple block RAMs.
Here's a 2Kx9 dual port using a single RAM. Declaration and then instatiation. The RAM was built with Xilinx tools and declared as a component.
Code:
-- CD400 BRAM for sync and burst edges. Single BRAM, both ports 2K*9. Latency = 1
component sync_burst_edge_ram port (
clka, clkb : IN STD_LOGIC; wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra, addrb : IN STD_LOGIC_VECTOR(10 DOWNTO 0); dina : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(8 DOWNTO 0));
end component;
EDGE_RAM_CD400 : sync_burst_edge_ram port map (
CLKA => CKC, DINA => CONTROL_DATA(8 downto 0), ADDRA => RAM_WADDR(10 downto 0), WEA(0) => RAM_WRITE,
CLKB => CK, ADDRB => SYNC_RAM_ADDR(10 downto 0), DOUTB => SYNC_LUT_CD400);Here's a big RAM that used 6 BRAM blocks
Code:
-- 6xBRAM (32768x3) for ident generator
component kram32768x3 port (
clka, ena, clkb, enb : IN std_logic; wea: IN std_logic_VECTOR(0 downto 0);
addra, addrb: IN std_logic_VECTOR(14 downto 0);
dina: IN std_logic_VECTOR(2 downto 0); doutb: OUT std_logic_VECTOR(2 downto 0));
end component;
IDENT_RAM1 : KRAM32768X3 PORT MAP (
CLKA => CKC, ENA => '1', WEA(0) => RAM_WRITE, ADDRA => RAM_WADDR, DINA => CD(2 downto 0),
CLKB => CK, ENB => CE, ADDRB => std_logic_vector(RAM_READ_ADDRESS(14 downto 0)), -- Remove sign bit and convert to SLV
DOUTB => IDENT_RAM_DATA);Having to declare the write enables (WEA) as 1 bit SLV rather than std_logic is a quirk of the Xilinx memory generator.
www.borinsky.co.uk Jeffrey Borinsky www.becg.tv







