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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [misc/] [ahbdma.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
-- GAISLER_LICENSE
2
-----------------------------------------------------------------------------   
3
-- Entity:      dma
4
-- File:        dma.vhd
5
-- Author:      Jiri Gaisler - Gaisler Research
6
-- Description: Simple DMA (needs the AHB master interface)
7
------------------------------------------------------------------------------  
8
 
9
library ieee;
10
use ieee.std_logic_1164.all;
11
library grlib;
12
use grlib.amba.all;
13
use grlib.stdlib.all;
14
use grlib.devices.all;
15
library gaisler;
16
use gaisler.misc.all;
17
 
18
entity ahbdma is
19
   generic (
20
     hindex : integer := 0;
21
     pindex : integer := 0;
22
     paddr  : integer := 0;
23
     pmask  : integer := 16#fff#;
24
     pirq   : integer := 0;
25
     dbuf   : integer := 4);
26
   port (
27
      rst  : in  std_logic;
28
      clk  : in  std_ulogic;
29
      apbi : in  apb_slv_in_type;
30
      apbo : out apb_slv_out_type;
31
      ahbi : in  ahb_mst_in_type;
32
      ahbo : out ahb_mst_out_type
33
      );
34
end;
35
 
36
architecture struct of ahbdma is
37
 
38
constant pconfig : apb_config_type := (
39
 
40
  1 => apb_iobar(paddr, pmask));
41
 
42
type dma_state_type is (readc, writec);
43
subtype word32 is std_logic_vector(31 downto 0);
44
type datavec is array (0 to dbuf-1) of word32;
45
type reg_type is record
46
  srcaddr : std_logic_vector(31 downto 0);
47
  srcinc  : std_logic_vector(1 downto 0);
48
  dstaddr : std_logic_vector(31 downto 0);
49
  dstinc  : std_logic_vector(1 downto 0);
50
  len     : std_logic_vector(15 downto 0);
51
  enable  : std_logic;
52
  write   : std_logic;
53
  inhibit : std_logic;
54
  status  : std_logic_vector(1 downto 0);
55
  dstate  : dma_state_type;
56
  data    : datavec;
57
  cnt     : integer range 0 to dbuf-1;
58
end record;
59
 
60
signal r, rin : reg_type;
61
signal dmai : ahb_dma_in_type;
62
signal dmao : ahb_dma_out_type;
63
 
64
begin
65
 
66
  comb : process(apbi, dmao, rst, r)
67
  variable v       : reg_type;
68
  variable regd    : std_logic_vector(31 downto 0);   -- data from registers
69
  variable start   : std_logic;
70
  variable burst   : std_logic;
71
  variable write   : std_logic;
72
  variable ready   : std_logic;
73
  variable retry   : std_logic;
74
  variable mexc    : std_logic;
75
  variable irq     : std_logic;
76
  variable address : std_logic_vector(31 downto 0);   -- DMA address
77
  variable size    : std_logic_vector( 1 downto 0);   -- DMA transfer size
78
  variable newlen  : std_logic_vector(15 downto 0);
79
  variable oldaddr : std_logic_vector(9 downto 0);
80
  variable newaddr : std_logic_vector(9 downto 0);
81
  variable oldsize : std_logic_vector( 1 downto 0);
82
  variable ainc    : std_logic_vector( 3 downto 0);
83
 
84
  begin
85
 
86
    v := r; regd := (others => '0'); burst := '0'; start := '0';
87
    write := '0'; ready := '0'; mexc := '0';
88
    size := r.srcinc; irq := '0'; v.inhibit := '0';
89
    if r.write = '0' then address := r.srcaddr;
90
    else address := r.dstaddr; end if;
91
    newlen := r.len - 1;
92
 
93
    if (r.cnt < dbuf-1) or (r.len(9 downto 2) = "11111111") then burst := '1';
94
    else burst := '0'; end if;
95
    start := r.enable;
96
    if dmao.active = '1' then
97
      if r.write = '0' then
98
        if dmao.ready = '1' then
99
          v.data(r.cnt) := dmao.rdata;
100
          if r.cnt = dbuf-1 then
101
            v.write := '1'; v.cnt := 0; v.inhibit := '1';
102
            address := r.dstaddr; size := r.dstinc;
103
          else v.cnt := r.cnt + 1; end if;
104
        end if;
105
      else
106
        if r.cnt = dbuf-1 then start := '0'; end if;
107
        if dmao.ready = '1' then
108
          if r.cnt = dbuf-1 then v.cnt := 0;
109
            v.write := '0'; v.len := newlen; v.enable := start; irq := start;
110
          else v.cnt := r.cnt + 1; end if;
111
        end if;
112
      end if;
113
    end if;
114
 
115
    if r.write = '0' then oldaddr := r.srcaddr(9 downto 0); oldsize := r.srcinc;
116
    else oldaddr := r.dstaddr(9 downto 0); oldsize := r.dstinc; end if;
117
 
118
    ainc := decode(oldsize);
119
 
120
    newaddr := oldaddr + ainc(3 downto 0);
121
 
122
    if (dmao.active and dmao.ready) = '1' then
123
      if r.write = '0' then v.srcaddr(9 downto 0) := newaddr;
124
      else v.dstaddr(9 downto 0) := newaddr; end if;
125
    end if;
126
 
127
-- read DMA registers
128
 
129
    case apbi.paddr(3 downto 2) is
130
    when "00" => regd := r.srcaddr;
131
    when "01" => regd := r.dstaddr;
132
    when "10" => regd(20 downto 0) := r.enable & r.srcinc & r.dstinc & r.len;
133
    when others => null;
134
    end case;
135
 
136
-- write DMA registers
137
 
138
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
139
      case apbi.paddr(3 downto 2) is
140
      when "00" =>
141
        v.srcaddr := apbi.pwdata;
142
      when "01" =>
143
        v.dstaddr := apbi.pwdata;
144
      when "10" =>
145
        v.len := apbi.pwdata(15 downto 0);
146
        v.srcinc := apbi.pwdata(17 downto 16);
147
        v.dstinc := apbi.pwdata(19 downto 18);
148
        v.enable := apbi.pwdata(20);
149
      when others => null;
150
      end case;
151
    end if;
152
 
153
    if rst = '0' then
154
      v.dstate := readc; v.enable := '0'; v.write := '0';
155
      v.cnt  := 0;
156
    end if;
157
 
158
    rin <= v;
159
    apbo.prdata  <= regd;
160
    dmai.address <= address;
161
    dmai.wdata   <= r.data(r.cnt);
162
    dmai.start   <= start and not v.inhibit;
163
    dmai.burst   <= burst;
164
    dmai.write   <= v.write;
165
    dmai.size    <= size;
166
    apbo.pirq    <= (others =>'0');
167
    apbo.pindex  <= pindex;
168
    apbo.pconfig <= pconfig;
169
 
170
  end process;
171
 
172
 
173
  ahbif : ahbmst generic map (hindex => hindex, devid => 16#26#, incaddr => 1)
174
        port map (rst, clk, dmai, dmao, ahbi, ahbo);
175
 
176
 
177
  regs : process(clk)
178
  begin if rising_edge(clk) then r <= rin; end if; end process;
179
 
180
-- pragma translate_off
181
    bootmsg : report_version
182
    generic map ("ahbdma" & tost(pindex) &
183
        ": AHB DMA Unit rev " & tost(0) & ", irq " & tost(pirq));
184
-- pragma translate_on
185
 
186
end;

powered by: WebSVN 2.1.0

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