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_L
es 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.
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).
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.
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...
usuario3728501
signal my_ram: RAMB16_S9_S9
?gestión
usuario3728501
ERROR:HDLParsers:164 - Line 83. parse error, unexpected IDENTIFIER
Esto se debe a la línea:RAMB16_S9_S9_inst : RAMB16_S9_S9
a la que sigue ¿generic map ( ...
Alguna idea?gestión
usuario3728501