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

Subversion Repositories wb_dma

[/] [wb_dma/] [trunk/] [rtl/] [verilog/] [wb_dma_ch_rf.v] - Blame information for rev 8

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

Line No. Rev Author Line
1 5 rudi
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  WISHBONE DMA One Channel Register File                     ////
4
////                                                             ////
5
////                                                             ////
6
////  Author: Rudolf Usselmann                                   ////
7
////          rudi@asics.ws                                      ////
8
////                                                             ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/cores/wb_dma/    ////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2001 Rudolf Usselmann                         ////
15
////                    rudi@asics.ws                            ////
16
////                                                             ////
17
//// This source file may be used and distributed without        ////
18
//// restriction provided that this copyright statement is not   ////
19
//// removed from the file and that any derivative work contains ////
20
//// the original copyright notice and the associated disclaimer.////
21
////                                                             ////
22
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
23
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
24
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
25
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
26
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
27
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
28
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
29
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
30
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
31
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
32
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
33
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
34
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
35
////                                                             ////
36
/////////////////////////////////////////////////////////////////////
37
 
38
//  CVS Log
39
//
40 8 rudi
//  $Id: wb_dma_ch_rf.v,v 1.2 2001-08-15 05:40:30 rudi Exp $
41 5 rudi
//
42 8 rudi
//  $Date: 2001-08-15 05:40:30 $
43
//  $Revision: 1.2 $
44 5 rudi
//  $Author: rudi $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               $Log: not supported by cvs2svn $
50 8 rudi
//               Revision 1.1  2001/07/29 08:57:02  rudi
51
//
52
//
53
//               1) Changed Directory Structure
54
//               2) Added restart signal (REST)
55
//
56 5 rudi
//               Revision 1.3  2001/06/14 08:50:01  rudi
57
//
58
//               Changed Module Name to match file name.
59
//
60
//               Revision 1.2  2001/06/13 02:26:48  rudi
61
//
62
//
63
//               Small changes after running lint.
64
//
65
//               Revision 1.1  2001/06/05 10:25:27  rudi
66
//
67
//
68
//               Initial checkin of register file for one channel.
69
//
70
//
71
//
72
//
73
 
74
`include "wb_dma_defines.v"
75
 
76
module wb_dma_ch_rf(    clk, rst,
77
                        pointer, pointer_s, ch_csr, ch_txsz, ch_adr0, ch_adr1,
78
                        ch_am0, ch_am1, sw_pointer, ch_stop, ch_dis, int,
79
 
80
                        wb_rf_din, wb_rf_adr, wb_rf_we, wb_rf_re,
81
 
82
                        // DMA Registers Write Back Channel Select
83
                        ch_sel, ndnr,
84
 
85
                        // DMA Engine Status
86
                        dma_busy, dma_err, dma_done, dma_done_all,
87
 
88
                        // DMA Engine Reg File Update ctrl signals
89
                        de_csr, de_txsz, de_adr0, de_adr1,
90
                        de_csr_we, de_txsz_we, de_adr0_we, de_adr1_we,
91
                        de_fetch_descr, dma_rest,
92
                        ptr_set
93
 
94
                );
95
 
96
parameter       [4:0]    CH_NO    = 5'h0;  // This Instances Channel ID
97
parameter       [0:0]     HAVE_ARS = 1'b1;  // 1=this Instance Supports ARS
98
parameter       [0:0]     HAVE_ED  = 1'b1;  // 1=this Instance Supports External Descriptors
99
parameter       [0:0]     HAVE_CBUF= 1'b1;  // 1=this Instance Supports Cyclic Buffers
100
 
101
input           clk, rst;
102
 
103
output  [31:0]   pointer;
104
output  [31:0]   pointer_s;
105
output  [31:0]   ch_csr;
106
output  [31:0]   ch_txsz;
107
output  [31:0]   ch_adr0;
108
output  [31:0]   ch_adr1;
109
output  [31:0]   ch_am0;
110
output  [31:0]   ch_am1;
111
output  [31:0]   sw_pointer;
112
output          ch_stop;
113
output          ch_dis;
114
output          int;
115
 
116
input   [31:0]   wb_rf_din;
117
input   [7:0]    wb_rf_adr;
118
input           wb_rf_we;
119
input           wb_rf_re;
120
 
121
input   [4:0]    ch_sel;
122
input           ndnr;
123
 
124
// DMA Engine Status
125
input           dma_busy, dma_err, dma_done, dma_done_all;
126
 
127
// DMA Engine Reg File Update ctrl signals
128
input   [31:0]   de_csr;
129
input   [11:0]   de_txsz;
130
input   [31:0]   de_adr0;
131
input   [31:0]   de_adr1;
132
input           de_csr_we, de_txsz_we, de_adr0_we, de_adr1_we, ptr_set;
133
input           de_fetch_descr;
134
input           dma_rest;
135
 
136
////////////////////////////////////////////////////////////////////
137
//
138
// Local Wires and Registers
139
//
140
 
141
wire    [31:0]   pointer;
142
reg     [27:0]   pointer_r;
143
reg     [27:0]   pointer_sr;
144
reg             ptr_valid;
145
reg             ch_eol;
146
 
147
wire    [31:0]   ch_csr, ch_txsz;
148
 
149
reg     [8:0]    ch_csr_r;
150
reg     [2:0]    ch_csr_r2;
151
reg     [2:0]    ch_csr_r3;
152
reg     [2:0]    int_src_r;
153
reg             ch_err_r;
154
reg             ch_stop;
155
reg             ch_busy;
156
reg             ch_done;
157
reg             ch_err;
158
reg             rest_en;
159
 
160
reg     [10:0]   ch_chk_sz_r;
161
reg     [11:0]   ch_tot_sz_r;
162
reg     [22:0]   ch_txsz_s;
163
reg             ch_sz_inf;
164
 
165
wire    [31:0]   ch_adr0, ch_adr1;
166
reg     [29:0]   ch_adr0_r, ch_adr1_r;
167
wire    [31:0]   ch_am0, ch_am1;
168
reg     [27:0]   ch_am0_r, ch_am1_r;
169
 
170
reg     [29:0]   ch_adr0_s, ch_adr1_s;
171
 
172
reg     [29:0]   sw_pointer_r;
173
wire            sw_pointer_we;
174
wire    [28:0]   cmp_adr;
175
reg             ch_dis;
176
wire            ch_enable;
177
 
178
wire            pointer_we;
179
wire            ch_csr_we, ch_csr_re, ch_txsz_we, ch_adr0_we, ch_adr1_we;
180
wire            ch_am0_we, ch_am1_we;
181
reg             ch_rl;
182
wire            ch_done_we;
183
wire            ch_err_we;
184
wire            chunk_done_we;
185
 
186
wire            ch_csr_dewe, ch_txsz_dewe, ch_adr0_dewe, ch_adr1_dewe;
187
 
188
wire            this_ptr_set;
189
wire            ptr_inv;
190
 
191
////////////////////////////////////////////////////////////////////
192
//
193
// Aliases
194
//
195
 
196
assign ch_adr0          = {ch_adr0_r, 2'h0};
197
assign ch_adr1          = {ch_adr1_r, 2'h0};
198
assign ch_am0           = {ch_am0_r, 4'h0};
199
assign ch_am1           = {ch_am1_r, 4'h0};
200
assign sw_pointer       = {sw_pointer_r,2'h0};
201
 
202
assign pointer          = {pointer_r, 3'h0, ptr_valid};
203
assign pointer_s        = {pointer_sr, 4'h0};
204
assign ch_csr           = {9'h0, int_src_r, ch_csr_r3, rest_en, ch_csr_r2,
205
                                ch_err, ch_done, ch_busy, 1'b0, ch_csr_r[8:1], ch_enable};
206
assign ch_txsz          = {5'h0, ch_chk_sz_r, ch_sz_inf, 3'h0, ch_tot_sz_r};
207
 
208 8 rudi
assign ch_enable        = ch_csr_r[`WDMA_CH_EN] & (HAVE_CBUF ? !ch_dis : 1'b1);
209 5 rudi
 
210
////////////////////////////////////////////////////////////////////
211
//
212
// CH0 control signals
213
//
214
 
215
parameter       [4:0]    CH_ADR = CH_NO + 5'h1;
216
 
217
assign ch_csr_we        = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h0);
218
assign ch_csr_re        = wb_rf_re & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h0);
219
assign ch_txsz_we       = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h1);
220
assign ch_adr0_we       = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h2);
221
assign ch_am0_we        = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h3);
222
assign ch_adr1_we       = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h4);
223
assign ch_am1_we        = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h5);
224
assign pointer_we       = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h6);
225
assign sw_pointer_we    = wb_rf_we & (wb_rf_adr[7:3] == CH_ADR) & (wb_rf_adr[2:0] == 3'h7);
226
 
227
assign ch_done_we       = (((ch_sel==CH_NO) & dma_done_all) | ndnr) &
228 8 rudi
                          (ch_csr[`WDMA_USE_ED] ? ch_eol : !ch_csr[`WDMA_ARS]);
229 5 rudi
assign chunk_done_we    = (ch_sel==CH_NO) & dma_done;
230
assign ch_err_we        = (ch_sel==CH_NO) & dma_err;
231
assign ch_csr_dewe      = de_csr_we & (ch_sel==CH_NO);
232
assign ch_txsz_dewe     = de_txsz_we & (ch_sel==CH_NO);
233
assign ch_adr0_dewe     = de_adr0_we & (ch_sel==CH_NO);
234
assign ch_adr1_dewe     = de_adr1_we & (ch_sel==CH_NO);
235
 
236
assign ptr_inv          = ((ch_sel==CH_NO) & dma_done_all) | ndnr;
237
assign this_ptr_set     = ptr_set & (ch_sel==CH_NO);
238
 
239
always @(posedge clk)
240
        ch_rl <= #1     HAVE_ARS & (
241
                        (rest_en & dma_rest) |
242 8 rudi
                        ((ch_sel==CH_NO) & dma_done_all & ch_csr[`WDMA_ARS] & !ch_csr[`WDMA_USE_ED])
243 5 rudi
                        );
244
 
245
// ---------------------------------------------------
246
// Pointers
247
 
248
always @(posedge clk or negedge rst)
249
        if(!rst)                        ptr_valid <= #1 1'b0;
250
        else
251
        if(HAVE_ED)
252
           begin
253
                if( this_ptr_set | (rest_en & dma_rest) )
254
                                        ptr_valid <= #1 1'b1;
255
                else
256
                if(ptr_inv)             ptr_valid <= #1 1'b0;
257
           end
258
        else                            ptr_valid <= #1 1'b0;
259
 
260
always @(posedge clk or negedge rst)
261
        if(!rst)                        ch_eol <= #1 1'b0;
262
        else
263
        if(HAVE_ED)
264
           begin
265 8 rudi
                if(ch_csr_dewe)         ch_eol <= #1 de_csr[`WDMA_ED_EOL];
266 5 rudi
                else
267
                if(ch_done_we)          ch_eol <= #1 1'b0;
268
           end
269
        else                            ch_eol <= #1 1'b0;
270
 
271
always @(posedge clk)
272
        if(HAVE_ED)
273
           begin
274
                if(pointer_we)          pointer_r <= #1 wb_rf_din[31:4];
275
                else
276
                if(this_ptr_set)        pointer_r <= #1 de_csr[31:4];
277
           end
278
        else                            pointer_r <= #1 1'b0;
279
 
280
always @(posedge clk)
281
        if(HAVE_ED)
282
           begin
283
                if(this_ptr_set)        pointer_sr <= #1 pointer_r;
284
           end
285
        else                            pointer_sr <= #1 1'b0;
286
 
287
// ---------------------------------------------------
288
// CSR
289
 
290
always @(posedge clk or negedge rst)
291
        if(!rst)                ch_csr_r <= #1 1'b0;
292
        else
293
        if(ch_csr_we)           ch_csr_r <= #1 wb_rf_din[8:0];
294
        else
295
           begin
296 8 rudi
                if(ch_done_we)  ch_csr_r[`WDMA_CH_EN] <= #1 1'b0;
297 5 rudi
                if(ch_csr_dewe) ch_csr_r[4:1] <= #1 de_csr[19:16];
298
           end
299
 
300
// done bit
301
always @(posedge clk or negedge rst)
302
        if(!rst)                ch_done <= #1 1'b0;
303
        else
304 8 rudi
        if(ch_csr_we)           ch_done <= #1 !wb_rf_din[`WDMA_CH_EN];
305 5 rudi
        else
306
        if(ch_done_we)          ch_done <= #1 1'b1;
307
 
308
// busy bit
309
always @(posedge clk)
310
        ch_busy <= #1 (ch_sel==CH_NO) & dma_busy;
311
 
312
// stop bit
313
always @(posedge clk)
314 8 rudi
        ch_stop <= #1 ch_csr_we & wb_rf_din[`WDMA_STOP];
315 5 rudi
 
316
// error bit
317
always @(posedge clk or negedge rst)
318
        if(!rst)                ch_err <= #1 1'b0;
319
        else
320
        if(ch_err_we)           ch_err <= #1 1'b1;
321
        else
322
        if(ch_csr_re)           ch_err <= #1 1'b0;
323
 
324
// Priority Bits
325
always @(posedge clk or negedge rst)
326
        if(!rst)                ch_csr_r2 <= #1 3'h0;
327
        else
328
        if(ch_csr_we)           ch_csr_r2 <= #1 wb_rf_din[15:13];
329
 
330
// Restart Enable Bit (REST)
331
always @(posedge clk or negedge rst)
332
        if(!rst)                rest_en <= #1 1'b0;
333
        else
334
        if(ch_csr_we)           rest_en <= #1 wb_rf_din[16];
335
 
336
// INT Mask
337
always @(posedge clk or negedge rst)
338
        if(!rst)                ch_csr_r3 <= #1 3'h0;
339
        else
340
        if(ch_csr_we)           ch_csr_r3 <= #1 wb_rf_din[19:17];
341
 
342
// INT Source
343
always @(posedge clk or negedge rst)
344
        if(!rst)                int_src_r[2] <= #1 1'b0;
345
        else
346
        if(chunk_done_we)       int_src_r[2] <= #1 1'b1;
347
        else
348
        if(ch_csr_re)           int_src_r[2] <= #1 1'b0;
349
 
350
always @(posedge clk or negedge rst)
351
        if(!rst)                int_src_r[1] <= #1 1'b0;
352
        else
353
        if(ch_done_we)          int_src_r[1] <= #1 1'b1;
354
        else
355
        if(ch_csr_re)           int_src_r[1] <= #1 1'b0;
356
 
357
always @(posedge clk or negedge rst)
358
        if(!rst)                int_src_r[0] <= #1 1'b0;
359
        else
360
        if(ch_err_we)           int_src_r[0] <= #1 1'b1;
361
        else
362
        if(ch_csr_re)           int_src_r[0] <= #1 1'b0;
363
 
364
// Interrupt Output
365
assign int = |(int_src_r & ch_csr_r3);
366
 
367
// ---------------------------------------------------
368
// TXZS
369
always @(posedge clk)
370
        if(ch_txsz_we)
371
                {ch_chk_sz_r, ch_tot_sz_r} <= #1 {wb_rf_din[26:16], wb_rf_din[11:0]};
372
        else
373
        if(ch_txsz_dewe)
374
                ch_tot_sz_r <= #1 de_txsz;
375
        else
376
        if(ch_rl)
377
                {ch_chk_sz_r, ch_tot_sz_r} <= #1 ch_txsz_s;
378
 
379
// txsz shadow register
380
always @(posedge clk)
381
        if(HAVE_ARS)
382
           begin
383
 
384
                if(ch_txsz_we)  ch_txsz_s <= #1 {wb_rf_din[26:16], wb_rf_din[11:0]};
385
                else
386
                if(rest_en & ch_txsz_dewe & de_fetch_descr)
387
                                ch_txsz_s[11:0] <= #1 de_txsz[11:0];
388
           end
389
 
390
// Infinite Size indicator
391
always @(posedge clk)
392
        if(ch_txsz_we)          ch_sz_inf <= #1 wb_rf_din[15];
393
 
394
// ---------------------------------------------------
395
// ADR0
396
always @(posedge clk)
397
        if(ch_adr0_we)          ch_adr0_r <= #1 wb_rf_din[31:2];
398
        else
399
        if(ch_adr0_dewe)        ch_adr0_r <= #1 de_adr0[31:2];
400
        else
401
        if(ch_rl)               ch_adr0_r <= #1 ch_adr0_s;
402
 
403
// Adr0 shadow register
404
always @(posedge clk)
405
        if(HAVE_ARS)
406
           begin
407
                if(ch_adr0_we)  ch_adr0_s <= #1 wb_rf_din[31:2];
408
                else
409
                if(rest_en & ch_adr0_dewe & de_fetch_descr)
410
                                ch_adr0_s <= #1 de_adr0[31:2];
411
           end
412
 
413
// ---------------------------------------------------
414
// AM0
415
always @(posedge clk or negedge rst)
416
        if(!rst)                        ch_am0_r <= #1 28'hfffffff;
417
        else
418
        if(ch_am0_we & HAVE_CBUF)       ch_am0_r <= #1 wb_rf_din[31:4];
419
 
420
// ---------------------------------------------------
421
// ADR1
422
always @(posedge clk)
423
        if(ch_adr1_we)          ch_adr1_r <= #1 wb_rf_din[31:2];
424
        else
425
        if(ch_adr1_dewe)        ch_adr1_r <= #1 de_adr1[31:2];
426
        else
427
        if(ch_rl)               ch_adr1_r <= #1 ch_adr1_s;
428
 
429
// Adr1 shadow register
430
always @(posedge clk)
431
        if(HAVE_ARS)
432
           begin
433
                if(ch_adr1_we)  ch_adr1_s <= #1 wb_rf_din[31:2];
434
                else
435
                if(rest_en & ch_adr1_dewe & de_fetch_descr)
436
                                ch_adr1_s <= #1 de_adr1[31:2];
437
           end
438
 
439
// ---------------------------------------------------
440
// AM1
441
always @(posedge clk or negedge rst)
442
        if(!rst)                        ch_am1_r <= #1 28'hfffffff;
443
        else
444
        if(ch_am1_we & HAVE_CBUF)       ch_am1_r <= #1 wb_rf_din[31:4];
445
 
446
// ---------------------------------------------------
447
// Software Pointer
448
always @(posedge clk or negedge rst)
449
        if(!rst)                        sw_pointer_r <= #1 28'h0;
450
        else
451
        if(sw_pointer_we & HAVE_CBUF)   sw_pointer_r <= #1 wb_rf_din[31:4];
452
 
453
// ---------------------------------------------------
454
// Software Pointer Match logic
455
 
456
assign cmp_adr = ch_csr[2] ? ch_adr1[30:2] : ch_adr0[30:2];
457
 
458
always @(posedge clk)
459
        ch_dis <= #1 HAVE_CBUF ? ((sw_pointer[30:2] == cmp_adr) & sw_pointer[31]) : 1'b0;
460
 
461
endmodule
462
 
463
 
464
module wb_dma_ch_rf_dummy(clk, rst,
465
                        pointer, pointer_s, ch_csr, ch_txsz, ch_adr0, ch_adr1,
466
                        ch_am0, ch_am1, sw_pointer, ch_stop, ch_dis, int,
467
 
468
                        wb_rf_din, wb_rf_adr, wb_rf_we, wb_rf_re,
469
 
470
                        // DMA Registers Write Back Channel Select
471
                        ch_sel, ndnr,
472
 
473
                        // DMA Engine Status
474
                        dma_busy, dma_err, dma_done, dma_done_all,
475
 
476
                        // DMA Engine Reg File Update ctrl signals
477
                        de_csr, de_txsz, de_adr0, de_adr1,
478
                        de_csr_we, de_txsz_we, de_adr0_we, de_adr1_we,
479
                        de_fetch_descr, dma_rest,
480
                        ptr_set
481
 
482
                );
483
 
484
parameter       CH_NO = 0;
485
parameter       HAVE_ARS = 1;
486
parameter       HAVE_ED  = 1;
487
parameter       HAVE_CBUF= 1;
488
 
489
input           clk, rst;
490
 
491
output  [31:0]   pointer;
492
output  [31:0]   pointer_s;
493
output  [31:0]   ch_csr;
494
output  [31:0]   ch_txsz;
495
output  [31:0]   ch_adr0;
496
output  [31:0]   ch_adr1;
497
output  [31:0]   ch_am0;
498
output  [31:0]   ch_am1;
499
output  [31:0]   sw_pointer;
500
output          ch_stop;
501
output          ch_dis;
502
output          int;
503
 
504
input   [31:0]   wb_rf_din;
505
input   [7:0]    wb_rf_adr;
506
input           wb_rf_we;
507
input           wb_rf_re;
508
 
509
input   [4:0]    ch_sel;
510
input           ndnr;
511
 
512
// DMA Engine Status
513
input           dma_busy, dma_err, dma_done, dma_done_all;
514
 
515
// DMA Engine Reg File Update ctrl signals
516
input   [31:0]   de_csr;
517
input   [11:0]   de_txsz;
518
input   [31:0]   de_adr0;
519
input   [31:0]   de_adr1;
520
input           de_csr_we, de_txsz_we, de_adr0_we, de_adr1_we, ptr_set;
521
input           de_fetch_descr;
522
input           dma_rest;
523
 
524
assign          pointer = 32'h0;
525
assign          pointer_s = 32'h0;
526
assign          ch_csr = 32'h0;
527
assign          ch_txsz = 32'h0;
528
assign          ch_adr0 = 32'h0;
529
assign          ch_adr1 = 32'h0;
530
assign          ch_am0 = 32'h0;
531
assign          ch_am1 = 32'h0;
532
assign          sw_pointer = 32'h0;
533
assign          ch_stop = 1'b0;
534
assign          ch_dis = 1'b0;
535
assign          int = 1'b0;
536
 
537
endmodule

powered by: WebSVN 2.1.0

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