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

Subversion Repositories wf3d

[/] [wf3d/] [trunk/] [implement/] [rtl/] [axi_cmn/] [fm_dispatch_dma.v] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 specular
//=======================================================================
2
// Project Monophony
3
//   Wire-Frame 3D Graphics Accelerator IP Core
4
//
5
// File:
6
//   fm_dispatch_dma.v
7
//
8
// Abstract:
9
//   DMA controller sequencer
10
//
11
// Author:
12
//   Kenji Ishimaru (info.wf3d@gmail.com)
13
//
14
//======================================================================
15
//
16
// Copyright (c) 2016, Kenji Ishimaru
17
// All rights reserved.
18
//
19
// Redistribution and use in source and binary forms, with or without
20
// modification, are permitted provided that the following conditions are met:
21
//
22
//  -Redistributions of source code must retain the above copyright notice,
23
//   this list of conditions and the following disclaimer.
24
//  -Redistributions in binary form must reproduce the above copyright notice,
25
//   this list of conditions and the following disclaimer in the documentation
26
//   and/or other materials provided with the distribution.
27
//
28
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
35
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
37
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
//
40
// Revision History
41
 
42
module fm_dispatch_dma (
43
    clk_core,
44
    rst_x,
45
    // system port
46
    i_dma_start,
47
    i_dma_mode,
48
    o_dma_end,
49
    i_dma_top_address0,
50
    i_dma_top_address1,
51
    i_dma_top_address2,
52
    i_dma_top_address3,
53
    i_dma_length,
54
    i_dma_be,
55
    i_dma_wd0,
56
    i_dma_wd1,
57
    // memory port
58
    o_req,
59
    o_wr,
60
    o_adrs,
61
    o_len,
62
    i_ack,
63
    o_strw,
64
    o_be,
65
    o_wd,
66
    i_ackw
67
);
68
`include "polyphony_params.v"
69
////////////////////////////
70
// Parameter definition
71
////////////////////////////
72
    parameter P_IDLE         = 3'h0;
73
    parameter P_SETUP        = 3'h1;
74
    parameter P_REQ          = 3'h2;
75
    parameter P_DOUT         = 3'h3;
76
    parameter P_NEXT         = 3'h4;
77
//////////////////////////////////
78
// I/O port definition
79
//////////////////////////////////
80
    input           clk_core;
81
    input           rst_x;
82
    // system port
83
    input           i_dma_start;
84
    input  [3:0]    i_dma_mode;
85
    output          o_dma_end;
86
    input  [19:0]   i_dma_top_address0;  // 32w:bit[29:10]
87
    input  [19:0]   i_dma_top_address1;
88
    input  [19:0]   i_dma_top_address2;
89
    input  [19:0]   i_dma_top_address3;
90
    input  [17:0]   i_dma_length;
91
    input  [3:0]    i_dma_be;
92
    input  [31:0]   i_dma_wd0;
93
    input  [31:0]   i_dma_wd1;
94
    // memory port
95
    output          o_req;
96
    output          o_wr;
97
    output [P_IB_ADDR_WIDTH-1:0] o_adrs;
98
    output [P_IB_LEN_WIDTH-1:0]  o_len;
99
    input           i_ack;
100
    output          o_strw;
101
    output [P_IB_BE_WIDTH-1:0]   o_be;
102
    output [P_IB_DATA_WIDTH-1:0] o_wd;
103
    input           i_ackw;
104
 
105
//////////////////////////////////
106
// reg 
107
//////////////////////////////////
108
    reg    [2:0]   r_state;
109
    reg    [P_IB_ADDR_WIDTH-1:0] r_adrs;
110
    reg    [17:0]  r_length;  // 32bits length
111
    reg    [4:0]   r_len;     // 32bits or 64bits
112
    reg    [4:0]   r_cnt;
113
    reg    [3:0]   r_dma_kind;
114
 
115
//////////////////////////////////
116
// wire 
117
//////////////////////////////////
118
`ifdef PP_BUSWIDTH_64
119
    wire   [5:0]   w_next_len;      // 32bits or 64bits
120
`else
121
    wire   [4:0]   w_next_len;      // 32bits or 64bits
122
`endif
123
    wire   [17:0]  w_remain_length; // 32bits length
124
    wire           w_dma_end;
125
    wire   [19:0]  w_set_address;
126
    wire           w_all_dma_end;
127
    wire           w_sel_wd;
128
    wire   [3:0]   w_next_kind;
129
//////////////////////////////////
130
// assign
131
//////////////////////////////////
132
    assign w_next_len = f_len(r_length);
133
    assign w_remain_length = r_length - {13'b0,w_next_len};
134
    assign w_set_address = f_adrs(r_dma_kind,
135
                                  i_dma_top_address0,
136
                                  i_dma_top_address1,
137
                                  i_dma_top_address2,
138
                                  i_dma_top_address3);
139
    assign w_next_kind = f_kind_update(r_dma_kind);
140
    assign w_dma_end = (r_length == 18'd0);
141
    assign w_all_dma_end = (r_dma_kind == 4'b0);
142
    assign o_dma_end = (r_state == P_SETUP) & w_all_dma_end;
143
 
144
    assign w_sel_wd = f_sel_wd(r_dma_kind);
145
    assign o_req = (r_state == P_REQ);
146
    assign o_wr = 1'b1;
147
    assign o_adrs = r_adrs;
148
    assign o_len = {1'b0,r_len};
149
    assign o_strw = (r_state == P_REQ) | (r_state == P_DOUT);
150
`ifdef PP_BUSWIDTH_64
151
    assign o_be = {i_dma_be,i_dma_be};
152
    assign o_wd = (w_sel_wd) ? {i_dma_wd1,i_dma_wd1} : {i_dma_wd0,i_dma_wd0};
153
`else
154
    assign o_be = i_dma_be;
155
    assign o_wd = (w_sel_wd) ? i_dma_wd1 : i_dma_wd0;
156
`endif
157
 
158
//////////////////////////////////
159
// always
160
//////////////////////////////////
161
 
162
// memory fill/ burst sequence (near interface)
163
always @(posedge clk_core or negedge rst_x) begin
164
    if (~rst_x) begin
165
        r_len <= 5'b0;
166
        r_cnt <= 5'b0;
167
        r_state <= P_IDLE;
168
        r_adrs <= {P_IB_ADDR_WIDTH{1'b0}};
169
        r_length <= 18'd0;
170
        r_dma_kind <= 4'b0;
171
    end else begin
172
        case (r_state)
173
            P_IDLE : begin
174
                if (i_dma_start) begin  // memory fill start (address0)
175
                    r_length <= i_dma_length;
176
                    r_cnt <= 5'b1;
177
                    r_dma_kind <= i_dma_mode;
178
                    r_state <= P_SETUP;
179
                end
180
            end
181
            P_SETUP : begin
182
                // decide burst length
183
`ifdef PP_BUSWIDTH_64
184
                r_adrs[28:9] <= w_set_address;
185
                r_adrs[8:0] <= 9'h0;
186
                r_len <= w_next_len[5:1];
187
`else
188
                r_adrs[29:10] <= w_set_address;
189
                r_adrs[9:0] <= 10'h0;
190
                r_len <= w_next_len;
191
`endif
192
                r_length <= w_remain_length;
193
                if (w_all_dma_end) begin
194
                    r_state <= P_IDLE;
195
                end else begin
196
                    r_state <= P_REQ;
197
                end
198
            end
199
            P_REQ : begin
200
                if (i_ack) begin
201
                    if (r_len == 1) begin  // not burst
202
                        r_state <= P_NEXT;
203
                    end else begin
204
                        r_state <= P_DOUT;
205
                    end
206
                    r_cnt <= r_cnt + 1'b1;
207
                end
208
            end
209
            P_DOUT : begin
210
                if (i_ackw) begin
211
                    r_cnt <= r_cnt + 1'b1;
212
                    if (r_cnt == r_len) begin
213
                        r_state <= P_NEXT;
214
                    end
215
                end
216
            end
217
            P_NEXT : begin
218
                if (w_dma_end) begin
219
                    r_dma_kind <= w_next_kind;
220
                    r_length <= i_dma_length;
221
                    r_cnt <= 5'd1;
222
                    r_state <= P_SETUP;
223
                end else begin
224
                    r_cnt <= 5'd1;
225
                    r_adrs <= r_adrs + r_len;
226
`ifdef PP_BUSWIDTH_64
227
                    r_len <= w_next_len[5:1];
228
`else
229
                    r_len <= w_next_len;
230
`endif
231
                    r_length <= w_remain_length;
232
                    r_state <= P_REQ;
233
                end
234
            end
235
        endcase
236
    end
237
end
238
//////////////////////////////////
239
// function
240
//////////////////////////////////
241
`ifdef PP_BUSWIDTH_64
242
    function [5:0] f_len;    // return per64
243
`else
244
    function [4:0] f_len;    // return  per32
245
`endif
246
        input [17:0] c_len;  // 32-bit length
247
        reg cmp;
248
        begin
249
`ifdef PP_BUSWIDTH_64
250
            cmp = |c_len[17:5];
251
            if (cmp) f_len = 6'h20;  // c_len > 'h20
252
            else f_len = {1'b0,c_len[4:0]};
253
`else
254
            cmp = |c_len[17:4];
255
            if (cmp) f_len = 5'h10;  // c_len > 'h10, 32bits x 16 burst
256
            else f_len = {1'b0,c_len[3:0]};
257
`endif
258
        end
259
    endfunction
260
 
261
    function [19:0] f_adrs;
262
        input [3:0]  kind;
263
        input [19:0] a0;
264
        input [19:0] a1;
265
        input [19:0] a2;
266
        input [19:0] a3;
267
        reg cmp;
268
        begin
269
            if (kind[0])f_adrs = a0;
270
            else if (kind[1])f_adrs = a1;
271
            else if (kind[2])f_adrs = a2;
272
            else f_adrs = a3;
273
        end
274
    endfunction
275
 
276
    function [4:0] f_kind_update;
277
        input [3:0] kind;
278
        reg [3:0] result;
279
        integer i;
280
        begin
281
            if (kind[0]) result = {kind[3:1],1'b0};
282
            else if (kind[1]) result = {kind[3:2],2'b0};
283
            else if (kind[2]) result = {kind[3],3'b0};
284
            else result = 4'b0;
285
            f_kind_update = result;
286
        end
287
    endfunction
288
 
289
    function f_sel_wd;
290
        input [3:0] kind;
291
        reg   result;
292
        integer i;
293
        begin
294
            if (kind[0]) result = 1'b0;
295
            else if (kind[1]) result = 1'b0;
296
            else if (kind[2]) result = 1'b1;
297
            else result = 1'b1;
298
            f_sel_wd = result;
299
        end
300
    endfunction
301
endmodule

powered by: WebSVN 2.1.0

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