Initial revision
Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@975 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
-----------------------------------------------------------------------
|
||||
-- $Header: /tmp/cvsroot/VHDL/lib/JBUS/src/dmac.vhd,v 1.1 2013-05-28 10:18:02 jens Exp $
|
||||
-----------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.utils_pkg.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
------------------------------------------------------------------
|
||||
entity dmac is
|
||||
Generic
|
||||
(
|
||||
DATA_WIDTH : natural := 32;
|
||||
XFER_CHUNK_SIZE : natural := 512
|
||||
);
|
||||
Port
|
||||
(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
master_req : out std_logic;
|
||||
master_gnt : in std_logic;
|
||||
|
||||
dma_active : out std_logic;
|
||||
|
||||
req_rdy : out std_logic;
|
||||
req_en : in std_logic;
|
||||
req_rw : in std_logic;
|
||||
req_addr_start : in unsigned(31 downto 0);
|
||||
req_num_xfers : in unsigned(31 downto 0);
|
||||
req_addr_auto_inc : in std_logic;
|
||||
|
||||
req_complete : out std_logic;
|
||||
req_complete_ack : in std_logic;
|
||||
|
||||
-- busmaster control
|
||||
bus_cyc_complete : in std_logic;
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_out : out bm_cmd_t
|
||||
);
|
||||
end dmac;
|
||||
|
||||
architecture Behavioral of dmac is
|
||||
|
||||
signal start_en : std_logic;
|
||||
signal finish_en : std_logic;
|
||||
signal complete : std_logic;
|
||||
signal addr_inc_en : std_logic;
|
||||
signal addr : unsigned(31 downto 0);
|
||||
signal rw : std_logic;
|
||||
|
||||
signal req_count_en : std_logic;
|
||||
signal req_count : unsigned(31 downto 0);
|
||||
signal req_count_next : unsigned(32 downto 0);
|
||||
signal req_count_rdy : std_logic;
|
||||
|
||||
signal chunk_count_rst : std_logic;
|
||||
signal chunk_count_en : std_logic;
|
||||
signal chunk_count : unsigned(31 downto 0);
|
||||
signal chunk_count_next : unsigned(32 downto 0);
|
||||
signal chunk_count_rdy : std_logic;
|
||||
|
||||
type state_t is (INIT, READY, SETUP, XFER, FINISH);
|
||||
signal s, sn : state_t;
|
||||
|
||||
begin
|
||||
|
||||
bus_cmd_out.addr <= addr;
|
||||
bus_cmd_out.sel <= (others => '1');
|
||||
bus_cmd_out.rw <= rw;
|
||||
req_complete <= complete;
|
||||
|
||||
state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
s <= INIT;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
state:
|
||||
process(s, req_en, master_gnt, req_count_rdy, chunk_count_rdy, bus_cyc_complete, bus_cmd_rdy)
|
||||
begin
|
||||
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
start_en <= '0';
|
||||
finish_en <= '0';
|
||||
req_count_en <= '0';
|
||||
req_rdy <= '0';
|
||||
chunk_count_rst <= '0';
|
||||
chunk_count_en <= '0';
|
||||
master_req <= '0';
|
||||
dma_active <= '0';
|
||||
|
||||
sn <= s;
|
||||
case s is
|
||||
when INIT =>
|
||||
sn <= READY;
|
||||
|
||||
when READY =>
|
||||
req_rdy <= '1';
|
||||
if req_en = '1' then
|
||||
start_en <= '1';
|
||||
sn <= SETUP;
|
||||
end if;
|
||||
|
||||
when SETUP =>
|
||||
master_req <= '1';
|
||||
chunk_count_rst <= '1';
|
||||
if req_count_rdy = '1' then
|
||||
sn <= READY;
|
||||
elsif master_gnt = '1' and bus_cyc_complete = '1' then
|
||||
sn <= XFER;
|
||||
end if;
|
||||
|
||||
when XFER =>
|
||||
dma_active <= '1';
|
||||
master_req <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
req_count_en <= bus_cmd_rdy;
|
||||
chunk_count_en <= bus_cmd_rdy;
|
||||
if req_count_rdy = '1' then
|
||||
sn <= FINISH;
|
||||
elsif chunk_count_rdy = '1' then
|
||||
sn <= SETUP;
|
||||
end if;
|
||||
|
||||
when FINISH =>
|
||||
master_req <= '1';
|
||||
if bus_cyc_complete = '1' then
|
||||
sn <= READY;
|
||||
finish_en <= '1';
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
sn <= READY;
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
addr_gen:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if start_en = '1' then
|
||||
rw <= req_rw;
|
||||
addr <= req_addr_start;
|
||||
addr_inc_en <= req_addr_auto_inc;
|
||||
elsif req_count_en = '1' and addr_inc_en = '1' then
|
||||
addr <= addr + DATA_WIDTH/8;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
req_count_next <= ('0' & req_num_xfers) - 1 when start_en = '1' else ('0' & req_count) - 1;
|
||||
req_count_rdy <= req_count_next(32);
|
||||
|
||||
req_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if start_en = '1' then
|
||||
req_count <= req_count_next(31 downto 0);
|
||||
elsif req_count_en = '1' then
|
||||
if req_count_rdy = '0' then
|
||||
req_count <= req_count_next(31 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
chunk_count_next <= to_unsigned(XFER_CHUNK_SIZE, 33) - 1 when chunk_count_rst = '1' else ('0' & chunk_count) - 1;
|
||||
chunk_count_rdy <= chunk_count_next(32);
|
||||
|
||||
chunk_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if chunk_count_rst = '1' then
|
||||
chunk_count <= chunk_count_next(31 downto 0);
|
||||
elsif chunk_count_en = '1' then
|
||||
if chunk_count_rdy = '0' then
|
||||
chunk_count <= chunk_count_next(31 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
complete_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if start_en = '1' or rst = '1' then
|
||||
complete <= '0';
|
||||
elsif complete = '0' then
|
||||
if finish_en = '1' then
|
||||
complete <= '1';
|
||||
elsif req_complete_ack = '1' then
|
||||
complete <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
Reference in New Issue
Block a user