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_noc/] [flit_buffer.sv] - Blame information for rev 54

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

Line No. Rev Author Line
1 54 alirezamon
`include "pronoc_def.v"
2
/**********************************************************************
3
 **     File:  flit_buffer.v
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 .
21
 **
22
 **
23
 **     Description:
24
 **     Input buffer module. All VCs located in the same router
25
 **     input port share one single FPGA BRAM
26
 **
27
 **************************************************************/
28
 
29
 
30
module flit_buffer
31
                import pronoc_pkg::*;
32
        #(
33
                parameter B =4,
34
                parameter SSA_EN="YES" // "YES" , "NO"
35
                )
36
                (
37
                        din,     // Data in
38
                        vc_num_wr,//write virtual channel
39
                        vc_num_rd,//read virtual channel
40
                        wr_en,   // Write enable
41
                        rd_en,   // Read the next word
42
                        dout,    // Data out
43
                        vc_not_empty,
44
                        reset,
45
                        clk,
46
                        ssa_rd,
47
 
48
                        //for multicast
49
                        multiple_dest, // incr rd-sub
50
                        sub_rd_ptr_ld,  // load rd_ptr to sub_rd_pt
51
                        flit_is_tail
52
                );
53
 
54
 
55
 
56
 
57
        localparam
58
                Bw      =   (B==1)? 1 : log2(B),
59
                BV      =   B   *   V,
60
                BVw              =   log2(BV),
61
                Vw               =  (V==1)? 1 : log2(V),
62
                DEPTHw           =   log2(B+1),
63
                BwV              =   Bw * V,
64
                BVwV             =   BVw * V,
65
                RESTw = Fw -2-V ,
66
                PTRw = ((2**Bw)==B)? Bw : BVw, // if B is power of 2 PTRw is Bw else is BVw
67
                ARRAYw = PTRw * V,
68
                /* verilator lint_off WIDTH */
69
                RAM_DATA_WIDTH   = (PCK_TYPE == "MULTI_FLIT")? Fw - V :  Fw - V -2;
70
        /* verilator lint_on WIDTH */
71
 
72
 
73
 
74
 
75
        input  [Fw-1      :0]   din;     // Data in
76
        input  [V-1       :0]   vc_num_wr;//write virtual chanel
77
        input  [V-1       :0]   vc_num_rd;//read virtual chanel
78
        input                   wr_en;   // Write enable
79
        input                   rd_en;   // Read the next word
80
        output [Fw-1       :0]  dout;    // Data out
81
        output [V-1        :0]  vc_not_empty;
82
        input                   reset;
83
        input                   clk;
84
        input  [V-1        :0]  ssa_rd;
85
        input  [V-1        :0]  multiple_dest;
86
        input  [V-1        :0]  sub_rd_ptr_ld;
87
        output [V-1 : 0]        flit_is_tail;
88
 
89
 
90
        //pointers
91
        wire [PTRw- 1     :   0] rd_ptr [V-1          :0];
92
        wire [PTRw- 1     :   0] wr_ptr [V-1          :0];
93
        reg  [PTRw- 1     :   0] rd_ptr_next [V-1          :0];
94
        reg  [PTRw- 1     :   0] wr_ptr_next [V-1          :0];
95
        reg  [PTRw- 1     :   0] sub_rd_ptr_next [V-1          :0];
96
        wire [PTRw- 1     :   0] sub_rd_ptr [V-1          :0];
97
        wire [PTRw-1      :   0] ptr_tmp  [V-1 : 0];
98
        wire [ARRAYw-1    :   0] rd_ptr_array;
99
        wire [ARRAYw-1    :   0] wr_ptr_array;
100
 
101
 
102
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_din;
103
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_dout;
104
        wire  [V-1                  :   0] wr;
105
        wire  [V-1                  :   0] rd;
106
        wire  [DEPTHw-1             :   0] depth      [V-1            :0];
107
        reg   [DEPTHw-1             :   0] depth_next [V-1            :0];
108
        wire  [DEPTHw-1             :   0] sub_depth       [V-1            :0];
109
        reg   [DEPTHw-1             :   0] sub_depth_next  [V-1            :0];
110
 
111
 
112
        reg   [B-1 : 0] tail_fifo [V-1 : 0];
113
        wire  [1  : 0] flgs_in, flgs_out;
114
        wire  [V-1: 0] vc_in;
115
        wire  [RESTw-1 :0      ] flit_rest_in,flit_rest_out;
116
        wire  [V-1       :   0] sub_rd;
117
        wire  [V-1       :   0] sub_restore;
118
 
119
        assign  wr  =   (wr_en)?  vc_num_wr : {V{1'b0}};
120
 
121
 
122
 
123
        genvar i;
124
 
125
        generate
126
        /* verilator lint_off WIDTH */
127
                if (CAST_TYPE != "UNICAST") begin
128
                        /* verilator lint_on WIDTH */
129
                        assign  sub_rd  =  (rd_en)?  vc_num_rd  : ssa_rd;
130
                        assign  sub_restore = sub_rd_ptr_ld;
131
                        assign  rd  =   (rd_en)?  vc_num_rd & ~multiple_dest : ssa_rd & ~multiple_dest;
132
                end else begin : unicast
133
                        assign  rd  =   (rd_en)?  vc_num_rd : ssa_rd;
134
                end
135
 
136
                /* verilator lint_off WIDTH */
137
                if (PCK_TYPE == "MULTI_FLIT") begin :multi
138
                        /* verilator lint_on WIDTH */
139
                        assign {flgs_in,vc_in,flit_rest_in}=din;
140
                        assign fifo_ram_din = {flgs_in,flit_rest_in};
141
                        assign {flgs_out,flit_rest_out} = fifo_ram_dout;
142
                        assign dout = {flgs_out,{V{1'bX}},flit_rest_out};
143
                end else begin : single
144
                        assign fifo_ram_din = din[RAM_DATA_WIDTH-1     :   0];
145
                        assign dout = {2'b11,{V{1'bX}},fifo_ram_dout};
146
                end
147
 
148
 
149
                for(i=0;i
150
                        assign  wr_ptr_array[(i+1)*PTRw- 1        :   i*PTRw]   =       wr_ptr[i];
151
 
152
                        /* verilator lint_off WIDTH */
153
                        if (CAST_TYPE != "UNICAST") begin
154
                                /* verilator lint_on WIDTH */
155
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       sub_rd_ptr[i];
156
                                localparam RESET_TO = ((2**Bw)==B)? 0 : B*i;
157
                                pronoc_register #(.W(PTRw),.RESET_TO(RESET_TO)) reg4 (.in(sub_rd_ptr_next[i]), .out(sub_rd_ptr[i]), .reset(reset), .clk(clk));
158
 
159
 
160
                                pronoc_register #(.W(DEPTHw)) sub_depth_reg (.in(sub_depth_next[i] ), .out(sub_depth [i]), .reset(reset), .clk(clk));
161
                                always @ (*)begin
162
                                        sub_depth_next  [i] = sub_depth   [i];
163
                                        if(sub_restore[i]) sub_depth_next  [i]= depth_next[i];
164
                                        else if (wr[i] & ~sub_rd[i]) sub_depth_next [i] = sub_depth[i] + 1'h1;
165
                                        else if (~wr[i] & sub_rd[i]) sub_depth_next [i] = sub_depth[i] - 1'h1;
166
                                end//always
167
 
168
                                assign  vc_not_empty    [i] =   (sub_depth[i] > 0);
169
 
170
 
171
 
172
 
173
                        end else begin : unicast
174
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       rd_ptr[i];
175
                                assign  vc_not_empty    [i] =   (depth[i] > 0);
176
                        end
177
                end//for
178
 
179
 
180
 
181
 
182
                if((2**Bw)==B)begin :pow2
183
                        /*****************
184
          Buffer width is power of 2
185
                         ******************/
186
 
187
                        wire [Bw-1     :    0]  vc_wr_addr;
188
                        wire [Bw-1     :    0]  vc_rd_addr;
189
                        wire [Vw-1     :    0]  wr_select_addr;
190
                        wire [Vw-1     :    0]  rd_select_addr;
191
                        wire [Bw+Vw-1  :    0]  wr_addr;
192
                        wire [Bw+Vw-1  :    0]  rd_addr;
193
 
194
                        assign  wr_addr =   {wr_select_addr,vc_wr_addr};
195
                        assign  rd_addr =   {rd_select_addr,vc_rd_addr};
196
 
197
 
198
                        onehot_mux_1D #(
199
                                        .W(Bw),
200
                                        .N(V)
201
                                )
202
                                wr_ptr_mux
203
                                (
204
                                        .in(wr_ptr_array),
205
                                        .out(vc_wr_addr),
206
                                        .sel(vc_num_wr)
207
                                );
208
 
209
 
210
                        onehot_mux_1D #(
211
                                        .W(Bw),
212
                                        .N(V)
213
                                )
214
                                rd_ptr_mux
215
                                (
216
                                        .in(rd_ptr_array),
217
                                        .out(vc_rd_addr),
218
                                        .sel(vc_num_rd)
219
                                );
220
 
221
                        one_hot_to_bin #(
222
                                        .ONE_HOT_WIDTH(V)
223
                                )
224
                                wr_vc_start_addr
225
                                (
226
                                        .one_hot_code(vc_num_wr),
227
                                        .bin_code(wr_select_addr)
228
                                );
229
 
230
                        one_hot_to_bin #(
231
                                        .ONE_HOT_WIDTH(V)
232
                                )
233
                                rd_vc_start_addr
234
                                (
235
                                        .one_hot_code(vc_num_rd),
236
                                        .bin_code(rd_select_addr)
237
                                );
238
 
239
                        fifo_ram    #(
240
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
241
                                        .ADDR_WIDTH (BVw ),
242
                                        .SSA_EN(SSA_EN)
243
                                )
244
                                the_queue
245
                                (
246
                                        .wr_data(fifo_ram_din),
247
                                        .wr_addr(wr_addr[BVw-1  :   0]),
248
                                        .rd_addr(rd_addr[BVw-1  :   0]),
249
                                        .wr_en(wr_en),
250
                                        .rd_en(rd_en),
251
                                        .clk(clk),
252
                                        .rd_data(fifo_ram_dout)
253
                                );
254
 
255
                        for(i=0;i
256
 
257
                                always @(posedge clk) begin
258
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]] <= din[Fw-2];
259
                                end
260
 
261
                                pronoc_register #(.W(Bw    )) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
262
                                pronoc_register #(.W(Bw    )) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
263
                                pronoc_register #(.W(DEPTHw)) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
264
 
265
 
266
                                always @ (*)begin
267
                                        rd_ptr_next [i] = rd_ptr  [i];
268
                                        wr_ptr_next [i] = wr_ptr  [i];
269
                                        depth_next  [i] = depth   [i];
270
 
271
                                        if (wr[i]  ) wr_ptr_next [i] = wr_ptr [i]+ 1'h1;
272
                                        if (rd[i]  ) rd_ptr_next [i] = rd_ptr [i]+ 1'h1;
273
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
274
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
275
 
276
                                end//always
277
 
278
                                /* verilator lint_off WIDTH */
279
                                if (CAST_TYPE != "UNICAST") begin :multicast
280
                                        /* verilator lint_on WIDTH */
281
                                        always @ (*)begin
282
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
283
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
284
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = sub_rd_ptr[i]+ 1'h1;
285
                                        end
286
 
287
                                        /* verilator lint_off WIDTH */
288
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][sub_rd_ptr[i]]  : 1'b1;
289
                                        /* verilator lint_on WIDTH */
290
 
291
 
292
                                end else begin : unicast
293
 
294
                                        /* verilator lint_off WIDTH */
295
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]] : 1'b1;
296
                                        /* verilator lint_on WIDTH */
297
                                end
298
                        end//for
299
 
300
 
301
 
302
                end  else begin :no_pow2
303
                        /*****************
304
        Buffer width is not power of 2
305
                         ******************/
306
                        // memory address
307
                        wire [BVw- 1    :   0]  wr_addr;
308
                        wire [BVw- 1    :   0]  rd_addr;
309
                        for(i=0;i
310
 
311
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
312
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
313
                                pronoc_register #(.W(DEPTHw)            ) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
314
 
315
 
316
                                always @(posedge clk) begin
317
                                        /* verilator lint_off WIDTH */
318
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]-(B*i)] <= din[Fw-2];
319
                                        /* verilator lint_on WIDTH */
320
                                end
321
 
322
                                always @ (*) begin
323
                                        rd_ptr_next [i] = rd_ptr  [i];
324
                                        wr_ptr_next [i] = wr_ptr  [i];
325
                                        depth_next  [i] = depth   [i];
326
                                        /* verilator lint_off WIDTH */
327
                                        if (wr[i] ) wr_ptr_next[i] =(wr_ptr[i]==(B*(i+1))-1)? (B*i) : wr_ptr [i]+ 1'h1;
328
                                        if (rd[i] ) rd_ptr_next[i] =(rd_ptr[i]==(B*(i+1))-1)? (B*i) : rd_ptr [i]+ 1'h1;
329
                                        /* verilator lint_on WIDTH */
330
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
331
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
332
                                end//always
333
 
334
 
335
 
336
                                /* verilator lint_off WIDTH */
337
                                if (CAST_TYPE != "UNICAST") begin :multicast
338
                                /* verilator lint_on WIDTH */
339
 
340
 
341
 
342
 
343
                                        always @ (*)begin
344
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
345
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
346
                                                /* verilator lint_off WIDTH */
347
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = (sub_rd_ptr[i]==(B*(i+1))-1)? (B*i) : sub_rd_ptr [i]+ 1'h1;
348
                                                /* verilator lint_on WIDTH */
349
                                        end
350
 
351
                                        /* verilator lint_off WIDTH */
352
                                        assign  ptr_tmp [i] = sub_rd_ptr[i]-(B*i);
353
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][ptr_tmp [i]] :1'b1;
354
                                        /* verilator lint_on WIDTH */
355
 
356
 
357
                                end else begin : unicast
358
                                        /* verilator lint_off WIDTH */
359
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]-(B*i)] : 1'b1;
360
                                        /* verilator lint_on WIDTH */
361
                                end
362
                        end//FOR
363
 
364
 
365
                        onehot_mux_1D #(
366
                                        .W(BVw),
367
                                        .N(V)
368
                                )
369
                                wr_mux
370
                                (
371
                                        .in(wr_ptr_array),
372
                                        .out(wr_addr),
373
                                        .sel(vc_num_wr)
374
                                );
375
 
376
                        onehot_mux_1D #(
377
                                        .W(BVw),
378
                                        .N(V)
379
                                )
380
                                rd_mux
381
                                (
382
                                        .in(rd_ptr_array),
383
                                        .out(rd_addr),
384
                                        .sel(vc_num_rd)
385
                                );
386
 
387
                        fifo_ram_mem_size #(
388
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
389
                                        .MEM_SIZE (BV ),
390
                                        .SSA_EN(SSA_EN)
391
                                )
392
                                the_queue
393
                                (
394
                                        .wr_data        (fifo_ram_din),
395
                                        .wr_addr        (wr_addr),
396
                                        .rd_addr        (rd_addr),
397
                                        .wr_en          (wr_en),
398
                                        .rd_en          (rd_en),
399
                                        .clk            (clk),
400
                                        .rd_data        (fifo_ram_dout)
401
                                );
402
                end
403
        endgenerate
404
 
405
 
406
 
407
 
408
 
409
 
410
        //synthesis translate_off
411
        //synopsys  translate_off
412
 
413
 
414
 
415
        generate
416
 
417
                if(DEBUG_EN) begin :dbg
418
                        always @(posedge clk) begin
419
                                if(wr_en && vc_num_wr == {V{1'b0}})begin
420
                                        $display("%t: ERROR: Attempt to write when no wr VC is asserted: %m",$time);
421
                                        $finish;
422
                                end
423
                                if(rd_en && vc_num_rd == {V{1'b0}})begin
424
                                        $display("%t: ERROR: Attempt to read when no rd VC is asserted: %m",$time);
425
                                        $finish;
426
                                end
427
                        end
428
                end //DEBUG_EN
429
 
430
 
431
                for(i=0;i
432
 
433
                        /* verilator lint_off WIDTH */
434
                        if (CAST_TYPE != "UNICAST") begin :multicast
435
                                /* verilator lint_on WIDTH */
436
 
437
 
438
 
439
                                always @(posedge clk) begin
440
                                        if (wr[i] && (sub_depth[i] == B [DEPTHw-1 : 0]) && !sub_rd[i]) begin
441
                                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
442
                                                $finish;
443
                                        end
444
                                        /* verilator lint_off WIDTH */
445
                                        if (sub_rd[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
446
                                                /* verilator lint_on WIDTH */
447
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
448
                                                $finish;
449
                                        end
450
                                        /* verilator lint_off WIDTH */
451
                                        if (sub_rd[i] && !wr[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
452
                                                /* verilator lint_on WIDTH */
453
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
454
                                                $finish;
455
                                        end
456
                                end//always
457
                        end     //multicast
458
 
459
 
460
                        always @(posedge clk) begin
461
                                if (wr[i] && (depth[i] == B [DEPTHw-1 : 0]) && !rd[i])begin
462
                                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
463
                                        $finish;
464
                                end
465
                                /* verilator lint_off WIDTH */
466
                                if (rd[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
467
                                        /* verilator lint_on WIDTH */
468
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
469
                                        $finish;
470
                                end
471
                                /* verilator lint_off WIDTH */
472
                                if (rd[i] && !wr[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
473
                                        /* verilator lint_on WIDTH */
474
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
475
                                        $finish;
476
                                end
477
                                //if (wr_en)       $display($time, " %h is written on fifo ",din);
478
                        end//always
479
                end//for
480
        endgenerate
481
        //synopsys  translate_on
482
        //synthesis translate_on
483
 
484
 
485
 
486
 
487
 
488
 
489
 
490
 
491
 
492
 
493
 
494
 
495
 
496
 
497
endmodule
498
 
499
 
500
 
501
/****************************
502
 
503
     fifo_ram
504
 
505
 *****************************/
506
 
507
 
508
 
509
module fifo_ram     #(
510
                parameter DATA_WIDTH    = 32,
511
                parameter ADDR_WIDTH    = 8,
512
                parameter SSA_EN="YES" // "YES" , "NO"
513
                )
514
                (
515
                wr_data,
516
                wr_addr,
517
                rd_addr,
518
                wr_en,
519
                rd_en,
520
                clk,
521
                rd_data
522
                );
523
 
524
 
525
        input [DATA_WIDTH-1         :       0]  wr_data;
526
        input [ADDR_WIDTH-1         :       0]  wr_addr;
527
        input [ADDR_WIDTH-1         :       0]  rd_addr;
528
        input                                   wr_en;
529
        input                                   rd_en;
530
        input                                   clk;
531
        output [DATA_WIDTH-1   :       0]       rd_data;
532
 
533
 
534
 
535
        reg [DATA_WIDTH-1:0] memory_rd_data;
536
        // memory
537
        reg [DATA_WIDTH-1:0] queue [2**ADDR_WIDTH-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
538
        always @(posedge clk ) begin
539
                if (wr_en)
540
                        queue[wr_addr] <= wr_data;
541
                if (rd_en)
542
                        memory_rd_data <=  queue[rd_addr];
543
        end
544
 
545
 
546
 
547
 
548
 
549
 
550
 
551
        generate
552
        /* verilator lint_off WIDTH */
553
                if(SSA_EN =="YES") begin :predict
554
                        /* verilator lint_on WIDTH */
555
                        //add bypass
556
                        reg [DATA_WIDTH-1:0]  bypass_reg;
557
                        reg rd_en_delayed;
558
                        always @(posedge clk ) begin
559
                                bypass_reg      <=wr_data;
560
                                rd_en_delayed   <=rd_en;
561
                        end
562
 
563
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
564
 
565
 
566
 
567
                end else begin : no_predict
568
                        assign rd_data =  memory_rd_data;
569
                end
570
        endgenerate
571
endmodule
572
 
573
 
574
 
575
/*********************
576
 *
577
 *   fifo_ram_mem_size
578
 *
579
 **********************/
580
 
581
 
582
module fifo_ram_mem_size     #(
583
                parameter DATA_WIDTH  = 32,
584
                parameter MEM_SIZE    = 200,
585
                parameter SSA_EN  = "YES" // "YES" , "NO"
586
                )
587
                (
588
                wr_data,
589
                wr_addr,
590
                rd_addr,
591
                wr_en,
592
                rd_en,
593
                clk,
594
                rd_data
595
                );
596
 
597
 
598
        function integer log2;
599
                input integer number; begin
600
                        log2=(number <=1) ? 1: 0;
601
                        while(2**log2
602
                                log2=log2+1;
603
                        end
604
                end
605
        endfunction // log2
606
 
607
        localparam ADDR_WIDTH=log2(MEM_SIZE);
608
 
609
        input  [DATA_WIDTH-1         :       0]  wr_data;
610
        input  [ADDR_WIDTH-1         :       0]  wr_addr;
611
        input  [ADDR_WIDTH-1         :       0]  rd_addr;
612
        input                                    wr_en;
613
        input                                    rd_en;
614
        input                                    clk;
615
        output [DATA_WIDTH-1        :       0]   rd_data;
616
 
617
 
618
 
619
 
620
 
621
 
622
        reg [DATA_WIDTH-1:0] memory_rd_data;
623
        // memory
624
        reg [DATA_WIDTH-1:0] queue [MEM_SIZE-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
625
        always @(posedge clk ) begin
626
                if (wr_en)
627
                        queue[wr_addr] <= wr_data;
628
                if (rd_en)
629
                        memory_rd_data <=  queue[rd_addr];
630
        end
631
 
632
        generate
633
        /* verilator lint_off WIDTH */
634
                if(SSA_EN =="YES") begin :predict
635
                        /* verilator lint_on WIDTH */
636
                        //add bypass
637
                        reg [DATA_WIDTH-1:0]  bypass_reg;
638
                        reg rd_en_delayed;
639
                        always @(posedge clk ) begin
640
                                bypass_reg     <=wr_data;
641
                                rd_en_delayed  <=rd_en;
642
                        end
643
 
644
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
645
 
646
 
647
 
648
                end else begin : no_predict
649
                        assign rd_data =  memory_rd_data;
650
                end
651
        endgenerate
652
endmodule
653
 
654
 
655
 
656
 
657
 
658
/**********************************
659
 
660
An small  First Word Fall Through FIFO. The code will use LUTs
661
    and  optimized for low LUTs utilization.
662
 
663
 **********************************/
664
 
665
 
666
module fwft_fifo #(
667
                parameter DATA_WIDTH = 2,
668
                parameter MAX_DEPTH = 2,
669
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
670
                )
671
                (
672
                input [DATA_WIDTH-1:0] din,     // Data in
673
                input          wr_en,   // Write enable
674
                input          rd_en,   // Read the next word
675
                output [DATA_WIDTH-1:0]  dout,    // Data out
676
                output         full,
677
                output         nearly_full,
678
                output          recieve_more_than_0,
679
                output          recieve_more_than_1,
680
                input          reset,
681
                input          clk
682
 
683
                );
684
 
685
 
686
        function integer log2;
687
                input integer number; begin
688
                        log2=(number <=1) ? 1: 0;
689
                        while(2**log2
690
                                log2=log2+1;
691
                        end
692
                end
693
        endfunction // log2
694
 
695
 
696
 
697
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
698
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
699
 
700
        wire                                        out_ld ;
701
        wire    [DATA_WIDTH-1                   :   0] dout_next;
702
        wire[DEPTH_DATA_WIDTH-1         :   0]  depth;
703
        reg [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
704
        reg [DATA_WIDTH-1:0]  dout_next_ld;
705
 
706
        genvar i;
707
        generate
708
 
709
                if(MAX_DEPTH>2) begin :mwb2
710
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
711
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
712
                        wire                               empty;
713
                        wire                               out_sel ;
714
                        if(DATA_WIDTH>1) begin :wb1
715
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
716
                                wire    [DATA_WIDTH-1       :   0] mux_out;
717
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
718
 
719
                                for(i=0;i
720
                                        always @(posedge clk ) begin
721
                                                //if (reset) begin
722
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
723
                                                //end else begin
724
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
725
                                                //end
726
                                        end
727
 
728
                                        assign mux_in[i]    = shiftreg[i];
729
                                        assign mux_out[i]   = mux_in[i][mux_sel];
730
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
731
                                end //for
732
 
733
 
734
                        end else begin :w1
735
                                wire    [MAX_DEPTH-2        :   0] mux_in;
736
                                wire    mux_out;
737
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
738
 
739
                                always @(posedge clk ) begin
740
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
741
                                end
742
 
743
                                assign mux_in    = shiftreg;
744
                                assign mux_out   = mux_in[mux_sel];
745
                                assign dout_next = (out_sel) ? mux_out : din;
746
 
747
 
748
 
749
 
750
                        end
751
 
752
 
753
                        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
754
                        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
755
                        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
756
                        assign recieve_more_than_0  = ~ empty;
757
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
758
                        assign out_sel                  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
759
                        assign out_ld                       = (depth !=0 )?  rd_en : wr_en;
760
                        assign depth_2                      = depth - 2;
761
                        assign mux_sel                  = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
762
 
763
                end else if  ( MAX_DEPTH == 2) begin :mw2
764
 
765
                        reg     [DATA_WIDTH-1       :   0] register;
766
 
767
 
768
                        always @(posedge clk ) begin
769
                                if(wr_en) register <= din;
770
                        end //always
771
 
772
                        assign full             = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
773
                        assign nearly_full      = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
774
                        assign out_ld           = (depth !=0 )?  rd_en : wr_en;
775
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
776
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
777
                        assign dout_next        = (recieve_more_than_1) ? register  : din;
778
 
779
 
780
                end else begin :mw1 // MAX_DEPTH == 1
781
                        assign out_ld       = wr_en;
782
                        assign dout_next    =   din;
783
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
784
                        assign nearly_full= 1'b1;
785
                        assign recieve_more_than_0 = full;
786
                        assign recieve_more_than_1 = 1'b0;
787
                end
788
 
789
 
790
 
791
        endgenerate
792
 
793
 
794
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
795
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
796
 
797
        always @ (*)begin
798
                depth_next  =  depth;
799
                dout_next_ld   =  dout;
800
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
801
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
802
                if (out_ld) dout_next_ld = dout_next;
803
        end//always
804
 
805
 
806
 
807
 
808
        //synthesis translate_off
809
        //synopsys  translate_off
810
        always @(posedge clk)
811
        begin
812
 
813
                if (wr_en & ~rd_en & full) begin
814
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
815
                        $finish;
816
                end
817
                /* verilator lint_off WIDTH */
818
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
819
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
820
                        $finish;
821
                end
822
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
823
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
824
                        $finish;
825
                end
826
                /* verilator lint_on WIDTH */
827
 
828
        end // always @ (posedge clk)
829
 
830
        //synopsys  translate_on
831
        //synthesis translate_on
832
 
833
 
834
 
835
 
836
endmodule
837
 
838
 
839
 
840
 
841
 
842
 
843
 
844
 
845
 
846
 
847
/*********************
848
 
849
    fwft_fifo_with_output_clear
850
    each individual output bit has
851
    its own clear signal
852
 
853
 **********************/
854
 
855
 
856
 
857
 
858
 
859
module fwft_fifo_with_output_clear #(
860
                parameter DATA_WIDTH = 2,
861
                parameter MAX_DEPTH = 2,
862
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="NO" // "YES" , "NO"
863
                )
864
                (
865
                din,     // Data in
866
                wr_en,   // Write enable
867
                rd_en,   // Read the next word
868
                dout,    // Data out
869
                full,
870
                nearly_full,
871
                recieve_more_than_0,
872
                recieve_more_than_1,
873
                reset,
874
                clk,
875
                clear
876
 
877
                );
878
 
879
        input   [DATA_WIDTH-1:0] din;
880
        input          wr_en;
881
        input          rd_en;
882
        output  [DATA_WIDTH-1:0]  dout;
883
        output         full;
884
        output         nearly_full;
885
        output         recieve_more_than_0;
886
        output         recieve_more_than_1;
887
        input          reset;
888
        input          clk;
889
        input    [DATA_WIDTH-1:0]  clear;
890
 
891
        function integer log2;
892
                input integer number; begin
893
                        log2=(number <=1) ? 1: 0;
894
                        while(2**log2
895
                                log2=log2+1;
896
                        end
897
                end
898
        endfunction // log2
899
 
900
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
901
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
902
 
903
        wire out_ld;
904
        wire [DATA_WIDTH-1 : 0] dout_next;
905
        wire [DEPTH_DATA_WIDTH-1 : 0]  depth;
906
        reg  [DEPTH_DATA_WIDTH-1 : 0]  depth_next;
907
        reg  [DATA_WIDTH-1:0]  dout_next_ld;
908
 
909
        genvar i;
910
        generate
911
                if(MAX_DEPTH>2) begin :mwb2
912
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
913
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
914
                        wire                               empty;
915
                        wire                               out_sel ;
916
                        if(DATA_WIDTH>1) begin :wb1
917
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
918
                                wire    [DATA_WIDTH-1       :   0] mux_out;
919
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
920
 
921
                                for(i=0;i
922
                                        always @(posedge clk ) begin
923
                                                //if (reset) begin
924
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
925
                                                //end else begin
926
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
927
                                                //end
928
                                        end
929
 
930
                                        assign mux_in[i]    = shiftreg[i];
931
                                        assign mux_out[i]   = mux_in[i][mux_sel];
932
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
933
                                end //for
934
 
935
                        end else begin :w1
936
                                wire    [MAX_DEPTH-2        :   0] mux_in;
937
                                wire    mux_out;
938
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
939
 
940
                                always @(posedge clk ) begin
941
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
942
                                end
943
 
944
                                assign mux_in    = shiftreg;
945
                                assign mux_out   = mux_in[mux_sel];
946
                                assign dout_next = (out_sel) ? mux_out : din;
947
 
948
                        end
949
 
950
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
951
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
952
                        assign empty  = depth == {DEPTH_DATA_WIDTH{1'b0}};
953
                        assign recieve_more_than_0  = ~ empty;
954
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
955
                        assign out_sel  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
956
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
957
                        assign depth_2 = depth-'d2;
958
                        assign mux_sel = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
959
 
960
                end else if  ( MAX_DEPTH == 2) begin :mw2
961
 
962
                        reg     [DATA_WIDTH-1       :   0] register;
963
 
964
                        always @(posedge clk ) begin
965
                                if(wr_en) register <= din;
966
                        end //always
967
 
968
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
969
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
970
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
971
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
972
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
973
                        assign dout_next = (recieve_more_than_1) ? register  : din;
974
 
975
                end else begin :mw1 // MAX_DEPTH == 1
976
                        assign out_ld       = wr_en;
977
                        assign dout_next    =   din;
978
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
979
                        assign nearly_full= 1'b1;
980
                        assign recieve_more_than_0 = full;
981
                        assign recieve_more_than_1 = 1'b0;
982
                end
983
        endgenerate
984
 
985
 
986
 
987
 
988
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
989
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
990
 
991
        always @ (*)begin
992
                depth_next  =  depth;
993
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
994
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
995
        end//always
996
 
997
 
998
 
999
        generate
1000
                for(i=0;i
1001
                        always @(*)begin
1002
                                dout_next_ld[i] = dout[i];
1003
                                if (clear[i]) dout_next_ld[i]   = 1'b0;
1004
                                else if (out_ld) dout_next_ld[i]   = dout_next[i];
1005
                        end//always
1006
                end
1007
        endgenerate
1008
 
1009
        //synthesis translate_off
1010
        //synopsys  translate_off
1011
        always @(posedge clk)
1012
 
1013
        begin
1014
                if(~reset)begin
1015
                        if (wr_en && ~rd_en && full) begin
1016
                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
1017
                                $finish;
1018
                        end
1019
                        /* verilator lint_off WIDTH */
1020
                        if (rd_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
1021
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
1022
                                $finish;
1023
                        end
1024
                        if (rd_en && ~wr_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "YES") begin
1025
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
1026
                                $finish;
1027
                        end
1028
                        /* verilator lint_on WIDTH */
1029
                end// ~reset
1030
        end // always @ (posedge clk)
1031
 
1032
        //synopsys  translate_on
1033
        //synthesis translate_on
1034
endmodule
1035
 
1036
 
1037
 
1038
 
1039
 
1040
 
1041
 
1042
 
1043
 
1044
module fwft_fifo_bram #(
1045
                parameter DATA_WIDTH = 2,
1046
                parameter MAX_DEPTH = 2,
1047
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
1048
                )
1049
                (
1050
                input [DATA_WIDTH-1:0] din,     // Data in
1051
                input          wr_en,   // Write enable
1052
                input          rd_en,   // Read the next word
1053
                output [DATA_WIDTH-1:0]  dout,    // Data out
1054
                output         full,
1055
                output         nearly_full,
1056
                output         recieve_more_than_0,
1057
                output         recieve_more_than_1,
1058
                input          reset,
1059
                input          clk
1060
 
1061
                );
1062
 
1063
 
1064
        function integer log2;
1065
                input integer number; begin
1066
                        log2=(number <=1) ? 1: 0;
1067
                        while(2**log2
1068
                                log2=log2+1;
1069
                        end
1070
                end
1071
        endfunction // log2
1072
 
1073
 
1074
 
1075
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
1076
 
1077
        reg  valid_next;
1078
        wire valid;
1079
        wire pass_din_to_out_reg, out_reg_wr_en, bram_out_is_valid_next;
1080
        wire bram_out_is_valid;
1081
        wire bram_empty, bram_rd_en, bram_wr_en;
1082
        wire [DATA_WIDTH-1 : 0] bram_dout;
1083
        wire [DATA_WIDTH-1 : 0] out_reg;
1084
        reg  [DATA_WIDTH-1 : 0] out_reg_next;
1085
 
1086
        assign dout = (bram_out_is_valid)?  bram_dout : out_reg;
1087
 
1088
 
1089
        assign  pass_din_to_out_reg = (wr_en & ~valid)| // a write has been recived while the reg_flit is not valid
1090
                (wr_en & valid & bram_empty & rd_en); //or its valid but bram is empty and its got a read request
1091
 
1092
        assign bram_rd_en = (rd_en & ~bram_empty);
1093
        assign bram_wr_en = (pass_din_to_out_reg)?  1'b0 :wr_en ; //make sure not write on the Bram if the reg fifo is empty
1094
 
1095
 
1096
        assign  out_reg_wr_en = pass_din_to_out_reg | bram_out_is_valid;
1097
 
1098
        assign  bram_out_is_valid_next = (bram_rd_en )? (rd_en &  ~bram_empty): 1'b0;
1099
 
1100
 
1101
        always @(*) begin
1102
                valid_next = valid;
1103
                if(out_reg_wr_en) valid_next =1'b1;
1104
                else if( bram_empty & rd_en) valid_next =1'b0;
1105
        end
1106
 
1107
 
1108
        bram_based_fifo  #(
1109
                        .Dw(DATA_WIDTH),//data_width
1110
                        .B(MAX_DEPTH)// buffer num
1111
                )bram_fifo(
1112
                        .din(din),
1113
                        .wr_en(bram_wr_en),
1114
                        .rd_en(bram_rd_en),
1115
                        .dout(bram_dout),
1116
                        .full(),
1117
                        .nearly_full(),
1118
                        .empty(bram_empty),
1119
                        .reset(reset),
1120
                        .clk(clk)
1121
                );
1122
 
1123
        wire [DEPTH_DATA_WIDTH-1         :   0]  depth;
1124
        reg  [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
1125
 
1126
 
1127
        pronoc_register #(.W(DATA_WIDTH)      ) reg1 (.in(out_reg_next           ), .out(out_reg), .reset(reset), .clk(clk));
1128
        pronoc_register #(.W(1)               ) reg2 (.in(valid_next             ), .out(valid), .reset(reset), .clk(clk));
1129
        pronoc_register #(.W(1)               ) reg3 (.in(bram_out_is_valid_next ), .out(bram_out_is_valid), .reset(reset), .clk(clk));
1130
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg4 (.in(depth_next             ), .out(depth), .reset(reset), .clk(clk));
1131
 
1132
 
1133
 
1134
        always @(*) begin
1135
                out_reg_next = out_reg;
1136
                depth_next   = depth;
1137
                if (wr_en & ~rd_en) depth_next =   depth + 1'h1;
1138
                else if (~wr_en & rd_en) depth_next  = depth - 1'h1;
1139
                if(pass_din_to_out_reg) out_reg_next = din;
1140
                if(bram_out_is_valid)   out_reg_next = bram_dout;
1141
        end
1142
 
1143
 
1144
 
1145
 
1146
        wire empty;
1147
        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
1148
        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
1149
        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
1150
        assign recieve_more_than_0  = ~ empty;
1151
        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
1152
 
1153
 
1154
 
1155
 
1156
        //synthesis translate_off
1157
        //synopsys  translate_off
1158
        always @(posedge clk)
1159
        begin
1160
                if (wr_en & ~rd_en & full) begin
1161
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
1162
                        $finish;
1163
                end
1164
                /* verilator lint_off WIDTH */
1165
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
1166
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
1167
                        $finish;
1168
                end
1169
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
1170
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
1171
                        $finish;
1172
                end
1173
                /* verilator lint_on WIDTH */
1174
        end // always @ (posedge clk)
1175
 
1176
        //synopsys  translate_on
1177
        //synthesis translate_on
1178
 
1179
 
1180
 
1181
 
1182
endmodule
1183
 
1184
 
1185
 
1186
 
1187
 
1188
 
1189
 
1190
 
1191
 
1192
/**********************************
1193
 
1194
            bram_based_fifo
1195
 
1196
 *********************************/
1197
 
1198
 
1199
module bram_based_fifo  #(
1200
                parameter Dw = 72,//data_width
1201
                parameter B  = 10// buffer num
1202
                )(
1203
                din,
1204
                wr_en,
1205
                rd_en,
1206
                dout,
1207
                full,
1208
                nearly_full,
1209
                empty,
1210
                reset,
1211
                clk
1212
                );
1213
 
1214
 
1215
        function integer log2;
1216
                input integer number; begin
1217
                        log2=(number <=1) ? 1: 0;
1218
                        while(2**log2
1219
                                log2=log2+1;
1220
                        end
1221
                end
1222
        endfunction // log2
1223
 
1224
        localparam  B_1 = B-1,
1225
                Bw = log2(B),
1226
                DEPTHw=log2(B+1);
1227
        localparam  [Bw-1   :   0] Bint =   B_1[Bw-1    :   0];
1228
 
1229
        input [Dw-1:0] din;     // Data in
1230
        input          wr_en;   // Write enable
1231
        input          rd_en;   // Read the next word
1232
 
1233
        output reg [Dw-1:0]  dout;    // Data out
1234
        output         full;
1235
        output         nearly_full;
1236
        output         empty;
1237
 
1238
        input          reset;
1239
        input          clk;
1240
 
1241
 
1242
 
1243
        reg [Dw-1       :   0] queue [B-1 : 0] /* synthesis ramstyle = "no_rw_check" */;
1244
        reg [Bw- 1      :   0] rd_ptr;
1245
        reg [Bw- 1      :   0] wr_ptr;
1246
        reg [DEPTHw-1   :   0] depth;
1247
 
1248
        // Sample the data
1249
        always @(posedge clk)
1250
        begin
1251
                if (wr_en)
1252
                        queue[wr_ptr] <= din;
1253
                if (rd_en)
1254
                        dout <=   queue[rd_ptr];
1255
        end
1256
 
1257
        always @(posedge clk)
1258
        begin
1259
                if (reset) begin
1260
                        rd_ptr <= {Bw{1'b0}};
1261
                        wr_ptr <= {Bw{1'b0}};
1262
                        depth  <= {DEPTHw{1'b0}};
1263
                end
1264
                else begin
1265
                        if (wr_en) wr_ptr <= (wr_ptr==Bint)? {Bw{1'b0}} : wr_ptr + 1'b1;
1266
                        if (rd_en) rd_ptr <= (rd_ptr==Bint)? {Bw{1'b0}} : rd_ptr + 1'b1;
1267
                        if (wr_en & ~rd_en) depth <=  depth + 1'b1;
1268
                        else if (~wr_en & rd_en) depth <=  depth - 1'b1;
1269
                end
1270
        end
1271
 
1272
        //assign dout = queue[rd_ptr];
1273
        localparam  [DEPTHw-1   :   0] Bint2 =   B_1[DEPTHw-1   :   0];
1274
 
1275
 
1276
        assign full = depth == B [DEPTHw-1   :   0];
1277
        assign nearly_full = depth >=Bint2; //  B-1
1278
        assign empty = depth == {DEPTHw{1'b0}};
1279
 
1280
        //synthesis translate_off
1281
        //synopsys  translate_off
1282
        always @(posedge clk)
1283
        begin
1284
                if(~reset)begin
1285
                        if (wr_en && depth == B[DEPTHw-1   :   0] && !rd_en) begin
1286
                                $display(" %t: ERROR: Attempt to write to full FIFO: %m",$time);
1287
                                $finish;
1288
                        end
1289
                        if (rd_en && depth == {DEPTHw{1'b0}}) begin
1290
                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
1291
                                $finish;
1292
                        end
1293
                end//~reset
1294
        end
1295
        //synopsys  translate_on
1296
        //synthesis translate_on
1297
 
1298
endmodule // fifo
1299
 

powered by: WebSVN 2.1.0

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