我正在尝试编写一个组件(mem_interface),它采用 8 位输入向量作为地址和数据,根据索引将它们写入更大的向量缓冲区中的特定位置,然后在被询问时输出这些更大的向量缓冲区。该组件将位于 picoblaze 处理器(只能输出 8 位值)和 Artix 7 BRAM 之间,我已将其配置为 18 位读/写端口宽度(即 11 位地址)。作为最终目标,mem_interface 将从 picoblaze 累积多个 8 位输出,然后使用提供的数据在提供的地址读取/写入 BRAM。
我遇到的问题是写入 mem_interface 的内部数据缓冲区没有生效。
在 15ns 时,测试台首先测试写入组件的地址缓冲区,它运行良好。在 45ns,它尝试写入数据缓冲区,该缓冲区立即将目标元素发送到“X”。我一直将“X”理解为多个驱动程序问题,但我无法在我的代码中识别一个。
这是代码,首先是 mem_interface.vhdl:
library ieee;
use ieee.std_logic_1164.all;
entity mem_interface is
port (
-- data inputs
clk : in std_logic;
idx : in std_logic_vector(1 downto 0);
split_addr_in : in std_logic_vector(7 downto 0);
split_data_in : in std_logic_vector(7 downto 0);
parity_in : in std_logic;
split_data_out : out std_logic_vector(7 downto 0);
parity_out : out std_logic;
-- signals
addr_buf_en : in std_logic;
data_buf_wr : in std_logic;
data_buf_rd : in std_logic;
reset_bufs : in std_logic;
write_to_mem : in std_logic;
read_from_mem : in std_logic;
-- to bram
addr_out : out std_logic_vector(15 downto 0);
data_out : out std_logic_vector(35 downto 0);
data_in : in std_logic_vector(35 downto 0)
);
end mem_interface;
architecture Behavioral of mem_interface is
signal addr_buf : std_logic_vector(15 downto 0) := (others => '0');
signal data_buf : std_logic_vector(35 downto 0) := (others => '0');
begin
handle_addr_buf : process(clk)
begin
if rising_edge(clk) then
if addr_buf_en = '1' then
case idx(0) is
when '0' => addr_buf(7 downto 0) <= split_addr_in;
when '1' => addr_buf(15 downto 8) <= split_addr_in;
when others => addr_buf <= "1010101010101010";
end case;
elsif reset_bufs = '1' then
addr_buf <= (others => '0');
end if;
end if;
end process handle_addr_buf;
handle_data_buf : process(clk)
begin
if rising_edge(clk) then
if data_buf_wr = '1' then
case idx is
when "00" => data_buf(7 downto 0) <= split_data_in;
data_buf(32) <= parity_in;
when "01" => data_buf(15 downto 8) <= split_data_in;
data_buf(33) <= parity_in;
when "10" => data_buf(23 downto 16) <= split_data_in;
data_buf(34) <= parity_in;
when "11" => data_buf(31 downto 24) <= split_data_in;
data_buf(35) <= parity_in;
when others => data_buf <= "101010101010101010101010101010101010";
end case;
elsif data_buf_rd = '1' then
case idx is
when "00" => parity_out <= data_buf(32);
split_data_out <= data_buf(7 downto 0);
when "01" => parity_out <= data_buf(33);
split_data_out <= data_buf(15 downto 8);
when "10" => parity_out <= data_buf(34);
split_data_out <= data_buf(23 downto 16);
when "11" => parity_out <= data_buf(35);
split_data_out <= data_buf(31 downto 24);
when others => split_data_out <= "10101010";
end case;
elsif reset_bufs = '1' then
data_buf <= (others => '0');
end if;
end if;
end process handle_data_buf;
handle_memory : process(clk)
begin
if rising_edge(clk) then
if write_to_mem = '1' then
addr_out <= addr_buf;
data_out <= data_buf;
elsif read_from_mem = '1' then
addr_out <= addr_buf;
data_buf <= data_in;
else
addr_out <= (others => '0');
data_out <= (others => '0');
end if;
end if;
end process handle_memory;
end Behavioral;
这是测试平台,mem_interface_tb.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mem_interface_tb is
-- Port ( );
end mem_interface_tb;
architecture Behavioral of mem_interface_tb is
component mem_interface is
port (
-- data inputs
clk : in std_logic;
idx : in std_logic_vector(1 downto 0);
split_addr_in : in std_logic_vector(7 downto 0);
split_data_in : in std_logic_vector(7 downto 0);
parity_in : in std_logic;
split_data_out : out std_logic_vector(7 downto 0);
parity_out : out std_logic;
-- signals
addr_buf_en : in std_logic;
data_buf_wr : in std_logic;
data_buf_rd : in std_logic;
reset_bufs : in std_logic;
write_to_mem : in std_logic;
read_from_mem : in std_logic;
-- to bram
addr_out : out std_logic_vector(15 downto 0);
data_out : out std_logic_vector(35 downto 0);
data_in : in std_logic_vector(35 downto 0)
);
end component;
component sim_clk_wrapper
port (
sim_clk_out : out std_logic;
sim_rst_out : out std_logic
);
end component;
signal sim_clk_sig : std_logic;
signal sim_rst_sig : std_logic;
signal sim_idx : std_logic_vector(1 downto 0) := "00";
signal sim_split_addr_in : std_logic_vector(7 downto 0) := (others => '0');
signal sim_split_data_in : std_logic_vector(7 downto 0) := (others => '0');
signal sim_parity_in : std_logic := '0';
signal sim_split_data_out : std_logic_vector(7 downto 0) := (others => '0');
signal sim_parity_out : std_logic := '0';
signal sim_addr_buf_en : std_logic := '0';
signal sim_data_buf_wr : std_logic := '0';
signal sim_data_buf_rd : std_logic := '0';
signal sim_reset_bufs : std_logic := '0';
signal sim_write_to_mem : std_logic := '0';
signal sim_read_from_mem : std_logic := '0';
signal sim_addr_out : std_logic_vector(15 downto 0) := (others => '0');
signal sim_data_out : std_logic_vector(35 downto 0) := (others => '0');
signal sim_data_in : std_logic_vector(35 downto 0) := (others => '0');
type bram_36k is array (0 to 2048) of std_logic_vector(17 downto 0);
signal sim_bram_36k : bram_36k;
begin
sim_clk_gen : sim_clk_wrapper
port map (
sim_clk_out => sim_clk_sig,
sim_rst_out => sim_rst_sig
);
UUT : mem_interface
port map (
clk => sim_clk_sig,
idx => sim_idx,
split_addr_in => sim_split_addr_in,
split_data_in => sim_split_data_in,
parity_in => sim_parity_in,
split_data_out => sim_split_data_out,
parity_out => sim_parity_out,
addr_buf_en => sim_addr_buf_en,
data_buf_wr => sim_data_buf_wr,
data_buf_rd => sim_data_buf_rd,
reset_bufs => sim_reset_bufs,
write_to_mem => sim_write_to_mem,
read_from_mem => sim_read_from_mem,
addr_out => sim_addr_out,
data_out => sim_data_out,
data_in => sim_data_in
);
-- simulating 18 bit port sizes with 11 bit addresses
manage_sim_bram : process(sim_clk_sig)
begin
if rising_edge(sim_clk_sig) then
if sim_write_to_mem = '1' then
sim_bram_36k(to_integer(unsigned(sim_addr_out(14 downto 4)))) <= sim_data_out(33 downto 32) & sim_data_out(15 downto 0);
elsif sim_read_from_mem = '1' then
sim_data_in(33 downto 32) <= sim_bram_36k(to_integer(unsigned(sim_addr_out(14 downto 4))))(17 downto 16);
sim_data_in(15 downto 0) <= sim_bram_36k(to_integer(unsigned(sim_addr_out(14 downto 4))))(15 downto 0);
end if;
end if;
end process manage_sim_bram;
simulate: process
begin
wait until rising_edge(sim_clk_sig);
sim_reset_bufs <= '1';
wait until rising_edge(sim_clk_sig);
-- first write an address to the buffer
sim_reset_bufs <= '0';
sim_addr_buf_en <= '1';
sim_idx <= "00";
sim_split_addr_in <= "00001111";
wait until rising_edge(sim_clk_sig);
sim_idx <= "01";
sim_split_addr_in <= "10000000";
wait until rising_edge(sim_clk_sig);
-- disable writing to address
sim_addr_buf_en <= '0';
sim_split_addr_in <= "00000000";
sim_idx <= "00";
wait until rising_edge(sim_clk_sig);
-- write to the data
sim_data_buf_wr <= '1';
sim_idx <= "00";
sim_split_data_in <= "11111111";
sim_parity_in <= '1';
wait until rising_edge(sim_clk_sig);
sim_idx <= "01";
sim_split_data_in <= "11111111";
sim_parity_in <= '1';
wait until rising_edge(sim_clk_sig);
-- then write the data to the memory
sim_data_buf_wr <= '0';
sim_split_data_in <= "00000000";
sim_parity_in <= '0';
sim_write_to_mem <= '1';
wait until rising_edge(sim_clk_sig);
wait until rising_edge(sim_clk_sig);
wait until rising_edge(sim_clk_sig);
end process simulate;
end Behavioral;
任何帮助将不胜感激,我已经盯着这个几个小时了,不知道问题出在哪里。