avalon-dma/design/dma_31ch.vhd

325 lines
11 KiB
VHDL
Raw Normal View History

2018-03-06 15:11:37 +01:00
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dma_31ch is
generic(
channel_config_g : std_logic_vector(3 downto 0) := "1011";
channel_count_g : integer range 1 to 31 := 31
);
port(
-- Generic I/O
dma_clk : in std_logic;
dma_rst : in std_logic;
-- Trigger inputs (only valid if dma channel is inactive)
dma_trig : in std_logic_vector(channel_count_g - 1 downto 0);
-- Interrupt output
inta : out std_logic;
-- Config interface (Avalon slave)
dma_conf_write : in std_logic;
dma_conf_read : in std_logic;
dma_conf_cs : in std_logic;
dma_conf_waitrequest : out std_logic;
dma_conf_data_from_dma : out std_logic_vector(31 downto 0);
dma_conf_data_to_dma : in std_logic_vector(31 downto 0);
dma_conf_addr : in std_logic_vector(15 downto 0);
dma_conf_response : out std_logic_vector(1 downto 0);
-- DMA Master Interface 0
dma_mst0_write : out std_logic;
dma_mst0_read : out std_logic;
dma_mst0_cs : out std_logic;
dma_mst0_waitrequest : in std_logic;
dma_mst0_data_to_dma : in std_logic_vector(31 downto 0);
dma_mst0_data_from_dma : out std_logic_vector(31 downto 0);
dma_mst0_addr : out std_logic_vector(31 downto 0);
-- DMA Master Interface 1
dma_mst1_write : out std_logic;
dma_mst1_read : out std_logic;
dma_mst1_cs : out std_logic;
dma_mst1_waitrequest : in std_logic;
dma_mst1_data_to_dma : in std_logic_vector(31 downto 0);
dma_mst1_data_from_dma : out std_logic_vector(31 downto 0);
dma_mst1_addr : out std_logic_vector(31 downto 0)
);
end entity dma_31ch;
architecture RTL of dma_31ch is
constant ch_conf : std_logic_vector(3 downto 0) := channel_config_g;
component avalon2wb
generic(
ADDR_WIDTH_G : natural := 32;
DATA_WIDTH_G : natural := 32
);
port(
avalon_write : in std_logic;
avalon_read : in std_logic;
avalon_cs : in std_logic;
avalon_waitrequest : out std_logic;
avalon_data_in : in std_logic_vector(DATA_WIDTH_G - 1 downto 0);
avalon_data_out : out std_logic_vector(DATA_WIDTH_G - 1 downto 0);
avalon_address : in std_logic_vector(ADDR_WIDTH_G - 1 downto 0);
avalon_response : out std_logic_vector(1 downto 0);
wb_cyc : out std_logic;
wb_we : out std_logic;
wb_stb : out std_logic;
wb_ack : in std_logic;
wb_address : out std_logic_vector(ADDR_WIDTH_G - 1 downto 0);
wb_data_out : out std_logic_vector(DATA_WIDTH_G - 1 downto 0);
wb_data_in : in std_logic_vector(DATA_WIDTH_G - 1 downto 0);
wb_err_i : in std_logic;
wb_rty_i : in std_logic
);
end component avalon2wb;
component wb2avalon
generic(
ADDR_WIDTH_G : natural := 32;
DATA_WIDTH_G : natural := 32
);
port(
avalon_write : out std_logic;
avalon_read : out std_logic;
avalon_cs : out std_logic;
avalon_waitrequest : in std_logic;
avalon_data_in : in std_logic_vector(DATA_WIDTH_G - 1 downto 0);
avalon_data_out : out std_logic_vector(DATA_WIDTH_G - 1 downto 0);
avalon_address : out std_logic_vector(ADDR_WIDTH_G - 1 downto 0);
wb_cyc : in std_logic;
wb_we : in std_logic;
wb_stb : in std_logic;
wb_ack : out std_logic;
wb_address : in std_logic_vector(ADDR_WIDTH_G - 1 downto 0);
wb_data_out : out std_logic_vector(DATA_WIDTH_G - 1 downto 0);
wb_data_in : in std_logic_vector(DATA_WIDTH_G - 1 downto 0);
wb_err : out std_logic;
wb_rty : out std_logic
);
end component wb2avalon;
-- Wishbone Config interface
signal wb_conf_addr : std_logic_vector(31 downto 0);
signal wb_conf_data_to_dma : std_logic_vector(31 downto 0);
signal wb_conf_data_from_dma : std_logic_vector(31 downto 0);
signal wb_conf_sel : std_logic_vector(3 downto 0);
signal wb_conf_we : std_logic;
signal wb_conf_cyc : std_logic;
signal wb_conf_stb : std_logic;
signal wb_conf_ack : std_logic;
signal wb_conf_err : std_logic;
signal wb_conf_rty : std_logic;
-- Wishbone Master Interface 0
signal wb_m0_addr : std_logic_vector(31 downto 0);
signal wb_m0_data_to_dma : std_logic_vector(31 downto 0);
signal wb_m0_data_from_dma : std_logic_vector(31 downto 0);
signal wb_m0_sel : std_logic_vector(3 downto 0);
signal wb_m0_we : std_logic;
signal wb_m0_cyc : std_logic;
signal wb_m0_stb : std_logic;
signal wb_m0_ack : std_logic;
signal wb_m0_err : std_logic;
signal wb_m0_rty : std_logic;
-- Wishbone Master Interface 1
signal wb_m1_addr : std_logic_vector(31 downto 0);
signal wb_m1_data_to_dma : std_logic_vector(31 downto 0);
signal wb_m1_data_from_dma : std_logic_vector(31 downto 0);
signal wb_m1_sel : std_logic_vector(3 downto 0);
signal wb_m1_we : std_logic;
signal wb_m1_cyc : std_logic;
signal wb_m1_stb : std_logic;
signal wb_m1_ack : std_logic;
signal wb_m1_err : std_logic;
signal wb_m1_rty : std_logic;
-- DMA trigger/request signals
signal dma_req : std_logic_vector(channel_count_g - 1 downto 0);
signal dma_req_ack : std_logic_vector(channel_count_g - 1 downto 0);
-- DMA Config address Signals
signal wb_conf_addr_premask : std_logic_vector(15 downto 0);
begin
-- DMA instance
wb_dma_top_inst : entity work.wb_dma_top
generic map(
rf_addr => x"F", -- Top address width. Will be remapped by wrapper
pri_sel => "00", -- Only 1 priority
ch_count => channel_count_g,
ch0_conf => ch_conf,
ch1_conf => ch_conf,
ch2_conf => ch_conf,
ch3_conf => ch_conf,
ch4_conf => ch_conf,
ch5_conf => ch_conf,
ch6_conf => ch_conf,
ch7_conf => ch_conf,
ch8_conf => ch_conf,
ch9_conf => ch_conf,
ch10_conf => ch_conf,
ch11_conf => ch_conf,
ch12_conf => ch_conf,
ch13_conf => ch_conf,
ch14_conf => ch_conf,
ch15_conf => ch_conf,
ch16_conf => ch_conf,
ch17_conf => ch_conf,
ch18_conf => ch_conf,
ch19_conf => ch_conf,
ch20_conf => ch_conf,
ch21_conf => ch_conf,
ch22_conf => ch_conf,
ch23_conf => ch_conf,
ch24_conf => ch_conf,
ch25_conf => ch_conf,
ch26_conf => ch_conf,
ch27_conf => ch_conf,
ch28_conf => ch_conf,
ch29_conf => ch_conf,
ch30_conf => ch_conf
)
port map(
clk_i => dma_clk,
rst_i => dma_rst,
wb0s_data_i => wb_conf_data_to_dma,
wb0s_data_o => wb_conf_data_from_dma,
wb0_addr_i => wb_conf_addr,
wb0_sel_i => wb_conf_sel,
wb0_we_i => wb_conf_we,
wb0_cyc_i => wb_conf_cyc,
wb0_stb_i => wb_conf_stb,
wb0_ack_o => wb_conf_ack,
wb0_err_o => wb_conf_err,
wb0_rty_o => wb_conf_rty,
wb0m_data_i => wb_m0_data_to_dma,
wb0m_data_o => wb_m0_data_from_dma,
wb0_addr_o => wb_m0_addr,
wb0_sel_o => wb_m0_sel,
wb0_we_o => wb_m0_we,
wb0_cyc_o => wb_m0_cyc,
wb0_stb_o => wb_m0_stb,
wb0_ack_i => wb_m0_ack,
wb0_err_i => wb_m0_err,
wb0_rty_i => wb_m0_rty,
wb1s_data_i => (others => '0'),
wb1s_data_o => open,
wb1_addr_i => open,
wb1_sel_i => open,
wb1_we_i => open,
wb1_cyc_i => open,
wb1_stb_i => open,
wb1_ack_o => open,
wb1_err_o => open,
wb1_rty_o => open,
wb1m_data_i => wb_m1_data_to_dma,
wb1m_data_o => wb_m1_data_from_dma,
wb1_addr_o => wb_m1_addr,
wb1_sel_o => wb_m1_sel,
wb1_we_o => wb_m1_we,
wb1_cyc_o => wb_m1_cyc,
wb1_stb_o => wb_m1_stb,
wb1_ack_i => wb_m1_ack,
wb1_err_i => wb_m1_err,
wb1_rty_i => wb_m1_rty,
dma_req_i => dma_req,
dma_nd_i => (others => '0'),
dma_ack_o => dma_req_ack,
dma_rest_i => (others => '0'),
inta_o => inta,
intb_o => open
);
config_iface: avalon2wb
generic map(
ADDR_WIDTH_G => 16,
DATA_WIDTH_G => 32
)
port map(
avalon_write => dma_conf_write,
avalon_read => dma_conf_read,
avalon_cs => dma_conf_cs,
avalon_waitrequest => dma_conf_waitrequest,
avalon_data_in => dma_conf_data_to_dma,
avalon_data_out => dma_conf_data_from_dma,
avalon_address => dma_conf_addr,
avalon_response => dma_conf_response,
wb_cyc => wb_conf_cyc,
wb_we => wb_conf_we,
wb_stb => wb_conf_stb,
wb_ack => wb_conf_ack,
wb_address => wb_conf_addr_premask,
wb_data_out => wb_conf_data_to_dma,
wb_data_in => wb_conf_data_from_dma,
wb_err_i => wb_conf_err,
wb_rty_i => wb_conf_rty
);
master_ifac0: wb2avalon
generic map(
ADDR_WIDTH_G => 32,
DATA_WIDTH_G => 32
)
port map(
avalon_write => dma_mst0_write,
avalon_read => dma_mst0_read,
avalon_cs => dma_mst0_cs,
avalon_waitrequest => dma_mst0_waitrequest,
avalon_data_in => dma_mst0_data_to_dma,
avalon_data_out => dma_mst0_data_from_dma,
avalon_address => dma_mst0_addr,
wb_cyc => wb_m0_cyc,
wb_we => wb_m0_we,
wb_stb => wb_m0_stb,
wb_ack => wb_m0_ack,
wb_address => wb_m0_addr,
wb_data_out => wb_m0_data_to_dma,
wb_data_in => wb_m0_data_from_dma,
wb_err => wb_m0_err,
wb_rty => wb_m0_rty
);
master_iface1: wb2avalon
generic map(
ADDR_WIDTH_G => 32,
DATA_WIDTH_G => 32
)
port map(
avalon_write => dma_mst1_write,
avalon_read => dma_mst1_read,
avalon_cs => dma_mst1_cs,
avalon_waitrequest => dma_mst1_waitrequest,
avalon_data_in => dma_mst1_data_to_dma,
avalon_data_out => dma_mst1_data_from_dma,
avalon_address => dma_mst1_addr,
wb_cyc => wb_m1_cyc,
wb_we => wb_m1_we,
wb_stb => wb_m1_stb,
wb_ack => wb_m1_ack,
wb_address => wb_m1_addr,
wb_data_out => wb_m1_data_to_dma,
wb_data_in => wb_m1_data_from_dma,
wb_err => wb_m1_err,
wb_rty => wb_m1_rty
);
-- DMA config address range is at the "top" of 32-bit address space beginning at 0xF0000000
wb_conf_addr <= x"F000" & wb_conf_addr_premask;
trigger_handshake : for i in 0 to channel_count_g - 1 generate
handshake_proc : process(dma_clk, dma_rst) is
begin
if dma_rst = '1' then
dma_req <= (others => '0');
elsif rising_edge(dma_clk) then
if dma_req_ack(i) = '1' and dma_req(i) = '1' then
dma_req(i) <= '0';
elsif dma_trig(i) = '1' then
dma_req(i) <= '1';
end if;
end if;
end process handshake_proc;
end generate trigger_handshake;
end architecture RTL;