⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmactrl.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------  This file is a part of the GRLIB VHDL IP LIBRARY--  Copyright (C) 2003, Gaisler Research----  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 2 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, write to the Free Software--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ------------------------------------------------------------------------------- Entity:  dmactrl-- File:  dmactrl.vhd-- Author:  Alf Vaerneus - Gaisler Research-- Modified:  Nils-Johan Wessman - Gaisler Research-- Description:	Simple DMA controller------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;use grlib.devices.all;library gaisler;use gaisler.misc.all;use gaisler.pci.all;entity dmactrl is  generic (    hindex    : integer := 0;    slvindex  : integer := 0;    pindex    : integer := 0;    paddr     : integer := 0;    pmask     : integer := 16#fff#;    blength   : integer := 4  );  port (    rst       : in std_logic;    clk       : in std_logic;    apbi      : in apb_slv_in_type;    apbo      : out apb_slv_out_type;    ahbmi     : in ahb_mst_in_type;    ahbmo     : out ahb_mst_out_type;    ahbsi0    : in ahb_slv_in_type;    ahbso0    : out ahb_slv_out_type;    ahbsi1    : out ahb_slv_in_type;    ahbso1    : in ahb_slv_out_type  );end;architecture rtl of dmactrl isconstant BURST_LENGTH : integer := blength;constant REVISION : integer := 0;constant pconfig : apb_config_type := (  0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_DMACTRL, 0, REVISION, 0),  1 => apb_iobar(paddr, pmask));type state_type is(idle, read1, read2, read3, read4, read5, write1, write2, writeb, write3, write4, turn); type rbuf_type is array (0 to 2) of std_logic_vector(31 downto 0);type dmactrl_reg_type is record  state     : state_type;  addr0     : std_logic_vector(31 downto 2);  addr1     : std_logic_vector(31 downto 2);  hmbsel    : std_logic_vector(0 to NAHBAMR-1);  htrans    : std_logic_vector(1 downto 0);  rbuf      : rbuf_type;  write     : std_logic;  start_req : std_logic;  start     : std_logic;  ready     : std_logic;  err       : std_logic;  first0    : std_logic;  first1    : std_logic;  no_ws     : std_logic; -- no wait states  blimit    : std_logic; -- 1k limit  dmao_start: std_logic;   two_in_buf: std_logic; -- two words in rbuf to be stored  burstl_p  : std_logic_vector(BURST_LENGTH - 1 downto 0); -- pci access counter  burstl_a  : std_logic_vector(BURST_LENGTH - 1 downto 0); -- amba access counter  ahb0_htrans : std_logic_vector(1 downto 0);  ahb0_hready : std_logic;  ahb0_retry  : std_logic;  ahb0_hsel   : std_logic;  start_del   : std_logic;end record;signal r,rin : dmactrl_reg_type;signal dmai : ahb_dma_in_type;signal dmao : ahb_dma_out_type;begin   comb : process(rst,r,dmao,apbi,ahbsi0,ahbso1)   variable v : dmactrl_reg_type;   variable vdmai : ahb_dma_in_type;   variable pdata : std_logic_vector(31 downto 0);   variable slvbusy : ahb_slv_out_type;   variable dma_done, pci_done : std_logic;   variable bufloc : integer range 0 to 2;   begin      slvbusy := ahbso1; v := r;   vdmai.burst := '1'; vdmai.address := r.addr0 & "00";   vdmai.write := not r.write; vdmai.start := '0'; vdmai.size := "10";   vdmai.wdata := r.rbuf(0); pdata := (others => '0');   vdmai.busy := '0'; vdmai.irq := '0';    bufloc := 0;   v.start_del := r.start;   slvbusy.hready := '1'; slvbusy.hindex := hindex; --slvbusy.hresp := "00";    v.ahb0_htrans := ahbsi0.htrans; v.ahb0_retry := '0';   v.ahb0_hsel := ahbsi0.hsel(slvindex); v.ahb0_hready := ahbsi0.hready;   -- AMBA busy response when dma is running    if r.ahb0_retry = '1' then slvbusy.hresp := "10";   else slvbusy.hresp := "00"; end if;   if r.ahb0_htrans = "10" and (r.start = '1') and r.ahb0_hsel = '1' and r.ahb0_hready = '1' then      slvbusy.hready := '0';      slvbusy.hresp := "10";      v.ahb0_retry := '1';   end if;   -- Done signals   if (r.burstl_a(BURST_LENGTH - 1 downto 1) = zero32(BURST_LENGTH - 1 downto 1)) then -- AMBA access done     dma_done := '1'; else dma_done := '0'; end if;      if (r.burstl_p(BURST_LENGTH - 1 downto 1) = zero32(BURST_LENGTH - 1 downto 1)) then -- PCI access done     pci_done := '1'; else pci_done := '0'; end if;   -- APB interface   if (apbi.psel(pindex) and apbi.penable) = '1' then      case apbi.paddr(4 downto 2) is      when "000" =>         if apbi.pwrite = '1' then            v.start_req := apbi.pwdata(0);            v.write := apbi.pwdata(1);            v.ready := r.ready and not apbi.pwdata(2);            v.err := r.err and not apbi.pwdata(3);            v.hmbsel := apbi.pwdata(7 downto 4);         end if;         pdata := zero32(31 downto 8) & r.hmbsel & r.err & r.ready & r.write & r.start_req;      when "001" =>         if apbi.pwrite = '1' then v.addr0 := apbi.pwdata(31 downto 2); end if;         pdata := r.addr0 & "00";      when "010" =>         if apbi.pwrite = '1' then v.addr1 := apbi.pwdata(31 downto 2); end if;         pdata := r.addr1 & "00";      when "011" =>         if apbi.pwrite = '1' then             v.burstl_p := apbi.pwdata(BURST_LENGTH - 1 downto 0);             v.burstl_a := apbi.pwdata(BURST_LENGTH - 1 downto 0);          end if;         pdata := zero32(31 downto BURST_LENGTH) & r.burstl_p;      when others =>      end case;   end if;   -- can't start dma until AMBA slave is idle   if r.start_req = '1' and (ahbsi0.hready = '1' and (ahbsi0.htrans = "00" or ahbsi0.hsel(slvindex) = '0')) then      v.start := '1';   end if;   case r.state is   when idle =>      v.htrans := "00";      v.first0 := '1'; v.first1 := '1';       v.no_ws := '0'; v.dmao_start := '0'; v.blimit := '0';      if r.start = '1' then         if r.write = '0' then v.state := read1;         else v.state := write1; end if;      end if;   when read1 => -- Start PCI read      bufloc := 0;      v.htrans := "10";      if ahbso1.hready = '1' and ahbso1.hresp = HRESP_OKAY then         if r.htrans(1) = '1' then            if pci_done = '1' then               v.htrans := "00";               v.state := read5;            else               v.htrans := "11";               v.state := read2;            end if;         end if;      elsif ahbso1.hready = '0' then         v.htrans := "11";      else         v.htrans := "00";      end if;   when read2 => -- fill rbuf (3 words)      if r.first1 = '1' then bufloc := 1; -- store 3 words      else bufloc := 2; end if;       if ahbso1.hready = '1' and ahbso1.hresp = HRESP_OKAY then         if r.htrans = "11" then            v.first1 := '0';            if pci_done = '1' then               v.htrans := "00";               v.state := read5;            elsif r.first1 = '0' then                v.htrans := "01";               v.state := read3;               v.first0 := '1';            end if;         end if;      end if;   when read3 => -- write to AMBA and read from PCI      vdmai.start := '1';      bufloc := 1;            if (dmao.ready and dmao.start) = '1' then bufloc := 1; v.no_ws := '1'; -- no wait state on AMBA ?      else          bufloc := 2;          if dmao.active = '1' then v.no_ws := '0'; end if;      end if;      if dmao.active = '0' then v.blimit := '1';       else v.blimit := '0'; end if;      if dmao.ready = '1' then         v.first0 := '0'; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -