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 56

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

powered by: WebSVN 2.1.0

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