Проблема с назначением с std_logic_vector - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь написать компонент (mem_interface), который принимает 8-битные входные векторы для адреса и данных, записывает их в определенные позиции в больших векторных буферах в зависимости от индекса, а затем выводит эти большие векторные буферы при запросе.Компонент будет находиться между процессором picoblaze (который может выводить только 8-битные значения) и Artix 7 BRAM, который я настроил с 18-битной шириной порта чтения / записи (так что 11-битные адреса).В качестве конечной цели mem_interface будет накапливать несколько 8-битных выходных сигналов из picoblaze, а затем считывать / записывать BRAM по предоставленному адресу с предоставленными данными.

У меня проблема в том, что запись во внутренний буфер данных mem_interface не вступает в силу.

simulation screenshot.

At15ns, testbench сначала тестирует запись в адресный буфер компонента, который отлично работает.При 45 нс он пытается выполнить запись в буфер данных, который немедленно отправляет целевые элементы в «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;

Любая помощь будет оценена, я смотрю на это в течение нескольких часов и не знаю, в чем проблема.

...