OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_peripheral/] [DMA/] [dma_multi_channel_wb.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/**********************************************************************
2
**      File:  dma.v
3
**      Date:2017-05-14
4
**
5
**      Copyright (C) 2014-2017  Alireza Monemi
6
**
7
**      This file is part of ProNoC
8
**
9
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
10
**      you can redistribute it and/or modify it under the terms of the GNU
11
**      Lesser General Public License as published by the Free Software Foundation,
12
**      either version 2 of the License, or (at your option) any later version.
13
**
14
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
15
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
17
**      Public License for more details.
18
**
19
**      You should have received a copy of the GNU Lesser General Public
20
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
21
**
22
**
23
**      Description:
24
**      weighted round robin arbiter
25
**      A multi chanel wishbone based DMA  and with support burst data transaction
26
**      (Dose not support byte enable yet).
27
***************************************/
28
 
29
// synthesis translate_off
30
`timescale 1ns / 1ps
31
// synthesis translate_on
32
 
33
 
34
 
35
 
36
 
37
 module dma_multi_chan_wb #(
38
    parameter chanel=4,
39
    parameter MAX_TRANSACTION_WIDTH=10, // Maximum transaction size will be 2 power of MAX_DMA_TRANSACTION_WIDTH words 
40
    parameter MAX_BURST_SIZE =256, // in words
41
    parameter FIFO_B = 4,
42
    parameter DEBUG_EN = 1,
43
    //wishbone port parameters
44
    parameter Dw            =   32,
45
    parameter S_Aw          =   7,
46
    parameter M_Aw          =   32,
47
    parameter TAGw          =   3,
48
    parameter SELw          =   4
49
 
50
 
51
)
52
(
53
     // 
54
    reset,
55
    clk,
56
 
57
     //wishbone slave interface signals
58
    s_dat_i,
59
    s_sel_i,
60
    s_addr_i,
61
    s_cti_i,
62
    s_stb_i,
63
    s_cyc_i,
64
    s_we_i,
65
    s_dat_o,
66
    s_ack_o,
67
 
68
 
69
 
70
    //wishbone master rd interface signals
71
    m_rd_sel_o,
72
    m_rd_addr_o,
73
    m_rd_cti_o,
74
    m_rd_stb_o,
75
    m_rd_cyc_o,
76
    m_rd_we_o,
77
    m_rd_dat_i,
78
    m_rd_ack_i,
79
 
80
 
81
     //wishbone master wr interface signals
82
 
83
    m_wr_sel_o,
84
    m_wr_dat_o,
85
    m_wr_addr_o,
86
    m_wr_cti_o,
87
    m_wr_stb_o,
88
    m_wr_cyc_o,
89
    m_wr_we_o,
90
    m_wr_ack_i,
91
 
92
 
93
    //intruupt interface
94
    irq
95
 
96
);
97
 
98
    input reset,clk;
99
 
100
   //wishbone slave interface signals
101
    input   [Dw-1       :   0]      s_dat_i;
102
    input   [SELw-1     :   0]      s_sel_i;
103
    input   [S_Aw-1     :   0]      s_addr_i;
104
    input   [TAGw-1     :   0]      s_cti_i;
105
    input                           s_stb_i;
106
    input                           s_cyc_i;
107
    input                           s_we_i;
108
 
109
    output      [Dw-1       :   0]  s_dat_o;
110
    output  reg                     s_ack_o;
111
 
112
 
113
 
114
    //wishbone read master interface signals
115
    output  [SELw-1          :   0] m_rd_sel_o;
116
    output  [M_Aw-1          :   0] m_rd_addr_o;
117
    output  [TAGw-1          :   0] m_rd_cti_o;
118
    output                          m_rd_stb_o;
119
    output                          m_rd_cyc_o;
120
    output                          m_rd_we_o;
121
    input   [Dw-1           :  0]   m_rd_dat_i;
122
    input                           m_rd_ack_i;
123
 
124
     //wishbone write master interface signals
125
    output  [SELw-1          :   0] m_wr_sel_o;
126
    output  [Dw-1            :   0] m_wr_dat_o;
127
    output  [M_Aw-1          :   0] m_wr_addr_o;
128
    output  [TAGw-1          :   0] m_wr_cti_o;
129
    output                          m_wr_stb_o;
130
    output                          m_wr_cyc_o;
131
    output                          m_wr_we_o;
132
    input                           m_wr_ack_i;
133
 
134
    output irq;
135
 
136
    wire                            s_ack_o_next;
137
 
138
 
139
     function integer log2;
140
      input integer number; begin
141
         log2=(number <=1) ? 1: 0;
142
         while(2**log2<number) begin
143
            log2=log2+1;
144
         end
145
      end
146
    endfunction // log2 
147
 
148
 
149
    localparam
150
        CHw=log2(chanel),
151
        BURST_SIZE_w= log2(MAX_BURST_SIZE);
152
 
153
     /*   wishbone slave adderess :
154
 
155
    [2:0]
156
 
157
            1   :   BURST_SIZE_WB_ADDR  // The busrt size in words
158
            2   :   DATA_SIZE_WB_ADDR,  // The transfer data size in byte
159
            3   :   RD_STRT_WB_ADDR3,  // The source start address in byte
160
            4   :   WR_STRT_WB_ADDR   // The destination start address in byte
161
 
162
    [3+CHw:3]
163
                chanel num
164
 
165
    */
166
 
167
    wire [CHw-1 :   0] chanel_addr = s_addr_i [3+CHw:3];
168
    wire [2     :   0] chanel_s_addr_i = s_addr_i [2: 0];
169
 
170
 
171
 
172
     localparam [2  :   0]
173
        DMA_STATUS_WB_ADDR =3'd0,
174
        BURST_SIZE_WB_ADDR =3'd1; // The busrt size in words
175
 
176
 
177
 
178
 
179
 
180
    reg [BURST_SIZE_w-1  :   0] burst_size, burst_size_next,burst_counter,burst_counter_next;
181
 
182
 
183
    wire [chanel-1 :   0] chanel_wr_is_busy, chanel_rd_is_busy;
184
    wire [chanel-1 :   0] chanel_wr_enable,chanel_rd_enable,chanel_state_reg_enable;
185
    wire [chanel-1 :   0] chanel_burst_counter_ld, chanel_burst_counter_dec;
186
    wire [chanel-1 :   0] chanel_fifo_wr, chanel_fifo_rd;
187
    wire [chanel-1 :   0] chanel_fifo_full, chanel_fifo_nearly_full, chanel_fifo_empty;
188
    wire [chanel-1 :   0] chanel_rd_is_active,chanel_wr_is_active;
189
    wire [CHw-1     :   0] rd_enable_binary,wr_enable_binary;
190
 
191
 
192
 
193
   wire  [SELw-1    :   0] chanel_m_rd_sel_o  [chanel-1 :   0];
194
   wire  [M_Aw-1    :   0] chanel_m_rd_addr_o [chanel-1 :   0];
195
   wire  [TAGw-1    :   0] chanel_m_rd_cti_o  [chanel-1 :   0];
196
   wire  [chanel-1 :   0] chanel_m_rd_stb_o;
197
   wire  [chanel-1 :   0] chanel_m_rd_cyc_o;
198
   wire  [chanel-1 :   0] chanel_m_rd_we_o;
199
 
200
 
201
   wire  [SELw-1    :   0] chanel_m_wr_sel_o  [chanel-1 :   0];
202
   wire  [M_Aw-1    :   0] chanel_m_wr_addr_o [chanel-1 :   0];
203
   wire  [TAGw-1    :   0] chanel_m_wr_cti_o  [chanel-1 :   0];
204
   wire  [chanel-1 :   0] chanel_m_wr_stb_o;
205
   wire  [chanel-1 :   0] chanel_m_wr_cyc_o;
206
   wire  [chanel-1 :   0] chanel_m_wr_we_o;
207
 
208
 
209
 
210
 
211
 
212
 
213
 
214
 
215
 
216
    wire burst_counter_ld = | chanel_burst_counter_ld;
217
    wire burst_counter_dec= | chanel_burst_counter_dec;
218
    wire fifo_wr =  | chanel_fifo_wr;
219
    wire fifo_rd =  | chanel_fifo_rd;
220
 
221
    wire last_burst = (burst_counter == 1);
222
    wire burst_is_set =  (burst_size>0);
223
 
224
    localparam STATUSw= 2 * CHw + 3 * chanel;
225
    wire  [STATUSw-1  :0] status;
226
    wire [chanel-1 :   0] chanel_is_active = chanel_rd_is_busy|chanel_wr_is_busy;
227
    assign status= {rd_enable_binary,wr_enable_binary,chanel_rd_is_busy,chanel_wr_is_busy,chanel_is_active};
228
    assign s_dat_o={{(Dw-STATUSw){1'b0}}, status};
229
 
230
 
231
 
232
   bin_to_one_hot #(
233
        .BIN_WIDTH(CHw),
234
        .ONE_HOT_WIDTH(chanel)
235
   )
236
   convert(
237
        .bin_code(chanel_addr),
238
        .one_hot_code(chanel_state_reg_enable)
239
   );
240
 
241
 
242
 
243
 
244
    assign s_ack_o_next    =   s_stb_i & (~s_ack_o);
245
 
246
 
247
    always @ (*)begin
248
        burst_counter_next=burst_counter;
249
        burst_size_next= burst_size;
250
        if(burst_counter_ld)    burst_counter_next = burst_size;
251
        if(burst_counter_dec)   burst_counter_next= burst_counter- 1'b1;
252
 
253
        if(s_stb_i  &    s_we_i )   begin
254
            if (chanel_wr_is_busy == {chanel{1'b0}})  begin
255
                case(chanel_s_addr_i)
256
                    BURST_SIZE_WB_ADDR: begin
257
                        burst_size_next=s_dat_i [BURST_SIZE_w-1 : 0];
258
                    end //BURST_SIZE_WB_ADDR
259
                endcase
260
            end
261
        end
262
 
263
    end
264
 
265
 
266
`ifdef SYNC_RESET_MODE
267
    always @ (posedge clk )begin
268
`else
269
    always @ (posedge clk or posedge reset)begin
270
`endif
271
        if(reset) begin
272
            burst_counter <= {BURST_SIZE_w{1'b0}};
273
            burst_size <= {BURST_SIZE_w{1'b1}};
274
            s_ack_o <= 1'b0;
275
        end else begin
276
            burst_counter<= burst_counter_next;
277
            burst_size <= burst_size_next;
278
            s_ack_o <= s_ack_o_next;
279
        end
280
    end
281
 
282
 
283
 
284
 
285
 
286
 
287
    genvar i;
288
    generate
289
    for (i=0;i<chanel; i=i+1) begin : chanel_
290
        dma_single_wb #(
291
                .MAX_TRANSACTION_WIDTH(MAX_TRANSACTION_WIDTH),
292
                .Dw(Dw),
293
                .S_Aw(3),
294
                .M_Aw(M_Aw),
295
                .TAGw(TAGw),
296
                .SELw(SELw)
297
        )
298
        chanel_dma
299
        (
300
                .reset(reset),
301
                .clk(clk),
302
                .status(),
303
 
304
                //active-enable signals
305
                .rd_enable(chanel_rd_enable[i]),
306
                .wr_enable(chanel_wr_enable[i]),
307
                .state_reg_enable(chanel_state_reg_enable[i]),
308
                .rd_is_busy(chanel_rd_is_busy[i]),
309
                .wr_is_busy(chanel_wr_is_busy[i]),
310
                .rd_is_active(chanel_rd_is_active[i]),
311
                .wr_is_active(chanel_wr_is_active[i]),
312
                .burst_counter_ld(chanel_burst_counter_ld[i]),
313
                .burst_counter_dec(chanel_burst_counter_dec[i]),
314
                .burst_size_is_set(burst_is_set),
315
                .last_burst(last_burst),
316
 
317
                //fifo
318
                .fifo_wr(chanel_fifo_wr[i]),
319
            .fifo_rd(chanel_fifo_rd[i]),
320
            .fifo_full(chanel_fifo_full[i]),
321
            .fifo_nearly_full(chanel_fifo_nearly_full[i]),
322
            .fifo_empty(chanel_fifo_empty[i]),
323
 
324
                //wb salve
325
                .s_dat_i(s_dat_i),
326
                .s_sel_i(s_sel_i),
327
                .s_addr_i(chanel_s_addr_i),
328
                .s_cti_i(s_cti_i),
329
                .s_stb_i(s_stb_i),
330
                .s_cyc_i(s_cyc_i),
331
                .s_we_i(s_we_i),
332
                //.s_dat_o(s_dat_o),
333
                //.s_ack_o(s_ack_o),
334
 
335
                //
336
                .m_rd_sel_o(chanel_m_rd_sel_o[i]),
337
                .m_rd_addr_o(chanel_m_rd_addr_o[i]),
338
                .m_rd_cti_o(chanel_m_rd_cti_o[i]),
339
                .m_rd_stb_o(chanel_m_rd_stb_o[i]),
340
                .m_rd_cyc_o(chanel_m_rd_cyc_o[i]),
341
                .m_rd_we_o(chanel_m_rd_we_o[i]),
342
        //      .m_rd_dat_i(m_rd_dat_i),
343
                .m_rd_ack_i(m_rd_ack_i),
344
 
345
 
346
                .m_wr_sel_o(chanel_m_wr_sel_o[i]),
347
        //      .m_wr_dat_o(chanel_m_wr_dat_o[i]),
348
                .m_wr_addr_o(chanel_m_wr_addr_o[i]),
349
                .m_wr_cti_o(chanel_m_wr_cti_o[i]),
350
                .m_wr_stb_o(chanel_m_wr_stb_o[i]),
351
                .m_wr_cyc_o(chanel_m_wr_cyc_o[i]),
352
                .m_wr_we_o(chanel_m_wr_we_o[i]),
353
                .m_wr_ack_i(m_wr_ack_i)
354
        );
355
 
356
    end  // for loop for chanel
357
 
358
 
359
    if(chanel> 1) begin : multi_chanel
360
 
361
        // round roubin arbiter
362
        bus_arbiter # (
363
            .M (chanel)
364
        )
365
        wr_arbiter
366
        (
367
            .request (chanel_wr_is_active ),
368
            .grant  (chanel_wr_enable),
369
            .clk (clk),
370
            .reset (reset)
371
        );
372
 
373
 
374
 
375
 
376
        bus_arbiter # (
377
            .M (chanel)
378
        )
379
        rd_arbiter
380
        (
381
            .request (chanel_rd_is_active),
382
            .grant  (chanel_rd_enable),
383
            .clk (clk),
384
            .reset (reset)
385
        );
386
 
387
 
388
        one_hot_to_bin #(
389
            .ONE_HOT_WIDTH(chanel),
390
            .BIN_WIDTH(CHw)
391
        )
392
        rd_en_conv
393
        (
394
            .one_hot_code(chanel_rd_enable),
395
            .bin_code(rd_enable_binary)
396
        );
397
 
398
 
399
         one_hot_to_bin #(
400
            .ONE_HOT_WIDTH(chanel),
401
            .BIN_WIDTH(CHw)
402
        )
403
        wr_en_conv
404
        (
405
            .one_hot_code(chanel_wr_enable),
406
            .bin_code(wr_enable_binary)
407
        );
408
 
409
 
410
    end else begin : single_chanel // if we have just one chanel there is no needs for arbitration
411
        assign chanel_wr_enable =  chanel_wr_is_busy;
412
        assign chanel_rd_enable =  chanel_rd_is_busy;
413
        assign rd_enable_binary = 1'b0;
414
        assign wr_enable_binary = 1'b0;
415
    end
416
    endgenerate
417
 
418
 
419
    //wb multiplexors
420
 
421
    assign m_rd_sel_o  = chanel_m_rd_sel_o[rd_enable_binary];
422
    assign m_rd_addr_o = chanel_m_rd_addr_o[rd_enable_binary];
423
    assign m_rd_cti_o  = chanel_m_rd_cti_o[rd_enable_binary];
424
    assign m_rd_stb_o  = chanel_m_rd_stb_o[rd_enable_binary];
425
    assign m_rd_cyc_o  = chanel_m_rd_cyc_o[rd_enable_binary];
426
    assign m_rd_we_o   = chanel_m_rd_we_o[rd_enable_binary];
427
 
428
 
429
 
430
    assign m_wr_sel_o = chanel_m_wr_sel_o[wr_enable_binary];
431
    assign m_wr_addr_o= chanel_m_wr_addr_o[wr_enable_binary];
432
    assign m_wr_cti_o = chanel_m_wr_cti_o[wr_enable_binary];
433
    assign m_wr_stb_o = chanel_m_wr_stb_o[wr_enable_binary];
434
    assign m_wr_cyc_o = chanel_m_wr_cyc_o[wr_enable_binary];
435
    assign m_wr_we_o  = chanel_m_wr_we_o[wr_enable_binary];
436
 
437
 
438
 
439
 
440
 
441
 
442
 
443
 
444
  shared_mem_fifos #(
445
        .NUM(chanel),
446
        .B(FIFO_B),
447
        .Dw(Dw),
448
        .DEBUG_EN(DEBUG_EN)
449
  )
450
  the_shared_mem_fifos
451
  (
452
        .din(m_rd_dat_i),
453
        .fifo_num_wr(chanel_rd_enable ), // when chnnel is in read mode it start writing on fifo
454
        .fifo_num_rd(chanel_wr_enable),
455
        .wr_en(fifo_wr),
456
        .rd_en(fifo_rd),
457
        .dout(m_wr_dat_o),
458
        .full(chanel_fifo_full),
459
        .nearly_full(chanel_fifo_nearly_full),
460
        .empty(chanel_fifo_empty),
461
        .reset(reset),
462
        .clk(clk)
463
  );
464
 
465
 
466
 
467
 
468
 
469
 
470
 
471
 endmodule
472
 
473
 
474
 
475
 
476
 
477
 
478
 
479
 
480
 
481
 
482
 
483
 
484
 
485
 
486
 
487
 
488
 
489
 
490
 
491
 
492
 
493
 
494
 
495
 
496
module dma_single_wb #(
497
 
498
    parameter MAX_TRANSACTION_WIDTH=10, // MAximum transaction size will be 2 power of MAX_DMA_TRANSACTION_WIDTH words 
499
    //wishbone port parameters
500
    parameter Dw            =   32,
501
    parameter S_Aw          =   7,
502
    parameter M_Aw          =   32,
503
    parameter TAGw          =   3,
504
    parameter SELw          =   4
505
 
506
 
507
)
508
(
509
     // 
510
    reset,
511
    clk,
512
 
513
    //ctrl signals
514
    rd_enable,
515
    wr_enable,
516
    state_reg_enable,
517
    rd_is_busy,
518
    wr_is_busy,
519
    rd_is_active,
520
    wr_is_active,
521
    last_burst,
522
    status,
523
 
524
    //fifo signals
525
    fifo_wr,
526
    fifo_rd,
527
    fifo_full,
528
    fifo_nearly_full,
529
    fifo_empty,
530
 
531
    //busrdt counter control signals
532
    burst_counter_ld,
533
    burst_counter_dec,
534
    burst_size_is_set,
535
 
536
     //wishbone slave interface signals
537
    s_dat_i,
538
    s_sel_i,
539
    s_addr_i,
540
    s_cti_i,
541
    s_stb_i,
542
    s_cyc_i,
543
    s_we_i,
544
   // s_dat_o,
545
   // s_ack_o,
546
 
547
 
548
 
549
    //wishbone master rd interface signals
550
    m_rd_sel_o,
551
    m_rd_addr_o,
552
    m_rd_cti_o,
553
    m_rd_stb_o,
554
    m_rd_cyc_o,
555
    m_rd_we_o,
556
  //  m_rd_dat_i,
557
    m_rd_ack_i,
558
 
559
 
560
     //wishbone master wr interface signals
561
 
562
    m_wr_sel_o,
563
   // m_wr_dat_o,
564
    m_wr_addr_o,
565
    m_wr_cti_o,
566
    m_wr_stb_o,
567
    m_wr_cyc_o,
568
    m_wr_we_o,
569
    m_wr_ack_i
570
 
571
 
572
 
573
 
574
);
575
 
576
 
577
    function integer log2;
578
      input integer number; begin
579
         log2=(number <=1) ? 1: 0;
580
         while(2**log2<number) begin
581
            log2=log2+1;
582
         end
583
      end
584
    endfunction // log2 
585
 
586
    localparam
587
        WORLD_SIZE = Dw/8,
588
        OFFSET_w= log2(WORLD_SIZE);
589
 
590
 
591
 
592
 
593
 
594
    //state machine registers/parameters
595
    localparam
596
        RD_ST_NUM=3,
597
        WR_ST_NUM=3;
598
    localparam [RD_ST_NUM-1 :   0]
599
        RD_IDEAL = 1,
600
        RD_ACTIVE =2,
601
        RD_RELEASE_WB=4;
602
 
603
 
604
    localparam [WR_ST_NUM-1:0]
605
        WR_IDEAL = 1,
606
        WR_READ_FIFO=2,
607
        WR_ACTIVE =4;
608
 
609
 
610
    localparam [2 : 0]
611
        CLASSIC = 3'b000,
612
        CONST_ADDR_BURST = 3'b010,
613
        INCREMENT_BURST = 3'b011,
614
        END_OF_BURST = 3'b111;
615
 
616
 
617
      //control Registers/ parameters 
618
 
619
    localparam [S_Aw-1  :   0]
620
        DMA_STATUS_WB_ADDR =0,
621
        BURST_SIZE_WB_ADDR =1, // The busrt size in words
622
        DATA_SIZE_WB_ADDR =2,  // The transfer data size in byte
623
        RD_STRT_WB_ADDR =   3, // The source start address in byte       
624
        WR_STRT_WB_ADDR=4; // the destination start address in byte   
625
 
626
 
627
    localparam STATUSw=RD_ST_NUM+WR_ST_NUM+1;
628
 
629
    output  [STATUSw-1  :0] status;
630
 
631
 
632
    input reset,clk,rd_enable,wr_enable, state_reg_enable;
633
    output reg rd_is_busy, wr_is_busy;
634
    output reg burst_counter_ld,    burst_counter_dec;
635
    input burst_size_is_set;
636
    input last_burst;
637
    output reg rd_is_active, wr_is_active;
638
 
639
 
640
    //fifo
641
    output reg  fifo_wr, fifo_rd;
642
    input       fifo_full, fifo_nearly_full, fifo_empty;
643
 
644
 
645
     //wishbone slave interface signals
646
    input   [Dw-1       :   0]      s_dat_i;
647
    input   [SELw-1     :   0]      s_sel_i;
648
    input   [S_Aw-1     :   0]      s_addr_i;
649
    input   [TAGw-1     :   0]      s_cti_i;
650
    input                           s_stb_i;
651
    input                           s_cyc_i;
652
    input                           s_we_i;
653
 
654
  //  output      [Dw-1       :   0]  s_dat_o;
655
  //  output  reg                     s_ack_o;
656
 
657
 
658
 
659
    //wishbone read master interface signals
660
    output  [SELw-1          :   0] m_rd_sel_o;
661
    output  [M_Aw-1          :   0] m_rd_addr_o;
662
    output reg [TAGw-1       :   0] m_rd_cti_o;
663
    output                          m_rd_stb_o;
664
    output   reg                    m_rd_cyc_o;
665
    output                          m_rd_we_o;
666
   // input   [Dw-1           :  0]   m_rd_dat_i;
667
    input                           m_rd_ack_i;
668
 
669
     //wishbone write master interface signals
670
    output  [SELw-1          :   0] m_wr_sel_o;
671
  //  output  [Dw-1            :   0] m_wr_dat_o;
672
    output  [M_Aw-1          :   0] m_wr_addr_o;
673
    output  reg [TAGw-1      :   0] m_wr_cti_o;
674
    output                          m_wr_stb_o;
675
    output  reg                     m_wr_cyc_o;
676
    output                          m_wr_we_o;
677
    input                           m_wr_ack_i;
678
 
679
 
680
 
681
 
682
     wire dma_busy;
683
 
684
 
685
 
686
 
687
 
688
    wire [S_Aw-1    :   0] wb_wr_rd_addr;
689
    assign wb_wr_rd_addr =   s_addr_i [S_Aw-1 :   0];
690
 
691
 
692
    reg [Dw-1   :   0] rd_start_addr,rd_start_addr_next;
693
    reg [Dw-1   :   0] wr_start_addr,wr_start_addr_next;
694
 
695
    reg [MAX_TRANSACTION_WIDTH-1    :   0] data_size, data_size_next;
696
    reg [MAX_TRANSACTION_WIDTH-1    :   0] rd_counter, rd_counter_next;
697
    reg [MAX_TRANSACTION_WIDTH-1    :   0] wr_counter, wr_counter_next;
698
 
699
 
700
 
701
 
702
 
703
 
704
 
705
    reg  rd_start, rd_done,wr_done;
706
 
707
    wire last_data = (rd_counter == data_size-1'b1);
708
 
709
 
710
 
711
 
712
 
713
    reg [RD_ST_NUM-1    :0] rd_ps,rd_ns; // read  peresent state, read next sate 
714
    reg [WR_ST_NUM-1    :0] wr_ps,wr_ns; // read  peresent state, read next sate
715
 
716
    reg wr_is_busy_next, rd_is_busy_next;
717
 
718
 
719
    assign status= {wr_ps,rd_ps,dma_busy};
720
   // assign s_dat_o={{(Dw-STATUSw){1'b0}}, status};
721
 
722
 
723
 
724
 
725
    assign dma_busy = (rd_ps!= RD_IDEAL) | (wr_ps!= WR_IDEAL);
726
 
727
 
728
    assign m_rd_addr_o =  rd_start_addr + rd_counter;
729
    assign m_wr_addr_o =  wr_start_addr + wr_counter;
730
    assign m_rd_stb_o =  m_rd_cyc_o;
731
    assign m_wr_stb_o =  m_wr_cyc_o;
732
    assign m_wr_we_o = 1'b1;
733
    assign m_rd_we_o = 1'b0;
734
    //assign m_rd_cti_o = ( rd_data_end | burst_data_end | fifo_nearly_full) ? END_OF_BURST : CONST_ADDR_BURST;
735
    //assign m_wr_cti_o = (fifo_has_one_word & ~fifo_wr) ? END_OF_BURST : CONST_ADDR_BURST;
736
    assign m_wr_sel_o = 4'b1111;
737
    assign m_rd_sel_o = 4'b1111;
738
 
739
 //  assign  rd_is_busy = (rd_ps == RD_ACTIVE);
740
 //   assign  wr_is_busy = (wr_ps == WR_ACTIVE);
741
 
742
 
743
 
744
    //read state machine
745
    always @ (*) begin
746
        // default values 
747
        rd_ns = rd_ps;
748
        rd_counter_next=rd_counter;
749
        burst_counter_ld=1'b0;
750
        burst_counter_dec=1'b0;
751
        m_rd_cti_o =  CONST_ADDR_BURST;
752
        m_rd_cyc_o=1'b0;
753
        fifo_wr=1'b0;
754
        rd_done = 1'b0;
755
        rd_is_active =1'b0;
756
 
757
            case(rd_ps)
758
                RD_IDEAL: begin
759
                   if(rd_start) begin
760
                        if (burst_size_is_set && (data_size>0)) begin
761
                            rd_counter_next= {MAX_TRANSACTION_WIDTH{1'b0}};
762
                            burst_counter_ld=1'b1;
763
                            rd_ns = RD_ACTIVE;
764
                        end else begin // sett error reg
765
 
766
                       end
767
                   end
768
                end // RD_IDEAL
769
                RD_ACTIVE: begin
770
                    rd_is_active =1'b1; // this signal sends request to the rd_arbiter, the granted signal is rd_enable
771
                    if(rd_enable) begin
772
                        m_rd_cyc_o=1'b1;
773
                        if(last_data |  last_burst | (fifo_nearly_full & !fifo_rd))  m_rd_cti_o= END_OF_BURST;
774
                        if(fifo_nearly_full & !fifo_rd)  rd_ns = RD_RELEASE_WB;
775
 
776
 
777
                        if (m_rd_ack_i) begin
778
                                fifo_wr=1'b1;
779
                                rd_counter_next=rd_counter +1'b1;
780
                                burst_counter_dec=1'b1;
781
 
782
                                if(last_data) begin
783
                                  rd_ns = RD_IDEAL;
784
                                  rd_done = 1'b1;
785
 
786
                                end else if (last_burst | (fifo_nearly_full & !fifo_rd)) begin
787
                                  rd_ns = RD_RELEASE_WB;
788
 
789
                                end
790
                        end
791
                    end
792
 
793
                end // RD_ACTIVE
794
                RD_RELEASE_WB: begin
795
                    //burst_counter_next = burst_size;
796
 
797
                      burst_counter_ld=1'b1;
798
                    if(!fifo_full) begin
799
                        rd_ns = RD_ACTIVE;
800
                    end
801
 
802
                end //RD_RELEASE_WB
803
                    default: begin
804
 
805
 
806
                    end
807
            endcase
808
    end//alays
809
 
810
 
811
 
812
 
813
 //write state machine    
814
    always @ (*) begin
815
        // default values 
816
        wr_ns = wr_ps;
817
        wr_counter_next=wr_counter;
818
        m_wr_cyc_o=1'b0;
819
        m_wr_cti_o= CONST_ADDR_BURST;
820
        fifo_rd=1'b0;
821
        wr_done=1'b0;
822
        wr_is_active =1'b0;
823
        if (rd_start ) wr_counter_next = {MAX_TRANSACTION_WIDTH{1'b0}};
824
 
825
 
826
            case(wr_ps)
827
                WR_IDEAL: begin
828
                    if(!fifo_empty)begin
829
                        wr_ns = WR_READ_FIFO;
830
                    end
831
 
832
                end // WR_IDEAL
833
                WR_READ_FIFO: begin
834
                     wr_is_active =1'b1; // this signal sends request to the wr_arbiter, the granted signal is wr_enable
835
                     if(wr_enable) begin
836
                          wr_ns = WR_ACTIVE;
837
                          fifo_rd=1'b1;
838
                    end
839
                end
840
 
841
 
842
                WR_ACTIVE: begin
843
                     wr_is_active =1'b1; // this signal sends request to the wr_arbiter, the granted signal is wr_enable
844
                     if(wr_enable) begin
845
                            m_wr_cyc_o=1'b1;
846
                            if (fifo_empty) begin
847
                                m_wr_cti_o= END_OF_BURST;
848
                            end
849
                            if (m_wr_ack_i) begin
850
                                wr_counter_next=wr_counter +1'b1;
851
                                if (fifo_empty) begin
852
                                    wr_ns = WR_IDEAL;
853
                                    wr_done=1'b1;
854
                                end else begin
855
                                    fifo_rd=1'b1;
856
                                end
857
                            end
858
                     end
859
                end // WR_ACTIVE
860
                default: begin
861
 
862
 
863
                    end
864
            endcase
865
 
866
    end//alays
867
 
868
 
869
 
870
 
871
 
872
    // update control registers
873
    always @ (*) begin
874
        //default values
875
        rd_start_addr_next= rd_start_addr;
876
        wr_start_addr_next=wr_start_addr;
877
        data_size_next= data_size;
878
      //  burst_size_next= burst_size;
879
        rd_start = 1'b0;
880
        if(s_stb_i  &    s_we_i & state_reg_enable)   begin
881
            if (!dma_busy)  begin
882
                case(wb_wr_rd_addr)
883
                    RD_STRT_WB_ADDR: begin
884
                        rd_start_addr_next={{OFFSET_w{1'b0}},s_dat_i [Dw-1    : OFFSET_w]};
885
                    end //RD_STRT_WB_ADDR
886
                    DATA_SIZE_WB_ADDR: begin
887
                        data_size_next=s_dat_i [MAX_TRANSACTION_WIDTH+OFFSET_w-1 :   OFFSET_w];
888
                    end //DATA_SIZE_WB_ADDR
889
                    BURST_SIZE_WB_ADDR: begin
890
              //          burst_size_next=s_dat_i [BURST_SIZE_w-1 : 0];    
891
                    end //BURST_SIZE_WB_ADDR
892
                    WR_STRT_WB_ADDR: begin
893
                        wr_start_addr_next= {{OFFSET_w{1'b0}},s_dat_i [Dw-1 :   OFFSET_w]};
894
                        rd_start = 1'b1;
895
                    end //WR_STRT_WB_ADDR
896
                          default :begin
897
 
898
 
899
                          end
900
                 endcase//wb_wr_rd_addr
901
            end//if
902
        end//if
903
   end// always
904
 
905
 
906
 
907
    always @(*)begin
908
        rd_is_busy_next= rd_is_busy;
909
        if(rd_start) rd_is_busy_next =1'b1;
910
        else if(rd_done) rd_is_busy_next=1'b0;
911
    end
912
 
913
    wire wr_start = ~fifo_empty;
914
     always @(*)begin
915
        wr_is_busy_next= wr_is_busy;
916
        if(wr_done) wr_is_busy_next =1'b0;
917
        else if(wr_start) wr_is_busy_next=1'b1;
918
    end
919
 
920
 
921
 
922
 
923
    //registers assigmnet
924
 
925
`ifdef SYNC_RESET_MODE
926
    always @ (posedge clk )begin
927
`else
928
    always @ (posedge clk or posedge reset)begin
929
`endif
930
        if(reset) begin
931
            rd_ps <= RD_IDEAL;
932
            wr_ps <= WR_IDEAL;
933
         //   s_ack_o <= 1'b0;
934
            rd_start_addr <= {Dw{1'b0}};
935
            wr_start_addr <= {Dw{1'b0}};
936
            data_size <= {MAX_TRANSACTION_WIDTH{1'b0}};
937
          //  burst_size <= {BURST_SIZE_w{1'b0}};   
938
            rd_counter <=  {MAX_TRANSACTION_WIDTH{1'b0}};
939
            wr_counter <=   {MAX_TRANSACTION_WIDTH{1'b0}};
940
            rd_is_busy<= 1'b0;
941
            wr_is_busy<= 1'b0;
942
       //     burst_counter <= {BURST_SIZE_w{1'b0}};
943
 
944
        end else begin
945
            rd_ps <= rd_ns;
946
            wr_ps <= wr_ns;
947
            rd_start_addr <= rd_start_addr_next;
948
            wr_start_addr <= wr_start_addr_next;
949
            data_size <= data_size_next;
950
   //         burst_size <= burst_size_next;  
951
            rd_counter <=  rd_counter_next;
952
            wr_counter <=  wr_counter_next;
953
            rd_is_busy <=rd_is_busy_next;
954
            wr_is_busy <=wr_is_busy_next;
955
       //     burst_counter<= burst_counter_next;            
956
       //     s_ack_o<=s_ack_o_next;
957
        end
958
    end
959
 
960
 
961
 
962
 
963
/*
964
    dma_fifo  #(
965
         .Dw(Dw),//data_width
966
         .B(FIFO_B) // buffer num
967
    )
968
    the_fifo
969
    (
970
         .din(m_rd_dat_i),
971
         .wr_en(fifo_wr),
972
         .rd_en(fifo_rd),
973
         .dout(m_wr_dat_o),
974
         .full(fifo_full),
975
         .nearly_full(fifo_nearly_full),
976
         .empty(fifo_empty),
977
         .reset(reset),
978
         .clk(clk)
979
    );
980
*/
981
 
982
 
983
 
984
 
985
 
986
 
987
endmodule
988
 
989
 
990
 
991
 
992
/**************
993
*   shared memory multi chanel fifo
994
*
995
****************/
996
 
997
module shared_mem_fifos #(
998
    parameter NUM      =   4,
999
    parameter B        =   4,   // buffer space :flit per VC 
1000
    parameter Dw     =   32,
1001
    parameter DEBUG_EN =   1
1002
 
1003
    )
1004
    (
1005
        din,     // Data in
1006
        fifo_num_wr,//write vertual chanel   
1007
        fifo_num_rd,//read vertual chanel    
1008
        wr_en,   // Write enable
1009
        rd_en,   // Read the next word
1010
        dout,    // Data out
1011
        full,
1012
        nearly_full,
1013
        empty,
1014
        reset,
1015
        clk
1016
 
1017
    );
1018
 
1019
 
1020
 
1021
    function integer log2;
1022
      input integer number; begin
1023
         log2=(number <=1) ? 1: 0;
1024
         while(2**log2<number) begin
1025
            log2=log2+1;
1026
         end
1027
      end
1028
    endfunction // log2 
1029
 
1030
    localparam      V       =   NUM,
1031
                    Fw      =   Dw,   //flit width
1032
                    BV      =   B   *   V;
1033
 
1034
 
1035
    input  [Fw-1      :0]   din;     // Data in
1036
    input  [V-1       :0]   fifo_num_wr;//write vertual chanel   
1037
    input  [V-1       :0]   fifo_num_rd;//read vertual chanel    
1038
    input                   wr_en;   // Write enable
1039
    input                   rd_en;   // Read the next word
1040
    output [Fw-1       :0]  dout;    // Data out
1041
 
1042
    output [V-1 :   0] full;
1043
    output [V-1 :   0] nearly_full;
1044
    output [V-1 :   0] empty;
1045
 
1046
 
1047
 
1048
 
1049
    input                   reset;
1050
    input                   clk;
1051
 
1052
 
1053
    localparam BVw              =   log2(BV),
1054
               Bw               =   (B==1)? 1 : log2(B),
1055
               Vw               =  (V==1)? 1 : log2(V),
1056
               DEPTHw           =   Bw+1,
1057
               BwV              =   Bw * V,
1058
               BVwV             =   BVw * V,
1059
               RAM_DATA_WIDTH   =   Fw ;
1060
 
1061
 
1062
 
1063
    wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_din;
1064
    wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_dout;
1065
    wire  [V-1                  :   0] wr;
1066
    wire  [V-1                  :   0] rd;
1067
    reg   [DEPTHw-1             :   0] depth    [V-1            :0];
1068
 
1069
 
1070
    assign fifo_ram_din = din;
1071
    assign dout = fifo_ram_dout;
1072
    assign  wr  =   (wr_en)?  fifo_num_wr : {V{1'b0}};
1073
    assign  rd  =   (rd_en)?  fifo_num_rd : {V{1'b0}};
1074
 
1075
 
1076
    //assign dout = queue[rd_ptr];
1077
 
1078
 
1079
 
1080
 
1081
genvar i;
1082
 
1083
generate
1084
    if((2**Bw)==B)begin :pow2
1085
        /*****************
1086
          Buffer width is power of 2
1087
        ******************/
1088
    reg [Bw- 1      :   0] rd_ptr [V-1          :0];
1089
    reg [Bw- 1      :   0] wr_ptr [V-1          :0];
1090
 
1091
 
1092
 
1093
 
1094
    wire [BwV-1    :    0]  rd_ptr_array;
1095
    wire [BwV-1    :    0]  wr_ptr_array;
1096
    wire [Bw-1     :    0]  vc_wr_addr;
1097
    wire [Bw-1     :    0]  vc_rd_addr;
1098
    wire [Vw-1     :    0]  wr_select_addr;
1099
    wire [Vw-1     :    0]  rd_select_addr;
1100
    wire [Bw+Vw-1  :    0]  wr_addr;
1101
    wire [Bw+Vw-1  :    0]  rd_addr;
1102
 
1103
 
1104
 
1105
 
1106
    assign  wr_addr =   {wr_select_addr,vc_wr_addr};
1107
    assign  rd_addr =   {rd_select_addr,vc_rd_addr};
1108
 
1109
 
1110
 
1111
    one_hot_mux #(
1112
        .IN_WIDTH       (BwV),
1113
        .SEL_WIDTH      (V)
1114
    )
1115
    wr_ptr_mux
1116
    (
1117
        .mux_in         (wr_ptr_array),
1118
        .mux_out            (vc_wr_addr),
1119
        .sel                (fifo_num_wr)
1120
    );
1121
 
1122
 
1123
 
1124
    one_hot_mux #(
1125
        .IN_WIDTH       (BwV),
1126
        .SEL_WIDTH      (V)
1127
    )
1128
    rd_ptr_mux
1129
    (
1130
        .mux_in         (rd_ptr_array),
1131
        .mux_out            (vc_rd_addr),
1132
        .sel                (fifo_num_rd)
1133
    );
1134
 
1135
 
1136
 
1137
    one_hot_to_bin #(
1138
    .ONE_HOT_WIDTH  (V)
1139
 
1140
    )
1141
    wr_vc_start_addr
1142
    (
1143
    .one_hot_code   (fifo_num_wr),
1144
    .bin_code       (wr_select_addr)
1145
 
1146
    );
1147
 
1148
    one_hot_to_bin #(
1149
    .ONE_HOT_WIDTH  (V)
1150
 
1151
    )
1152
    rd_vc_start_addr
1153
    (
1154
    .one_hot_code   (fifo_num_rd),
1155
    .bin_code       (rd_select_addr)
1156
 
1157
    );
1158
 
1159
    dma_fifo_ram    #(
1160
        .DATA_WIDTH (RAM_DATA_WIDTH),
1161
        .ADDR_WIDTH (BVw )
1162
    )
1163
    the_queue
1164
    (
1165
        .wr_data        (fifo_ram_din),
1166
        .wr_addr        (wr_addr[BVw-1  :   0]),
1167
        .rd_addr        (rd_addr[BVw-1  :   0]),
1168
        .wr_en          (wr_en),
1169
        .rd_en          (rd_en),
1170
        .clk            (clk),
1171
        .rd_data        (fifo_ram_dout)
1172
    );
1173
 
1174
    for(i=0;i<V;i=i+1) begin :loop0
1175
 
1176
        assign full[i] = (depth [i] == B);
1177
        assign nearly_full[i] = depth[i] >= B-1;
1178
        assign empty[i] = depth[i] == {DEPTHw{1'b0}};
1179
 
1180
 
1181
        assign  wr_ptr_array[(i+1)*Bw- 1        :   i*Bw]   =       wr_ptr[i];
1182
        assign  rd_ptr_array[(i+1)*Bw- 1        :   i*Bw]   =       rd_ptr[i];
1183
        //assign    vc_nearly_full[i] = (depth[i] >= B-1);
1184
 
1185
 
1186
 
1187
`ifdef SYNC_RESET_MODE
1188
    always @ (posedge clk )begin
1189
`else
1190
    always @ (posedge clk or posedge reset)begin
1191
`endif
1192
            if (reset) begin
1193
                rd_ptr  [i] <= {Bw{1'b0}};
1194
                wr_ptr  [i] <= {Bw{1'b0}};
1195
                depth   [i] <= {DEPTHw{1'b0}};
1196
            end
1197
            else begin
1198
                if (wr[i] ) wr_ptr[i] <= wr_ptr [i]+ 1'h1;
1199
                if (rd[i] ) rd_ptr [i]<= rd_ptr [i]+ 1'h1;
1200
                if (wr[i] & ~rd[i]) depth [i]<=
1201
//synthesis translate_off
1202
//synopsys  translate_off
1203
                   #1
1204
//synopsys  translate_on
1205
//synthesis translate_on
1206
                   depth[i] + 1'h1;
1207
                else if (~wr[i] & rd[i]) depth [i]<=
1208
//synthesis translate_off
1209
//synopsys  translate_off
1210
                   #1
1211
//synopsys  translate_on
1212
//synthesis translate_on
1213
                   depth[i] - 1'h1;
1214
            end//else
1215
        end//always
1216
 
1217
 
1218
//synthesis translate_off
1219
//synopsys  translate_off
1220
 
1221
        always @(posedge clk) begin
1222
            if(~reset)begin
1223
                if (wr[i] && (depth[i] == B) && !rd[i])
1224
                    $display("%t: ERROR: Attempt to write to full FIFO: %m",$time);
1225
                if (rd[i] && (depth[i] == {DEPTHw{1'b0}}   ))
1226
                    $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
1227
 
1228
          end//~reset      
1229
        //if (wr_en)       $display($time, " %h is written on fifo ",din);
1230
        end//always
1231
//synopsys  translate_on
1232
//synthesis translate_on
1233
    end//for
1234
 
1235
 
1236
 
1237
    end  else begin :no_pow2    //pow2
1238
 
1239
 
1240
 
1241
 
1242
 
1243
    /*****************
1244
        Buffer width is not power of 2
1245
     ******************/
1246
 
1247
 
1248
 
1249
 
1250
 
1251
    //pointers
1252
    reg [BVw- 1     :   0] rd_ptr [V-1          :0];
1253
    reg [BVw- 1     :   0] wr_ptr [V-1          :0];
1254
 
1255
    // memory address
1256
    wire [BVw- 1    :   0]  wr_addr;
1257
    wire [BVw- 1    :   0]  rd_addr;
1258
 
1259
    //pointer array      
1260
    wire [BVwV- 1   :   0]  wr_addr_all;
1261
    wire [BVwV- 1   :   0]  rd_addr_all;
1262
 
1263
    for(i=0;i<V;i=i+1) begin :loop0
1264
 
1265
        assign  wr_addr_all[(i+1)*BVw- 1        :   i*BVw]   =       wr_ptr[i];
1266
        assign  rd_addr_all[(i+1)*BVw- 1        :   i*BVw]   =       rd_ptr[i];
1267
        assign full[i] = (depth [i] == B);
1268
        assign nearly_full[i] = depth[i] >= B-1;
1269
        assign empty[i] = depth[i] == {DEPTHw{1'b0}};
1270
 
1271
 
1272
`ifdef SYNC_RESET_MODE
1273
    always @ (posedge clk )begin
1274
`else
1275
    always @ (posedge clk or posedge reset)begin
1276
`endif
1277
            if (reset) begin
1278
                rd_ptr  [i] <= (B*i);
1279
                wr_ptr  [i] <= (B*i);
1280
                depth   [i] <= {DEPTHw{1'b0}};
1281
            end
1282
            else begin
1283
                if (wr[i] ) wr_ptr[i] <=(wr_ptr[i]==(B*(i+1))-1)? (B*i) : wr_ptr [i]+ 1'h1;
1284
                if (rd[i] ) rd_ptr[i] <=(rd_ptr[i]==(B*(i+1))-1)? (B*i) : rd_ptr [i]+ 1'h1;
1285
                if (wr[i] & ~rd[i]) depth [i]<=
1286
//synthesis translate_off
1287
//synopsys  translate_off
1288
                   #1
1289
//synopsys  translate_on
1290
//synthesis translate_on
1291
                   depth[i] + 1'h1;
1292
                else if (~wr[i] & rd[i]) depth [i]<=
1293
//synthesis translate_off
1294
//synopsys  translate_off
1295
                   #1
1296
//synopsys  translate_on
1297
//synthesis translate_on
1298
                   depth[i] - 1'h1;
1299
            end//else
1300
        end//always  
1301
 
1302
 
1303
//synthesis translate_off
1304
//synopsys  translate_off
1305
 
1306
        always @(posedge clk) begin
1307
            if(~reset)begin
1308
                if (wr[i] && (depth[i] == B) && !rd[i])
1309
                    $display("%t: ERROR: Attempt to write to full FIFO: %m",$time);
1310
                if (rd[i] && (depth[i] == {DEPTHw{1'b0}}   ))
1311
                    $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
1312
 
1313
 
1314
        //if (wr_en)       $display($time, " %h is written on fifo ",din);
1315
            end//~reset
1316
        end//always
1317
 
1318
//synopsys  translate_on
1319
//synthesis translate_on
1320
 
1321
 
1322
 
1323
    end//FOR
1324
 
1325
 
1326
    one_hot_mux #(
1327
        .IN_WIDTH(BVwV),
1328
        .SEL_WIDTH(V),
1329
        .OUT_WIDTH(BVw)
1330
    )
1331
    wr_mux
1332
    (
1333
        .mux_in(wr_addr_all),
1334
        .mux_out(wr_addr),
1335
        .sel(fifo_num_wr)
1336
    );
1337
 
1338
    one_hot_mux #(
1339
        .IN_WIDTH(BVwV),
1340
        .SEL_WIDTH(V),
1341
        .OUT_WIDTH(BVw)
1342
    )
1343
    rd_mux
1344
    (
1345
        .mux_in(rd_addr_all),
1346
        .mux_out(rd_addr),
1347
        .sel(fifo_num_rd)
1348
    );
1349
 
1350
    dma_fifo_ram_mem_size  #(
1351
       .DATA_WIDTH (RAM_DATA_WIDTH),
1352
       .MEM_SIZE (BV )
1353
    )
1354
    the_queue
1355
    (
1356
        .wr_data        (fifo_ram_din),
1357
        .wr_addr        (wr_addr),
1358
        .rd_addr        (rd_addr),
1359
        .wr_en          (wr_en),
1360
        .rd_en          (rd_en),
1361
        .clk            (clk),
1362
        .rd_data        (fifo_ram_dout)
1363
    );
1364
 
1365
 
1366
 
1367
 
1368
 
1369
 
1370
    end
1371
    endgenerate
1372
 
1373
 
1374
 
1375
 
1376
 
1377
 
1378
//synthesis translate_off
1379
//synopsys  translate_off
1380
generate
1381
if(DEBUG_EN) begin :dbg
1382
    always @(posedge clk) begin
1383
        if(~reset)begin
1384
            if(wr_en && fifo_num_wr == {V{1'b0}})
1385
                    $display("%t: ERROR: Attempt to write when no wr chanel is asserted: %m",$time);
1386
            if(rd_en && fifo_num_rd == {V{1'b0}})
1387
                    $display("%t: ERROR: Attempt to read when no rd chanel  is asserted: %m",$time);
1388
        end
1389
    end
1390
end
1391
endgenerate
1392
//synopsys  translate_on
1393
//synthesis translate_on    
1394
 
1395
endmodule
1396
 
1397
 
1398
 
1399
 
1400
/****************************
1401
 
1402
     fifo_ram
1403
 
1404
*****************************/
1405
 
1406
 
1407
 
1408
module dma_fifo_ram     #(
1409
    parameter DATA_WIDTH    = 32,
1410
    parameter ADDR_WIDTH    = 8
1411
    )
1412
    (
1413
        input [DATA_WIDTH-1         :       0]  wr_data,
1414
        input [ADDR_WIDTH-1         :       0]      wr_addr,
1415
        input [ADDR_WIDTH-1         :       0]      rd_addr,
1416
        input                                               wr_en,
1417
        input                                               rd_en,
1418
        input                                           clk,
1419
        output [DATA_WIDTH-1   :       0]      rd_data
1420
    );
1421
 
1422
        reg [DATA_WIDTH-1:0] memory_rd_data;
1423
   // memory
1424
        reg [DATA_WIDTH-1:0] queue [2**ADDR_WIDTH-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
1425
        always @(posedge clk ) begin
1426
                        if (wr_en)
1427
                                 queue[wr_addr] <= wr_data;
1428
                        if (rd_en)
1429
                                 memory_rd_data <= queue[rd_addr];
1430
        end
1431
 
1432
    assign rd_data =  memory_rd_data;
1433
 
1434
endmodule
1435
 
1436
 
1437
 
1438
module dma_fifo_ram_mem_size     #(
1439
    parameter DATA_WIDTH  = 32,
1440
    parameter MEM_SIZE    = 200
1441
    )
1442
    (
1443
       wr_data,
1444
       wr_addr,
1445
       rd_addr,
1446
       wr_en,
1447
       rd_en,
1448
       clk,
1449
       rd_data
1450
    );
1451
 
1452
 
1453
    function integer log2;
1454
      input integer number; begin
1455
         log2=(number <=1) ? 1: 0;
1456
         while(2**log2<number) begin
1457
            log2=log2+1;
1458
         end
1459
      end
1460
    endfunction // log2 
1461
 
1462
    localparam ADDR_WIDTH=log2(MEM_SIZE);
1463
 
1464
    input [DATA_WIDTH-1         :       0]  wr_data;
1465
    input [ADDR_WIDTH-1         :       0]  wr_addr;
1466
    input [ADDR_WIDTH-1         :       0]  rd_addr;
1467
    input                                   wr_en;
1468
    input                                   rd_en;
1469
    input                                   clk;
1470
    output reg  [DATA_WIDTH-1   :       0]  rd_data;
1471
 
1472
 
1473
 
1474
    reg [DATA_WIDTH-1:0] queue [MEM_SIZE-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
1475
 
1476
    always @(posedge clk ) begin
1477
         if (wr_en)   queue[wr_addr] <= wr_data;
1478
         if (rd_en)   rd_data <= queue[rd_addr];
1479
    end
1480
 
1481
 
1482
endmodule
1483
 

powered by: WebSVN 2.1.0

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