Создал компонент Avalon MM Slave с пользовательской логикой.
В качестве пользовательской логики двухпортовая RAM куда с помощью
внешней кнопки загружаются 4 слова данных с последующим тестом чтения (для просмотра на wavwform) в
соответствии с диаграммой работы двухпортовой памяти.
Вот верхний уровень
CODE
--------------------------------------------------------------------
-- Project : ramtest
--------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
entity ramtest is
port (
-- Avalon Slave
clk : in std_logic := '0'; -- clock.clk
reset_n : in std_logic := '0'; -- .reset_n
avs_s0_address : in std_logic_vector(1 downto 0) := (others => '0'); -- s0.address
avs_s0_read_n : in std_logic := '0'; -- .read_n
avs_s0_readdata : out std_logic_vector(15 downto 0); -- .readdata
avs_s0_write_n : in std_logic := '0'; -- .write_n
avs_s0_writedata : in std_logic_vector(15 downto 0) := (others => '0'); -- .writedata
avs_s0_chipselect : in std_logic := '1'; -- .chipselect
-- ins_irq0_irq : out std_logic;
-- RAM Exports
-- Вспомогательные сигналы (тест загрузки и чтения RAM)
ldrd : in std_logic := '1'; -- внешний старт записи-чтения RAM (от кнопки)
ram_load : out std_logic; -- старт загрузки RAM (для теста)
ram_wr : out std_logic; -- строб записи RAM
ram_rd : out std_logic; -- строб чтения RAM
ram_ld : out std_logic; --
ram_wt : out std_logic; --
cnt_out : out std_logic; --
ram_read : out std_logic; -- старт чтение RAM (для теста)
ram_data_in : out std_logic_vector(15 downto 0); -- входные данные RAM (для теста)
ram_data_out : out std_logic_vector(15 downto 0) -- выходные данные RAM (для теста)
);
end entity ramtest;
architecture rtl of ramtest is
--------------------------------------------------------------------
-- компонент двухпортовая RAM
component ramresult
generic
(
DATA_WIDTH : integer := 16;
ADDR_WIDTH : integer := 2
);
port
(
rclk : in std_logic;
wclk : in std_logic;
raddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
waddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
-- сигналы загрузки и теста чтения RAM
signal cnt : std_logic_vector(3 downto 0) := X"0"; -- делитель
signal s_data_in : std_logic_vector(15 downto 0) := X"0000"; -- данные RAM (вход)
signal s_data_out : std_logic_vector(15 downto 0); -- данные RAM (выход)
signal s_rd : std_logic; -- клок чтения из RAM
signal s_wr : std_logic; -- клок записи в RAM
signal s_we : std_logic := '1'; -- выбор кристалла
signal s_addr_rd_ram : std_logic_vector(1 downto 0); -- адрес чтения
signal s_addr_wr_ram : std_logic_vector(1 downto 0); -- адрес записи
signal en_loadcnt : std_logic := '0'; -- разрешение загрузки в RAM
signal en_readcnt : std_logic := '0'; -- разрешение чтения из RAM
signal s_lrcnt : std_logic_vector(5 downto 0) := "000000"; -- счетчик
signal s_ramload : std_logic := '1'; --
signal s_ramread : std_logic := '1'; --
signal en_wrrd : std_logic := '0'; --
-- сигналы для шины Avalon
signal avs_s0_readdata_reg : std_logic_vector(15 downto 0);
begin
uramresult : ramresult
generic map (16, 2)
port map (rclk => s_rd, wclk => s_wr, raddr => s_addr_rd_ram,
waddr => s_addr_wr_ram, data => s_data_in, we => s_we, q => s_data_out);
--------------------------------------------------------------------
-- Вспомогательные сигналы
--------------------------------------------------------------------
--
process(clk)
begin
if (rising_edge(clk)) then
cnt <= cnt + 1;
end if;
end process;
cnt_out <= cnt(0);
process(cnt(0))
begin
if (rising_edge(cnt(0))) then
if(ldrd = '0') then
en_wrrd <= '1';
end if;
if(en_wrrd = '1') then
s_lrcnt <= s_lrcnt + 1;
end if;
if (s_lrcnt = "000011") then
s_ramload <= '0';
elsif (s_lrcnt = "000101") then
s_ramload <= '1';
elsif (s_lrcnt = "001011") then
s_ramread <= '0';
elsif (s_lrcnt = "001101") then
s_ramread <= '1';
elsif (s_lrcnt = "101101") then
en_wrrd <= '0';
end if;
end if;
end process;
ram_ld <= s_ramload;
ram_wt <= s_ramread;
--------------------------------------------------------------------
-- Заполнение RAM
--------------------------------------------------------------------
-- старт стоп перебора адресов RAM
process(cnt(0))
begin
if (falling_edge(cnt(0))) then
if(s_ramload = '0') then
en_loadcnt <= '1';
end if;
if(en_loadcnt = '1') then
s_addr_wr_ram <= s_addr_wr_ram + 1;
else
s_addr_wr_ram <= (others => '0');
end if;
if(s_addr_wr_ram = "11") then
en_loadcnt <= '0';
end if;
end if;
end process;
ram_load <= en_loadcnt;
s_wr <= not((cnt(0) and en_loadcnt) and (not clk));
ram_wr <= s_wr;
-- загрузка RAM
process(cnt(0))
begin
if (rising_edge(cnt(0))) then
if(en_loadcnt = '1') then
if(s_addr_wr_ram = "00") then
s_data_in <= X"0102";
elsif(s_addr_wr_ram = "01") then
s_data_in <= X"0304";
elsif(s_addr_wr_ram = "10") then
s_data_in <= X"0506";
elsif(s_addr_wr_ram = "11") then
s_data_in <= X"0708";
end if;
end if;
end if;
end process;
ram_data_in <= s_data_in;
--------------------------------------------------------------------
-- Чтение RAM (для тестирования)
--------------------------------------------------------------------
-- старт стоп перебора адресов RAM
process(cnt(0))
begin
if (falling_edge(cnt(0))) then
if(s_ramread = '0') then
en_readcnt <= '1';
s_we <= '0';
end if;
if(en_readcnt = '1') then
s_addr_rd_ram <= s_addr_rd_ram + 1;
end if;
if(s_addr_rd_ram = "11") then
en_readcnt <= '0';
s_we <= '1';
end if;
end if;
end process;
ram_read <= en_readcnt;
s_rd <= cnt(0) and en_readcnt;
ram_rd <= s_rd;
ram_data_out <= s_data_out;
--------------------------------------------------------------------
-- Avalon slave register read logic
--------------------------------------------------------------------
process(clk)
begin
if (falling_edge(clk)) then
if(reset_n = '0') then
avs_s0_readdata_reg <= (others => '0');
else if(avs_s0_read_n = '0' and ) then
avs_s0_readdata_reg <= s_data_out;
end if;
end if;
end if;
end process;
avs_s0_readdata <= avs_s0_readdata_reg;
end architecture rtl; -- of ramtest
Вот двухпортовая RAM
CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ramresult is
generic
(
DATA_WIDTH : natural := 16;
ADDR_WIDTH : natural := 2
);
port
(
rclk : in std_logic;
wclk : in std_logic;
raddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
waddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic;
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end ramresult;
architecture behavioural of ramresult is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM signal.
signal ram : memory_t;
begin
process(wclk)
begin
if(falling_edge(wclk)) then
ram(conv_integer(waddr)) <= data;
end if;
end process;
process(rclk)
begin
if(rising_edge(rclk)) then
if(we = '0') then
q <= ram(conv_integer(raddr));
else
q <= (others => 'Z');
end if;
end if;
end process;
end behavioural;
Вот Waveform
Далее ступор.
Не понимаю как теперь построить логику переноса данных из этой же RAM на шину Avalon
имея набор только этих сигналов
Очевидно нужен промежуточный регистр между выходом RAM и Avalon.
Кому приходилось с этим сталкиваться подскажите please как примерно это должно выглядеть в коде (Avalon slave register read logic).
Если не в коде, то словах тоже думаю пойму.
Сообщение отредактировал Acvarif - Aug 17 2012, 06:49