RAM de doble puerto en Altera y Xilinx FPGA

Siempre he logrado sintetizar una RAM de doble puerto de 256 x 32 bits (no una verdadera RAM de doble puerto) en Xilinx ISE con solo 1 x 18K BRAM.

Se usó el código de ejemplo de aquí :

-- A parameterized, inferable, true dual-port, dual-clock block RAM in VHDL.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity bram_tdp is
generic (
    DATA    : integer := 72;
    ADDR    : integer := 10
);
port (
    -- Port A
    a_clk   : in  std_logic;
    a_wr    : in  std_logic;
    a_addr  : in  std_logic_vector(ADDR-1 downto 0);
    a_din   : in  std_logic_vector(DATA-1 downto 0);
    a_dout  : out std_logic_vector(DATA-1 downto 0);

    -- Port B
    b_clk   : in  std_logic;
    b_wr    : in  std_logic;
    b_addr  : in  std_logic_vector(ADDR-1 downto 0);
    b_din   : in  std_logic_vector(DATA-1 downto 0);
    b_dout  : out std_logic_vector(DATA-1 downto 0)
);
end bram_tdp;

architecture rtl of bram_tdp is
    -- Shared memory
    type mem_type is array ( (2**ADDR)-1 downto 0 ) of std_logic_vector(DATA-1 downto 0);
    shared variable mem : mem_type;
begin

-- Port A
process(a_clk)
begin
    if(a_clk'event and a_clk='1') then
        if(a_wr='1') then
            mem(conv_integer(a_addr)) := a_din;
        end if;
        a_dout <= mem(conv_integer(a_addr));
    end if;
end process;

-- Port B
process(b_clk)
begin
    if(b_clk'event and b_clk='1') then
        if(b_wr='1') then
            mem(conv_integer(b_addr)) := b_din;
        end if;
        b_dout <= mem(conv_integer(b_addr));
    end if;
end process;

end rtl;

He intentado hacer lo mismo con Altera, sin embargo, la compilación me da cifras que requieren 2 x M20K RAM.

¿No debería requerir solo 1 x M20K? ¿Cómo puedo hacer eso sin recurrir a otros recursos como otros MLAB?

¿Infirió un verdadero puerto dual de un par de puertos individuales? Recientemente tuve algunos problemas para inferir una verdadera RAM de doble puerto en cuarto y tuve que colocar la RAM en un módulo separado para que se sintetice correctamente. El ide puede ser mejor que el ise, pero el sintetizador es una mierda.
Recomiendo usar la altsyncrammacro de altera_mf. Es una macro para generar la RAM correcta.
Muestra el código que usaste para inferir la memoria RAM.
Lo he comprobado y 256x32b es una configuración compatible. 40b es el ancho máximo para un M20K.
Utilicé el siguiente código vhdl tomado de danstrother.com/2010/09/11/inferring-rams-in-fpgas Lo siento, no tengo idea de cómo pegar el código aquí usando lenguaje de rebajas y sin exceder el límite de palabras.
Debe agregar el dispositivo FPGA específico a su pregunta. Parece ser un Stratix V, que es la única familia que tiene M20K según esta guía del usuario .
Sí, es un statix ​​V, creo que Tom Carpenter respondió perfectamente a mi pregunta. Gracias Tom Carpenter, ¡has sido de gran ayuda! Especialmente por modificar mi pregunta. Me has mostrado cómo incrustar mi código en el futuro. Me acabo de dar cuenta de que no me funcionó anteriormente porque probé el formato en la sección de respuesta de comentarios.

Respuestas (2)

También intenté compilar para un Stratix V con Quartus 15.0 que tiene bloques M20K, y tiene razón: infiere dos M20K, lo que no debería ser el caso. De hecho, usar el código de prueba de Verilog que acabo de eliminar de mi respuesta también infiere dos M20K.


¿Por qué? Los verdaderos requisitos de puerto dual

Una memoria RAM de un solo puerto del tamaño que le interesa debería poder caber en un solo M20K, ya que puede admitir anchos de hasta 40 bits. Para el modo simple de doble puerto, también debería encajar: en este modo, tiene un puerto de lectura y un puerto de escritura.

Configuración de puerto único

Fuente de la imagen: Manual del dispositivo Stratix V, Sección 2-9

Sin embargo, en el modo True Dual-Port no encajará. El motivo es que los M20K solo tienen una ruta de lectura de 40 bits de ancho y una ruta de escritura de 40 bits de ancho. Cuando se opera en el modo True Dual-Port, estas rutas deben compartirse entre los puertos; en otras palabras, cada puerto solo puede tener 20 bits de ancho.

Ancho de puerto dual real

Fuente de la imagen: Manual del dispositivo Stratix V, Sección 2-9

Debido a estas rutas compartidas, se requieren dos M20K para instalar la RAM. Si estuviera operando en modo de puerto único o en modo de puerto dual simple, solo necesitaría 1.

Usé el siguiente código vhdl tomado de danstrother.com/2010/09/11/inferring-rams-in-fpgas
Lo siento, no tengo idea de cómo pegar el código aquí usando lenguaje de rebajas y sin exceder el límite de palabras.

Parece que está utilizando un Stratix V, que es la única familia de FPGA que tiene bloques de memoria M20K según la Guía del usuario de memoria integrada de Altera.

De acuerdo con la Tabla 2-8 del Volumen 1 del Manual del dispositivo Stratix V , el ancho máximo de datos de un M20K en modo de puerto dual real es de 20 bits. Por lo tanto, se requieren dos M20K para un bus de datos de 32 bits.

Solo en el modo de puerto dual simple , el M20K admite un ancho de datos de hasta 40 bits, como se indica en la Tabla 2-7.