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;