Inferencia de RAM del bloque VHDL

3

Estoy almacenando una tabla senoidal constante de 16k de vectores con signo de 14 bits en un paquete.

Utilizo este paquete en mi módulo para leer la matriz en un proceso cronometrado

Pero recibo esta advertencia durante la síntesis y mi síntesis está demorando mucho -

  

La RAM se implementará en las LUT, ya sea porque ha descrito una lectura asíncrona o debido a las características de RAM de bloque actualmente no admitidas. Si ha descrito una lectura asíncrona, hacerla sincrónica le permitiría aprovechar los recursos de RAM de bloque disponibles para optimizar el uso del dispositivo y mejorar los tiempos. Consulte su documentación para conocer las pautas de codificación ".

código en el paquete -

TYPE signed_array IS ARRAY (integer RANGE <>) OF signed (DATAWIDTH-1 DOWNTO 0); 

CONSTANT SINE_TABLE_SIZE : integer := QUARTER_LENGTH+1; -- 16384+1
----sine pi/2 = 1 <=> "0111111....1" MSB is 0 because of the signed representation

CONSTANT SINE_TABLE : signed_array(0 TO SINE_TABLE_SIZE-1):= (
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.0), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*9.5873799096e-05), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000191747597311), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000287621393763), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000383495187571), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000479368977855), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000575242763732), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000671116544322), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000766990318743), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000862864086114), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000958737845553), DATAWIDTH) ,
                    to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.00105461159618), DATAWIDTH) ,


process(clk)
    if rising_edge(clk) then
        ctd <= ctr + 1;
    end if;
end process;

cos <= SINE_TABLE(to_integer(unsigned(ctr)));

¿Alguna sugerencia sobre cómo escribir un código vhdl en inferir un bloque de RAM en lugar de LUTs?

SINE TABLE está en un paquete, y el proceso está en el módulo principal

    
pregunta Sai Gautam

2 respuestas

3

Mueve la búsqueda de tomas justo al lado del incremento para que se registre la salida.

Aunque es una tabla de búsqueda gigantesca. Es posible que desee considerar el uso de una tabla de búsqueda comprimida para guardar en la RAM del bloque. La compensación es que puede necesitar un par de multiplicadores.

Aquí hay un ejemplo de una tabla de búsqueda de seno comprimida segmentada: enlace . Por defecto, este tiene una entrada de fase de 18 bits (2 ^ 18 = 262k entradas equivalentes) con un ancho de salida de 16 bits. Consume 3 RAM de bloque (dos son 512x16 y una es 256x8) y dos segmentos DSP.

    
respondido por el alex.forencich
2

La lectura de la memoria debe registrarse para ser reconocida como una RAM de bloque:

process(clk)
    if rising_edge(clk) then
        ctr <= ctr + 1;
        cos <= SINE_TABLE(to_integer(unsigned(ctr)));
    end if;
end process;

También haría ctr de un tipo integer , por lo que no es necesario que hagas el seguimiento de las conversiones.

    
respondido por el Martin Thompson

Lea otras preguntas en las etiquetas