3 votos

Inferencia de RAM de bloque VHDL

Estoy almacenando una tabla de seno constante de 16k de vectores firmados de 14 bits en un paquete.

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

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

La RAM se implementará en LUTs ya sea porque ha descrito una lectura asíncrona o debido a características de RAM en bloque actualmente no compatibles. Si ha descrito una lectura asíncrona, hacerla síncrona le permitiría aprovechar los recursos de RAM en bloque disponibles, para un uso optimizado del dispositivo y tiempos mejorados. Por favor refiérase a su documentación para las pautas de codificación."

código en el paquete -

TIPO signed_array IS ARRAY (ENTERO RANGO <>) DE signed (DATAWIDTH-1 DOWNT O 0); 

CONSTANTE TAMAÑO_TABLA_SENO : entero := LONGITUD_CUARTO+1; -- 16384+1
----seno pi/2 = 1 <=> "0111111....1" MSB es 0 debido a la representación firmada

CONSTANTE TABLA_SENO : signed_array(0 A TAMAÑO_TABLA_SINO-1):= (
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.0), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*9.5873799096e-05), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000191747597311), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000287621393763), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000383495187571), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000479368977855), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000575242763732), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000671116544322), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000766990318743), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000862864086114), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.000958737845553), DATAWIDTH) ,
                    to_signed(entero((2.0**(DATAWIDTH-1)-1.0)*0.00105461159618), DATAWIDTH) ,

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

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

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

La TABLA DE SENO está en un paquete, y el proceso está en el módulo principal

3voto

silverbolt Puntos 18

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

Esa es una tabla de búsqueda gigantesca, sin embargo. Puede considerar usar una tabla de búsqueda comprimida para ahorrar en la RAM en bloque. El inconveniente es que puede necesitar un par de multiplicadores.

Aquí hay un ejemplo de una tabla de búsqueda de seno comprimida y con pipeline: https://github.com/alexforencich/verilog-dsp/blob/master/rtl/sine_dds_lut.v. Por defecto, esta tiene una entrada de fase de 18 bits (2^18 = 262k entradas equivalentes) con un ancho de salida de 16 bits. Consume 3 RAM en bloque (dos son de 512x16 y uno es de 256x8) y dos bloques DSP.

2voto

Martin Thompson Puntos 6509

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 que ctr fuera de tipo integer - entonces no necesitas complicarte con las conversiones.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X