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

Subversion Repositories pss

[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [zpu_uc/] [motherblock/] [pss_dma.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 AlexAntono
/*
2
 PSS
3
 
4
 Copyright (c) 2016 Alexander Antonov <153287@niuitmo.ru>
5
 All rights reserved.
6
 
7
 Version 0.9
8
 
9
 The FreeBSD license
10
 
11
 Redistribution and use in source and binary forms, with or without
12
 modification, are permitted provided that the following conditions
13
 are met:
14
 
15
 1. Redistributions of source code must retain the above copyright
16
    notice, this list of conditions and the following disclaimer.
17
 2. Redistributions in binary form must reproduce the above
18
    copyright notice, this list of conditions and the following
19
    disclaimer in the documentation and/or other materials
20
    provided with the distribution.
21
 
22
 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
23
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 PSS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
 
36
 
37
module PSS_DMA
38
(
39
        input clk_i, rst_i,
40
 
41
        input xport_busy_i,
42
        output xport_busy_o,
43
 
44
        output reg dma_int_o,
45
 
46
        input dma_req_i,
47
        input dma_cmd_i,
48
        input dma_autoinc_i,
49
        input [31:0] dma_size_bi,
50
        input [31:0] dma_sourceaddr_bi,
51
        input [31:0] dma_destaddr_bi,
52
 
53
        // RAM 1 interface
54
        output reg [31:0] ram_addr_bo,
55
        output reg ram_we_o,
56
        output reg [31:0] ram_wdata_bo,
57
        input [31:0] ram_rdata_bi,
58
 
59
        // Expansion bus //
60
        output reg xport_req_o,
61
        input  xport_ack_i,
62
        input  xport_err_i,
63
        output reg xport_we_o,
64
        output reg [31:0] xport_addr_bo,
65
        output reg [31:0] xport_wdata_bo,
66
        input xport_resp_i,
67
        input [31:0] xport_rdata_bi
68
);
69
 
70
localparam DMA_IDLE = 3'h0;
71
localparam DMA_WAIT = 3'h1;
72
localparam DMA_PRESTART = 3'h2;
73
localparam DMA_WORK = 3'h3;
74
localparam DMA_LOAD = 3'h4;
75
localparam DMA_STORE = 3'h5;
76
 
77
reg [2:0] DMA_state;
78
 
79
reg [31:0] dma_sourceaddr;
80
reg [31:0] dma_destaddr;
81
reg [31:0] dma_size, dma_size_aux;
82
 
83
assign xport_busy_o = ((DMA_state == DMA_IDLE) || (DMA_state == DMA_WAIT)) ? 1'b0 : 1'b1;
84
 
85
// DMA data logic
86
reg [31:0] ram1_addr, ram1_addr_shadow;
87
 
88
always @*
89
        begin
90
        if (DMA_state != DMA_LOAD)
91
                ram_addr_bo = ram1_addr;
92
        else if (xport_ack_i == 1'b1)
93
                ram_addr_bo = ram1_addr;
94
        else
95
                ram_addr_bo = ram1_addr_shadow;
96
        end
97
 
98
always @(posedge clk_i)
99
        begin
100
        if (rst_i)
101
                ram1_addr_shadow <= 32'h0;
102
        else if (xport_ack_i == 1'b1)
103
                ram1_addr_shadow <= ram1_addr;
104
        end
105
 
106
always @*
107
        begin
108
 
109
        xport_req_o = 1'b0;
110
        xport_we_o = 1'b0;
111
        xport_addr_bo = 32'hx;
112
        xport_wdata_bo = 32'hx;
113
 
114
        ram1_addr = dma_sourceaddr;
115
        ram_we_o = 1'b0;
116
        ram_wdata_bo = 32'hx;
117
 
118
        if (DMA_state == DMA_LOAD)
119
                begin
120
 
121
                if (dma_size != 32'h0)
122
                        begin
123
                        xport_req_o = 1'b1;
124
                        xport_we_o = 1'b0;
125
                        xport_addr_bo = dma_sourceaddr;
126
                        xport_wdata_bo = 32'hx;
127
                        end
128
 
129
                if (dma_size_aux != 32'h0)
130
                        begin
131
                        ram1_addr = dma_destaddr;
132
                        ram_we_o = xport_resp_i;
133
                        ram_wdata_bo = xport_rdata_bi;
134
                        end
135
 
136
                end
137
 
138
        else if (DMA_state == DMA_STORE)
139
                begin
140
 
141
                if (dma_size != 32'h0)
142
                        begin
143
                        xport_req_o = 1'b1;
144
                        xport_we_o = 1'b1;
145
                        xport_addr_bo = dma_destaddr;
146
                        xport_wdata_bo = ram_rdata_bi;
147
                        end
148
 
149
                end
150
 
151
        end
152
 
153
// DMA control logic
154
always @(posedge clk_i)
155
        begin
156
        if (rst_i)
157
                begin
158
 
159
                DMA_state <= DMA_IDLE;
160
 
161
                dma_sourceaddr <= 32'h0;
162
                dma_destaddr <= 32'h0;
163
                dma_size <= 32'h0;
164
 
165
                dma_int_o <= 1'b0;
166
 
167
                end
168
        else
169
                begin
170
 
171
                dma_int_o <= 1'b0;
172
 
173
                case (DMA_state)
174
 
175
                        DMA_IDLE:
176
                                begin
177
                                if (dma_req_i)
178
                                        begin
179
                                        dma_size <= dma_size_bi;
180
                                        dma_size_aux <= dma_size_bi;
181
                                        dma_sourceaddr <= dma_sourceaddr_bi;
182
                                        dma_destaddr <= dma_destaddr_bi;
183
 
184
                                        DMA_state <= DMA_WAIT;
185
                                        end
186
                                end
187
 
188
                        DMA_WAIT:
189
                                begin
190
                                if (!xport_busy_i)      // no pending requests
191
                                        if (dma_cmd_i)
192
                                                begin
193
                                                dma_sourceaddr <= dma_sourceaddr + 32'h4;
194
                                                DMA_state <= DMA_STORE;
195
                                                end
196
                                        else
197
                                                DMA_state <= DMA_LOAD;
198
                                end
199
 
200
                        DMA_STORE:
201
                                begin
202
                                if (xport_ack_i == 1'b1)
203
                                        if (dma_size == 32'h4)
204
                                                begin
205
                                                DMA_state <= DMA_IDLE;
206
                                                dma_int_o <= 1'b1;
207
                                                end
208
                                        else
209
                                                begin
210
                                                dma_size <= dma_size - 32'h4;
211
                                                dma_sourceaddr <= dma_sourceaddr + 32'h4;
212
                                                if (dma_autoinc_i == 1'b1) dma_destaddr <= dma_destaddr + 32'h4;
213
                                                end
214
                                end
215
 
216
                        DMA_LOAD:
217
                                begin
218
 
219
                                if ( (xport_ack_i == 1'b1) && (dma_size != 32'h0) )
220
                                        begin
221
                                        if (dma_autoinc_i == 1'b1) dma_sourceaddr <= dma_sourceaddr + 32'h4;
222
                                        dma_size <= dma_size - 32'h4;
223
                                        end
224
 
225
                                if ( (xport_resp_i == 1'b1) && (dma_size_aux != 32'h0) )
226
                                        begin
227
                                        dma_destaddr <= dma_destaddr + 32'h4;
228
                                        dma_size_aux <= dma_size_aux - 32'h4;
229
                                        end
230
 
231
                                if ( (dma_size == 32'h0) && (dma_size_aux == 32'h0) )
232
                                        begin
233
                                        DMA_state <= DMA_IDLE;
234
                                        dma_int_o <= 1'b1;
235
                                        end
236
 
237
                                end
238
 
239
                        default:
240
                                DMA_state <= DMA_IDLE;
241
 
242
                endcase
243
                end
244
        end
245
 
246
endmodule

powered by: WebSVN 2.1.0

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