一、Distributed Memory Generator有什么用?
Distributed Memory Generator是Vivado中的IP核,即分布式存储器。
它可以生成只读存储器 (ROM),单端口、简单双端口和双端口随机存取存储器 (RAM),
且生成的存储器支持16-65536字的数据深度,和1-1024位的数据宽度。
xilinx_dist_sdpram_0oregs_32x12
似乎是指一个双端口的分布式存储器(SDPRAM),它具有32个地址和每个地址可以存储12位数据。在Xilinx FPGA中,分布式RAM(Distributed RAM)是利用查找表(LUTs)中的额外逻辑来实现的小型RAM,通常用于实现小规模的存储需求。
在Xilinx FPGA架构中,分布式RAM可以在SLICEM中的查找表(LUTs)实现,而SLICEL则不支持此功能。每个SLICEM可以配置为不同形式的RAM,例如单端口RAM、双端口RAM、简单双端口RAM或四端口RAM。对于简单双端口RAM,一个SLICEM可以提供最多256位的存储空间,即4个LUTs,每个LUT提供64位的存储能力。
二、端口说明
本次选择的设置是简单双端口,接口调用如下:
分布式ram代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dist_sdpram is
Port (
a : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address
d : in STD_LOGIC_VECTOR(11 downto 0); -- 12-bit data input
dpra : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address for read
clk : in STD_LOGIC; -- Clock input
we : in STD_LOGIC; -- Write enable
qdpo_ce : in STD_LOGIC; -- Output register clock enable
qdpo : out STD_LOGIC_VECTOR(11 downto 0) -- 12-bit data output
);
end dist_sdpram;
architecture Behavioral of dist_sdpram is
type ram_type is array (0 to 31) of STD_LOGIC_VECTOR(11 downto 0);
signal ram : ram_type := (others => (others => '0')); -- Initialize RAM
begin
process(clk)
begin
if rising_edge(clk) then
if we = '1' then
ram(conv_integer(a)) <= d; -- Write operation
end if;
end if;
end process;
-- Read operation
process(clk)
begin
if rising_edge(clk) then
if qdpo_ce = '1' then
qdpo <= ram(conv_integer(dpra)); -- Read operation
end if;
end if;
end process;
end Behavioral;
调用两次封装为更大的sdpram_32x24_0oregs_wrapper
entity sdpram_32x24_0oregs_wrapper is
waddr : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address
wdata : in STD_LOGIC_VECTOR(11 downto 0); -- 12-bit data input
raddr : in STD_LOGIC_VECTOR(4 downto 0); -- 5-bit address for read
clk : in STD_LOGIC; -- Clock input
wen : in STD_LOGIC; -- Write enable
ren : in STD_LOGIC; -- Output register clock enable
q : out STD_LOGIC_VECTOR(11 downto 0) -- 12-bit data output
end sdpram_32x24_0oregs_wrapper;
architecture testbench of sdpram_32x24_tb is
component dist_sdpram_32x12
port (
clk : in std_logic;
we : in std_logic;
a : in std_logic_vector(4 downto 0);
d : in std_logic_vector(11 downto 0);
dpra : in std_logic_vector(4 downto 0);
qdpo_ce : in std_logic;
qdpo : out std_logic_vector(11 downto 0)
);
end component;
-- 测试平台内部连接RAM实体
begin
sdpram_L_inst: dist_sdpram_32x12
port map (
clk => clk,
we => wen,
a => waddr,
d => wdata (11 downto 0),
dpra => raddr,
qdpo_ce => ren,
qdpo => q (11 downto 0)
);
sdpram_H_inst: dist_sdpram_32x12
port map (
clk => clk,
we => wen,
a => waddr,
d => wdata (23 downto 12),
dpra => raddr,
qdpo_ce => ren,
qdpo => q (23 downto 12)
);
tb:
entity sdpram_32x24_tb is
-- 测试平台不需要端口
end sdpram_32x24_tb;
architecture testbench of sdpram_32x24_tb is
signal clk : std_logic := '0';
signal we : std_logic := '0';
signal a : std_logic_vector(4 downto 0) := (others => '0'); -- 写/读地址
signal d : std_logic_vector(23 downto 0) := (others => '0'); -- 数据输入
signal dpra : std_logic_vector(4 downto 0) := (others => '0'); -- 读地址
signal qdpo_ce : std_logic := '0'; -- 输出寄存器时钟使能
signal qdpo : std_logic_vector(23 downto 0); -- 数据输出
component sdpram_32x24
port (
clk : in std_logic;
we : in std_logic;
a : in std_logic_vector(4 downto 0);
d : in std_logic_vector(23 downto 0);
dpra : in std_logic_vector(4 downto 0);
qdpo_ce : in std_logic;
qdpo : out std_logic_vector(23 downto 0)
);
end component;
begin
uut: sdpram_32x24
port map (
clk => clk,
we => we,
a => a,
d => d,
dpra => dpra,
qdpo_ce => qdpo_ce,
qdpo => qdpo
);
clock: process
begin
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end process;
test_proc: process
begin
-- 初始化
we <= '0';
wait for 40 ns;
-- 写入24个数据到低位地址
we <= '1';
for i in 0 to 23 loop
a <= std_logic_vector(to_unsigned(i, a'length));
d <= std_logic_vector(to_unsigned(i, d'length)); -- 写入数据i
wait for 20 ns;
end loop;
we <= '0'; -- 确保写完后禁用写使能
-- 写入冲突数据
we <= '1';
a <= (others => '0'); -- 选择一个低位地址进行写入
d <= "1111111111111111111111111"; -- 写入新的数据
wait for 20 ns;
we <= '0'; -- 禁用写使能
-- 验证数据是否正确存储在低位
qdpo_ce <= '1';
for i in 0 to 23 loop
dpra <= std_logic_vector(to_unsigned(i, dpra'length));
wait for 20 ns;
if i = 0 then
assert qdpo = "1111111111111111111111111"
report "测试失败:地址0处读出的数据不正确,存在冲突"
severity error;
else
assert qdpo = std_logic_vector(to_unsigned(i, qdpo'length))
report "测试失败:地址 " & integer'image(i) & " 处读出的数据不正确"
severity error;
end if;
end loop;
-- 验证数据是否正确移位到高位
for i in 0 to 11 loop
dpra <= std_logic_vector(to_unsigned(23 - i, dpra'length));
wait for 20 ns;
assert qdpo = std_logic_vector(to_unsigned(23 - i, qdpo'length))
report "测试失败:地址 " & integer'image(23 - i) & " 处读出的数据不正确"
severity error;
end loop;
wait;
end process test_proc;
end testbench;
功能列表省略
标签:std,dist,自定义,--,IP,sdpram,downto,LOGIC,logic From: https://blog.csdn.net/weixin_60610210/article/details/142181993