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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [sparc/] [dma.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
 
2
 
3
 
4
 
5
----------------------------------------------------------------------------
6
--  This file is a part of the LEON VHDL model
7
--  Copyright (C) 1999  European Space Agency (ESA)
8
--
9
--  This library is free software; you can redistribute it and/or
10
--  modify it under the terms of the GNU Lesser General Public
11
--  License as published by the Free Software Foundation; either
12
--  version 2 of the License, or (at your option) any later version.
13
--
14
--  See the file COPYING.LGPL for the full details of the license.
15
 
16
 
17
-----------------------------------------------------------------------------   
18
-- Entity:      dma
19
-- File:        dma.vhd
20
-- Author:      Jiri Gaisler - Gaisler Research
21
-- Description: Simple DMA (needs the AHB master interface)
22
------------------------------------------------------------------------------  
23
 
24
library IEEE;
25
use IEEE.std_logic_1164.all;
26
use IEEE.std_logic_unsigned."-";
27
use IEEE.std_logic_unsigned."+";
28
use IEEE.std_logic_arith.conv_unsigned;
29
use work.macro.all;
30
use work.amba.all;
31
use work.ambacomp.all;
32
use work.leon_iface.all;
33
 
34
 
35
entity dma is
36
   port (
37
      rst  : in  std_logic;
38
      clk  : in  clk_type;
39
      dirq  : out std_logic;
40
      apbi   : in  apb_slv_in_type;
41
      apbo   : out apb_slv_out_type;
42
      ahbi : in  ahb_mst_in_type;
43
      ahbo : out ahb_mst_out_type
44
      );
45
end;
46
 
47
architecture struct of dma is
48
type dma_state_type is (readc, writec);
49
type reg_type is record
50
  srcaddr : std_logic_vector(31 downto 0);
51
  srcinc  : std_logic_vector(1 downto 0);
52
  dstaddr : std_logic_vector(31 downto 0);
53
  dstinc  : std_logic_vector(1 downto 0);
54
  len     : std_logic_vector(7 downto 0);
55
  enable  : std_logic;
56
  write   : std_logic;
57
  status  : std_logic_vector(1 downto 0);
58
  dstate  : dma_state_type;
59
  data    : std_logic_vector(31 downto 0);
60
end record;
61
 
62
signal r, rin : reg_type;
63
signal dmai : ahb_dma_in_type;
64
signal dmao : ahb_dma_out_type;
65
 
66
begin
67
 
68
  comb : process(apbi, dmao, rst, r)
69
  variable v       : reg_type;
70
  variable regd    : std_logic_vector(31 downto 0);   -- data from registers
71
  variable start   : std_logic;
72
  variable burst   : std_logic;
73
  variable write   : std_logic;
74
  variable ready   : std_logic;
75
  variable retry   : std_logic;
76
  variable mexc    : std_logic;
77
  variable irq     : std_logic;
78
  variable address : std_logic_vector(31 downto 0);   -- DMA address
79
  variable size    : std_logic_vector( 1 downto 0);   -- DMA transfer size
80
  variable newlen  : std_logic_vector(7 downto 0);
81
  variable oldaddr : std_logic_vector(9 downto 0);
82
  variable newaddr : std_logic_vector(9 downto 0);
83
  variable oldsize : std_logic_vector( 1 downto 0);
84
  variable ainc    : std_logic_vector( 3 downto 0);
85
 
86
  begin
87
 
88
    v := r; regd := (others => '0'); burst := '0'; start := '0';
89
    write := '0'; ready := '0'; mexc := '0'; address := r.srcaddr;
90
    size := r.srcinc; irq := '0';
91
 
92
-- pragma translate_off
93
    if not is_x(r.len) then
94
-- pragma translate_on
95
      newlen := r.len - 1;
96
-- pragma translate_off
97
   end if;
98
-- pragma translate_on
99
 
100
    write := r.write; start := r.enable;
101
    if dmao.active = '1' then
102
      if r.write = '0' then
103
        write := '1'; address := r.dstaddr; size := r.dstinc;
104
        if dmao.ready = '1' then
105
          v.write := '1'; v.data := dmao.rdata;
106
        end if;
107
      else
108
        if (r.len(7) xor newlen(7)) = '1' then start := '0'; end if;
109
        write := '0';
110
        if dmao.ready = '1' then
111
          v.write := '0'; v.len := newlen; v.enable := start; irq := start;
112
        end if;
113
      end if;
114
    end if;
115
 
116
    if r.write = '0' then oldaddr := r.srcaddr(9 downto 0); oldsize := r.srcinc;
117
    else oldaddr := r.dstaddr(9 downto 0); oldsize := r.dstinc; end if;
118
 
119
    ainc := decode(oldsize);
120
 
121
-- pragma translate_off
122
    if not is_x(oldaddr & ainc) then
123
-- pragma translate_on
124
      newaddr := oldaddr + ainc(3 downto 1);
125
-- pragma translate_off
126
   end if;
127
-- pragma translate_on
128
 
129
    if (dmao.active and dmao.ready) = '1' then
130
      if r.write = '0' then v.srcaddr(9 downto 0) := newaddr;
131
      else v.dstaddr(9 downto 0) := newaddr; end if;
132
    end if;
133
 
134
-- read DMA registers
135
 
136
    case apbi.paddr(3 downto 2) is
137
    when "00" => regd := r.srcaddr;
138
    when "01" => regd := r.dstaddr;
139
    when "10" => regd(12 downto 0) := r.enable & r.srcinc & r.dstinc & r.len;
140
    when others => null;
141
    end case;
142
 
143
-- write DMA registers
144
 
145
    if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then
146
      case apbi.paddr(3 downto 2) is
147
      when "00" =>
148
        v.srcaddr := apbi.pwdata;
149
      when "01" =>
150
        v.dstaddr := apbi.pwdata;
151
      when "10" =>
152
        v.len := apbi.pwdata(7 downto 0);
153
        v.srcinc := apbi.pwdata(9 downto 8);
154
        v.dstinc := apbi.pwdata(11 downto 10);
155
        v.enable := apbi.pwdata(12);
156
      when others => null;
157
      end case;
158
    end if;
159
 
160
    if rst = '0' then
161
      v.dstate := readc; v.enable := '0'; v.write := '0';
162
    end if;
163
 
164
    rin <= v;
165
    apbo.prdata  <= regd;
166
    dmai.address <= address;
167
    dmai.wdata   <= r.data;
168
    dmai.start   <= start;
169
    dmai.burst   <= '0';
170
    dmai.write   <= write;
171
    dmai.size    <= size;
172
    dirq         <= irq;
173
 
174
  end process;
175
 
176
  ahbif : ahbmst generic map (1) port map (rst, clk, dmai, dmao, ahbi, ahbo);
177
 
178
 
179
  regs : process(clk)
180
  begin if rising_edge(clk) then r <= rin; end if; end process;
181
 
182
end;

powered by: WebSVN 2.1.0

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