FPGA RAM/SRAM en VHDL

Hoy me quedé sin puertas en mi Xylinx Spartan 3 (Basys2 de Digilent) FPGA.

Esto no fue una sorpresa para mí, ya que había implementado una matriz de 8 bits x 2048 para usar como un búfer FIFO.

Código:type MEMORY is array(0 to (MEM_L - 1)) of std_logic_vector(7 downto 0);

donde MEM_Les un entero, valor 2048.

Leí el resumen del producto y, según tengo entendido, hay 72 kB de RAM bidireccional en los FPGA de la serie Spartan 3E.

Sin embargo, no sé cómo usarlo (programarlo) usando VHDL. ¿Cómo haría para declarar que quiero que algunos datos se almacenen en la memoria RAM?

Inicialmente supuse que el uso de RAM dependía del compilador (herramientas de sintetizador e implementación) y que no podía controlar cómo se usaba directamente, sin embargo, sospecho que estaba equivocado en esta suposición, porque el proceso de implementación falló debido a mi FIFO es demasiado grande para la cantidad de puertas admitidas. (Aprox. 100 k puertas.)

Debo agregar que no pude encontrar una respuesta a través de Google, ¿tal vez no sabía muy bien qué buscar?

EDITAR: Eso debería haber dicho 78 kb de ram, 78000 bits.

Respuestas (2)

Lo más sencillo de hacer (OMI) es instanciar directamente la primitiva del dispositivo en su VHDL. De esta manera, no confía en las herramientas para inferir RAM de bloque. En ISE, vaya a Editar -> Plantillas de idioma y podrá abrir la plantilla. (Querrá elegir Spartan-3E, por supuesto, aunque creo que la primitiva es la misma en este caso).

seleccionando dispositivo primitivo

La desventaja de usar la primitiva, por supuesto, es que su código no es trivialmente portátil fuera de la familia de dispositivos. (Para las RAM de bloque, esto no es un gran problema ya que son muy similares entre proveedores y familias).

Otra opción es usar Core Generator, que es quizás más 'fácil de usar' para configurar, pero lento durante la síntesis inicial. También puede generar un FIFO completo de esta manera.

Tal vez alguien pueda hablar sobre métodos para inferir RAM de bloque.

Ah, ya veo, ¿dónde puedo encontrar la información sobre cómo usar estos dispositivos? ¿Supongo que inicialmente creo un tipo de RAM haciendo algo como signal my_ram: RAMB16_S9_S9?
Tendrás que reorientar tu pensamiento, porque este es un módulo y no una entidad señal. La plantilla tiene instrucciones de uso. También eche un vistazo a XAPP463.
Seguí las instrucciones: copié el código debajo de la línea "copiar aquí abajo" y lo pegué dentro de la sección de arquitectura. El error aparece en la síntesis: ERROR:HDLParsers:164 - Line 83. parse error, unexpected IDENTIFIEREsto se debe a la línea: RAMB16_S9_S9_inst : RAMB16_S9_S9a la que sigue ¿ generic map ( ...Alguna idea?
@ user3728501, eso suena como un error de sintaxis. Pero asegúrese de haber incluido también las líneas de la biblioteca UNISIM.
Sí, lo hice, literalmente lo copié, pero lo intentaré de nuevo.

XST puede inferir automáticamente bloques de RAM.

Lea la ref. de la "Guía del usuario de XST" de Xilinx. UG627

"RAM de doble puerto con lectura síncrona (lectura completa)"

architecture syn of rams_11 is
    type ram_type is array (63 downto 0) of std_logic_vector (15 downto 0);
    signal RAM : ram_type;
    signal read_a : std_logic_vector(5 downto 0);
    signal read_dpra : std_logic_vector(5 downto 0);
begin
    process (clk)
    begin
        if (clk’event and clk = ’1’) then
            if (we = ’1’) then
                RAM(conv_integer(a)) <= di;
            end if;
            read_a <= a;
            read_dpra <= dpra;
        end if;
    end process;
    spo <= RAM(conv_integer(read_a));
    dpo <= RAM(conv_integer(read_dpra));
end syn;

También hay una solución cuando el puerto de lectura y escritura tienen relojes diferentes. BlockRAM son memorias registradas, por lo que no puede leer el contenido de forma asíncrona. También puede haber algunas opciones para verificar en el cuadro de diálogo de síntesis de ISE...