OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [dma6844.vhd] - Rev 101

Go to most recent revision | Compare with Previous | Blame | View Log

--===========================================================================--
--                                                                           --
--               Synthesizable 6844 Compatible DMA Controller                --
--                                                                           --
--===========================================================================--
--
--  File name      : dma6844.vhd
--
--  Entity name    : dma6844
--
--  Purpose        : Implements a 6844 compatible Direct Memory Access Controller
--                   It is intended for use with 68xx compatible FPGA SoCs.
--                  
--  Dependencies   : ieee.std_logic_1164
--                   ieee.std_logic_unsigned
--                   ieee.std_logic_arith
--                   unisim.vcomponents
--
--  Author         : John E. Kent
--
--  Email          : dilbert57@opencores.org      
--
--  Web            : http://opencores.org/project,system09
--
--  Registers      :
--
--  4 Channel version
--
--  IO +  0 = DMA_AH0 = Address Register 0 High
--  IO +  1 = DMA_AL0 = Address Register 0 Low
--  IO +  2 = DMA_CH0 = Count   Register 0 High
--  IO +  3 = DMA_CL0 = Count   Register 0 Low
--
--  IO +  4 = DMA_AH1 = Address Register 1 High
--  IO +  5 = DMA_AL1 = Address Register 1 Low
--  IO +  6 = DMA_CH1 = Count   Register 1 High
--  IO +  7 = DMA_CL1 = Count   Register 1 Low
-- 
--  IO +  8 = DMA_AH2 = Address Register 2 High
--  IO +  9 = DMA_AL2 = Address Register 2 Low
--  IO + 10 = DMA_CH2 = Count   Register 2 High
--  IO + 11 = DMA_CL2 = Count   Register 2 Low
-- 
--  IO + 12 = DMA_AH3 = Address Register 3 High
--  IO + 13 = DMA_AL3 = Address Register 3 Low
--  IO + 14 = DMA_CH3 = Count   Register 3 High
--  IO + 15 = DMA_CL3 = Count   Register 3 Low
--  
--  IO + 16 = DMA_CC0 = Channel Control Register 0
--  IO + 17 = DMA_CC1 = Channel Control Register 1
--  IO + 18 = DMA_CC2 = Channel Control Register 2
--  IO + 19 = DMA_CC3 = Channel Control Register 3
--    Bit[7] = DMA_DEF = DMA END FLAG (DEND)
--    Bit[6] = DMA_BSY = DMA BUSY FLAG (READ ONLY)
--    Bit[3] = DMA_AUD = DMA ADDRESS NOT UP/DOWN
--    Bit[2] = DMA_MCA = DMA MODE CONTROL 0=>DRQ2   1=>DRQ1 
--    Bit[1] = DMA_MCB = DMA MODE CONTROL 0=>SINGLE 1=>BLOCK 
--       0 0 = DMA_MD2 = DMA MODE 2 - SINGLE TRANSFER - DRQ2
--       0 1 = DMA_MD3 = DMA MODE 3 - BLOCK  TRANSFER - DRQ2
--       1 0 = DMA_MD1 = DMA MODE 1 - SINGLE TRANSFER - DRQ1
--       1 1 = DMA_MDU = DMA MODE 4 - BLOCK  TRANSFER - DRQ1 - ACTUALLY UDEFINED 
--    Bit[0] = DMA_RW  = DMA READ/NOT WRITE
--
--  IO + 20  = DMA_PRI = DMA Priority Control Register
--    Bit[7] = DMA_ROT = DMA Rotate Control 0=>FIXED 1=>ROTATE
--    Bit[3] = DMA_RE3 = DMA REQUEST ENABLE #3
--    Bit[2] = DMA_RE2 = DMA REQUEST ENABLE #2
--    Bit[1] = DMA_RE1 = DMA REQUEST ENABLE #1
--    Bit[0] = DMA_RE0 = DMA REQUEST ENABLE #0
-- 
--  IO + 21  = DMA_INT = DMA Interrupt Control Register
--    Bit[7] = DMA_IEF = DMA END IRQ FLAG
--    Bit[3] = DMA_IE3 = DMA END IRQ ENABLE #3
--    Bit[2] = DMA_IE2 = DMA END IRQ ENABLE #2
--    Bit[1] = DMA_IE1 = DMA END IRQ ENABLE #1
--    Bit[0] = DMA_IE0 = DMA END IRQ ENABLE #0
--  
--  IO + 22  = DMA_CHN = DMA Data Chain register
--    Bit[3] = DMA_C24 = TWO/FOUR CHANNEL SELECT
--    Bit[2] = DMA_DCB = DATA CHAIN CHANNEL SELECT B
--    Bit[1] = DMA_DCA = DATA CHAIN CHANNEL SELECT A
--    Bit[0] = DMA_DCE = DATA CHAIN ENABLE 
--
--  Copyright (C) 2010 John Kent
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
--===========================================================================--
--                                                                           --
--                              Revision  History                            --
--                                                                           --
--===========================================================================--
--
-- Revision Author        Date               Description
-- 0.1      John E. Kent  18th April 2010    Initial release
--
 
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_unsigned.all;
  use ieee.std_logic_arith.all;
 
library unisim;
  use unisim.vcomponents.all;
 
entity dma6844 is
   generic (
      ADDR_WIDTH = 16;
      DATA_WIDTH = 8;
      CHAN_COUNT = 4
      )
	port (
      --
      -- CPU Slave Interface
      --	
		clk      : in  std_logic;
		rst      : in  std_logic;
		rw       : out std_logic;
		cs       : out std_logic;
		addr     : in  std_logic_vector(LOG2(CHAN_COUNT*4*ADDR_WIDTH/DATA_WIDTH)-1 downto 0);
	   data_in  : in  std_logic_vector(DATA_WIDTH-1 downto 0);
	   data_out : out std_logic_vector(DATA_WIDTH-1 downto 0);
      irq      : out std_logic;
      --
      -- Bus Master Interface
      --
      breq     : out std_logic;
      bgnt     : in  std_logic;
      brw      : out std_logic;
      bvma     : out std_logic;
      baddr    : out std_logic_vector(ADDR_WIDTH-1 downto 0);
      --
      -- Device Interface
      --
      txreq    : in  std_logic_vector(CHAN_COUNT-1 downto 0);
      txstb    : out std_logic_vector(CHAN_COUNT-1 downto 0);
      txack    : out std_logic_vector(CHAN_COUNT-1 downto 0);
      txend    : out std_logic_vector(CHAN_COUNT-1 downto 0)
		);
end dma6844;
 
architecture rtl of dma6844 is
 
constant REG_COUNT : integer = (CHAN_COUNT * 2 * ADDR_WIDTH / DATA_WIDTH) + DMA_CHAN + 3;
 
subtype addr_subtype is std_logic_vector(ADDR_WIDTH-1 downto 0);
subtype data_subtype is std_logic_vector(DATA_WIDTH-1 downto 0);
 
type addr_type is array(0 to CHAN_COUNT-1) of addr_subtype;
type data_type is array(0 to CHAN_COUNT-1) of data_subtype;
type reg_type  is array(0 to REG_COUNT-1)  of data_subtype;
 
signal dma_addr    : addr_type;
signal dma_count   : addr_type;
signal dma_in_reg  : reg_type;
signal dma_out_reg : reg_type;
 
signal dma_reg_wr : std_logic := '0';
signal dma_reg_rd : std_logic := '0';
 
--
-- Registers
--
signal dma_adh_reg : data_type;
signal dma_adl_reg : data_type;
signal dma_cth_reg : data_type;
signal dma_ctl_reg : data_type;
signal dma_chc_reg : data_type;
signal dma_pri_reg : std_logic_vector(DATA_WIDTH-1 downto 0);
signal dma_irq_reg : std_logic_vector(DATA_WIDTH-1 downto 0);
signal dma_chn_reg : std_logic_vector(DATA_WIDTH-1 downto 0);
 
begin
--
-- Write to DMA input register
--
dma_reg_write : process( clk, rst )
variable reg_addr   : integer := 0;
begin
  if( falling_edge(clk) )
    if( rst = '1' ) then
      for i in 0 to CHAN_COUNT-1 loop
        dma_addr(i)   <= (others=>'0');
        dma_count(i)  <= (others=>'0');
      end loop;
      for i in 0 to REG_COUNT-1 loop
        dma_in_reg(i) <= (others=>'0');
      end loop;
    else
      if( cs='1' and rw='0' ) then
        reg_addr := conv_integer(addr(ADDR_WIDTH-1 downto 0));
        if( reg_addr < REG_COUNT ) then
          dma_in_reg(reg_addr) <= data_in;
        end if;
      end if;
    end if;
  end if;
end process;
 
--
-- Assign input register to specific register names
--
dma_reg_assign : process( dma_in_reg )
begin
  for i in 0 to CHAN_COUNT-1 loop
    dma_adh_reg(i) <= dma_in_reg((i*4)+0);
    dma_adl_reg(i) <= dma_in_reg((i*4)+1);
    dma_cth_reg(i) <= dma_in_reg((i*4)+2);
    dma_ctl_reg(i) <= dma_in_reg((i*4)+3);
    dma_chc_reg(i) <= dma_in_reg((CHAN_COUNT*4)+i);
  end loop;
  dma_pri_reg <= dma_in_reg((CHAN_COUNT*5)+0);
  dma_irq_reg <= dma_in_reg((CHAN_COUNT*5)+1);
  dma_chn_reg <= dma_in_reg((CHAN_COUNT*5)+2);
end process;
 
--
-- Process Transfer Request Inputs
--
dma_tx_req : process( clk, rst, txreq )
begin
  if( rising_edge( clk ) ) then
    if( rst='1' ) then
    else
      for i in 0 to CHAN_COUNT-1 loop
      end loop;
    end if;
  end if; 
end process;
 
end architecture rtl;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.