推断具有一些未使用的较高地址的 RAM(使用块 RAM)的正确方法是什么?
使用下面的代码(泛型、Xilinx 合成器和映射的默认值),我得到的 RAM 大小与深度设置为一样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;
例如,我想要一个带有DATAWIDTH = 8
and的 RAM DATADEPTH = 5000
,所以地址必须是ADDRWIDTH = 13
因为ADDRWIDTH = 12
只允许寻址 4096 个 RAM 位置。让我们假设我的 FPGA 上的一个块 RAM 资源可以容纳 8192 位。如果我手动编码,我需要 5000*8/8192 向上舍入 = 5 个块 RAM 资源。然而,使用上面的代码,Xilinx 的综合和映射会导致使用 8 个块 RAM 资源,因为这可以通过 13 位宽地址来寻址......
尽管如此,这并不是真正有效地使用资源,因为 8 个中的 3 个永远不会使用块 RAM。
我试图检查输入的地址是否大于DATADEPTH
然后分配不关心数据,但这导致整个 ram 被实现为分布式 RAM / LUTRAM。
我是否遗漏了一些重要的东西,或者我必须为此使用一个大而丑陋的生成器?