1

我正在尝试编写一个组件(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;

任何帮助将不胜感激,我已经盯着这个几个小时了,不知道问题出在哪里。

4

0 回答 0