¿Cuál es la forma correcta de inferir una RAM con algunas direcciones más altas no utilizadas (utilizando RAM de bloque)?
Al usar el código a continuación (valores predeterminados para genéricos, sintetizador Xilinx y mapa), obtengo una RAM del mismo tamaño que si la profundidad estuviera establecida en 2**ADDRWIDTH
:
entity foo is
generic (
DATAWIDTH : positive := 8;
DATADEPTH : positive := 5000;
ADDRWIDTH : positive := 13
);
port (
clk_a : in std_logic;
we_a : in std_logic;
addr_a : in std_logic_vector(ADDRWIDTH-1 downto 0);
di_a : in std_logic_vector(DATAWIDTH-1 downto 0);
do_a : out std_logic_vector(DATAWIDTH-1 downto 0)
);
end foo;
architecture bar of foo is
type myram_type is array (DATADEPTH-1 downto 0) of std_logic_vector(DATAWIDTH-1 downto 0); --! type for ram content
shared variable myram : myram_type; --! ram
begin
process (clk_a)
begin
if rising_edge(clk_a) then
if we_a = '1' then
myram(conv_integer(addr_a)) := di_a;
end if;
do_a <= myram(conv_integer(addr_a));
end if;
end process;
end bar;
Por ejemplo, quiero una RAM con DATAWIDTH = 8
y DATADEPTH = 5000
, por lo que la dirección debe ser ADDRWIDTH = 13
porque ADDRWIDTH = 12
solo permitiría abordar 4096 ubicaciones RAM. Asumamos que un recurso RAM de bloque en mi FPGA puede contener 8192 bits.
Si codifiqué esto a mano, requerí 5000 * 8/8192 redondeados hacia arriba = 5 recursos de RAM de bloque.
Sin embargo, con el código anterior, la síntesis y el mapa de Xilinx dan como resultado el uso de 8 recursos de RAM de bloque, porque eso es lo que puede ser abordado por direcciones de 13 bits de ancho ...
Sin embargo, este no es realmente un uso eficiente de los recursos, ya que 3 de las 8 memorias RAM de bloque nunca se utilizarán.
Intenté verificar si la dirección en la entrada es mayor que DATADEPTH
y luego asignar no cuida los datos, pero eso hace que todo el ram se implemente como RAM / LUTRAM distribuido.
¿Me estoy perdiendo algo importante o tengo que usar un generador grande y feo para esto?