--**********************************************************************
-- - H/W Development
Group
--
************************************************************************
--
-- Title: BASIC DAM CONTROLLER
--
-- Created: Fri Aug 25 17:58:34 2000
-- Author: DEEPAK GEORGE
-- Source File
Name: dma.vhd
--
-- $Id: dma.vhd,v
1.1 2000/08/25 17:58:34 acts Exp $
--
-- Description: This file give the vhdl code for a basic DMA
controller
--
connected to only one peripheral IO device.
--
-- Revision History:
Rev 1.0 2000/08/28 5:38PM
-- Rev 2.0 2000/08/29 10:45AM
--
-- $Log: dma.vhd $
--
--
************************************************************************
library IEEE, STD;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_components.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_misc.all;
use IEEE.std_logic_unsigned.all;
entity dma is
port (clk : in
std_logic;-- Clock
rst : in std_logic;-- Reset
dma_rq : in std_logic;-- DMA Request from peripheral
HLDA : in std_logic;-- HOLD ACK
from uP.
rd_b : in std_logic;-- Read
wr_b : in std_logic;-- Write
D_rdy : in std_logic;-- Indicates Status of IO Device
count : in std_logic_vector(7 downto 0);-- Count input
addrin : in std_logic_vector(7 downto 0);-- Addr. input
hold : out
std_logic;-- HOLD to uP
dma_ack : out std_logic;-- To peripheral
Memr_b : out std_logic;-- Memory Read
Memw_b : out std_logic;-- Memory Write
ior_b : out
std_logic;-- IO read
iow_b : out std_logic;-- IO write
TC : out std_logic;-- Terminal
Count
addrout : out std_logic_vector(7 downto 0) -- Addr. out.
);
end dma;
architecture dma_A of dma is
type state_t is
(s0,s1,s2,s3,s4);
signal state :
state_t;
signal counti : std_logic_vector(7 downto 0);
signal addri : std_logic_vector(7 downto 0);
-- stores the count and address on getting a DMA request
signal rd_bi : std_logic;
signal wr_bi : std_logic;
-- Stores the status of Read and Write signal
at the time of DMA req.
begin
main :
process(clk,rst)
begin
addri <= (others =>'0');
counti <= (others =>'0');
hold <= '0';
dma_ack <=
'0';
Memw_b <= '1';
ior_b <= '1';
Memr_b <= '1';
iow_b <= '1';
Tc <= '0';
state <= s0 ;
addr_out<=
(others=>'Z');
elsif (clk'event
and clk = '1') then
case state is
when s0 =>
if (dma_rq
= '1') then -- Check
for DMA Request
hold <= '1'; -- Issue HOLD
addri
<= addrin; --
Store Addr in addr reg
counti<= count;
-- Store Count in count reg
rd_bi
<= rd_b; --
Store RD signal
wr_bi
<= wr_b; -- Store WR signal
state
<= s1;
end if;
when s1 =>
if(hlda =
'1') then -- Check
for Hold Ack
dma_ack <= '1';
state <= s2 ;
end if;
when s2
=>
if (
D_rdy = '1') then --
Checks Status of IO Device
if
(rd_bi='0' and wr_bi='1') then --
Memory Read IO Write Operation
Memr_b <= '0';
iow_b <= '0';
Memw_b <= '1';
ior_b <= '1';
state <= s3;
elsif
(rd_bi='1' and wr_bi='0') then -- IO
Read Memory Write Operation
Memr_b <= '1';
iow_b <= '1';
Memw_b <= '0';
ior_b <= '0';
state <= s3;
end if;
end
if;
when s3
=>
-- Reset the R\W signals
Memw_b
<= '1';
ior_b <= '1';
Memr_b
<= '1';
iow_b <= '1';
state <= s4 ;
when s4 =>
if
(counti<="00000000") then
-- Checks for Terminal Count,if
tc <= '1'; --
reached gives TC = '1' and
hold <= '0'; --
deactivates the hold and waits
dma_ack<= '0';
-- for the next DMA request
to
-- appear.
state <= s0 ;
else -- If terminal count not reached
counti
<= counti - 1; -- then decriment the counter by
addri <= addri + 1; -- 1 and incriment the addr by 1
tc <= '0';
state <= s1 ;
end if;
end case;
end if;
end process;
---------------------------------------------------------------------------
-- Output the
address when Hold Ack is 1 and Device ready is 1, else
-- tristate the
address bus.
---------------------------------------------------------------------------
addrout <= addri when (D_Rdy = '1' and Hlda = '1') else
"ZZZZZZZZ";
end dma_A;