Estoy usando un Basys 2 con 72Kbits de RAM de bloque de doble puerto. Utilicé más del 100% de los segmentos disponibles, por lo que quiero asegurarme de que Xilinx no solo los llene con los valores del mapa de caracteres en lugar de colocarlos en los lugares apropiados. Estoy seguro de que tengo muchas más formas de optimizar mi diseño y esas sugerencias son muy bienvenidas.
¿Qué muestra Xilinx cuando se ha deducido correctamente la RAM de bloque de puerto dual?
¿Necesita dos relojes separados para implementar la RAM de bloque de puerto dual?
He intentado ambos de estos diseños (a continuación) y ambos muestran lo que parecen ser dos elementos de Bloqueo de RAM en lugar de un elemento de Doble Puerto de RAM de Bloque.
Estoespartedeun
Informe completo de síntesis
Diseño # 1:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fontROM is
generic(
addrWidth: integer := 11;
dataWidth: integer := 8
);
port(
clk: in std_logic;
addr_A: in std_logic_vector(addrWidth-1 downto 0);
data_A: out std_logic_vector(dataWidth-1 downto 0);
addr_B: in std_logic_vector(addrWidth-1 downto 0);
data_B: out std_logic_vector(dataWidth-1 downto 0)
);
end fontROM;
architecture Behavioral of fontROM is
signal addr_reg_A: std_logic_vector(addrWidth-1 downto 0);
signal addr_reg_B: std_logic_vector(addrWidth-1 downto 0);
type rom_type is array (0 to 2**addrWidth-1) of std_logic_vector(dataWidth-1 downto 0);
-- ROM definition
constant ROM: rom_type := ( -- 2^11-by-8
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- redacted...
);
begin
-- addr register to infer block RAM
portDProcess: process (clk)
begin
if rising_edge(clk) then
addr_reg_A <= addr_A;
addr_reg_B <= addr_B;
end if;
end process;
data_A <= ROM(to_integer(unsigned(addr_reg_A)));
data_B <= ROM(to_integer(unsigned(addr_reg_B)));
end Behavioral;
Diseño # 2 (inspirado por este artículo ):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fontROM is
generic(
addrWidth: integer := 11;
dataWidth: integer := 8
);
port(
clk: in std_logic;
addr_A: in std_logic_vector(addrWidth-1 downto 0);
data_A: out std_logic_vector(dataWidth-1 downto 0);
addr_B: in std_logic_vector(addrWidth-1 downto 0);
data_B: out std_logic_vector(dataWidth-1 downto 0)
);
end fontROM;
architecture Behavioral of fontROM is
signal addr_reg_A: std_logic_vector(addrWidth-1 downto 0);
signal addr_reg_B: std_logic_vector(addrWidth-1 downto 0);
type rom_type is array (0 to 2**addrWidth-1) of std_logic_vector(dataWidth-1 downto 0);
-- ROM definition
constant ROM: rom_type := ( -- 2^11-by-8
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- redacted...
);
begin
-- addr register to infer block RAM
portAProcess: process (clk)
begin
if rising_edge(clk) then
addr_reg_A <= addr_A;
data_A <= ROM(to_integer(unsigned(addr_reg_A)));
end if;
end process;
portBProcess: process (clk)
begin
if rising_edge(clk) then
addr_reg_B <= addr_B;
data_B <= ROM(to_integer(unsigned(addr_reg_B)));
end if;
end process;
end Behavioral;