18
18
19
19
preview_fifo #(
20
20
.WIDTH( 16 ),
21
- .DEPTH( 16 )
21
+ .DEPTH( 16 ) // must be at least 8
22
22
) pf (
23
23
.clk( clk ),
24
24
.nrst( nrst ),
25
25
26
26
// input port
27
- .wrreq( ), // 3 bit one-hot
28
- .id0( ), // first word
29
- .id1( ), // secong word
27
+ .wrreq( ), // 3 bit one-hot
28
+ .id0( ), // first word
29
+ .id1( ), // secong word
30
30
31
31
// output port
32
- .rdreq( ), // 3 bit one-hot
33
- .od0( ), // first word
34
- .od1( ) // second word
32
+ .rdreq( ), // 3 bit one-hot
33
+ .od0( ), // first word
34
+ .od1( ), // second word
35
+
36
+ .empty( [1:0] ), // 2'b00, 2'b10 or 2'b11
37
+ .full( [1:0] ), // 2'b11, 2'b01 or 2'b00
38
+ .usedw( [USED_W:0] ) // attention to the width!
39
+
35
40
);
36
41
37
42
--- INSTANTIATION TEMPLATE END ---*/
@@ -66,7 +71,8 @@ module preview_fifo #( parameter
66
71
// when FIFO has no words -
67
72
// both of these flags will be active
68
73
output [1 : 0 ] full, // "full" flags, logic is similar to "empty"
69
- output [USED_W - 1 : 0 ] usedw // word count
74
+ output logic [USED_W : 0 ] usedw // word count, attention to the additional
75
+ // MSB for holding word count when full
70
76
);
71
77
72
78
@@ -81,10 +87,6 @@ logic [1:0][WIDTH-1:0] f_wrdata;
81
87
logic [1 : 0 ] f_rdreq;
82
88
logic [1 : 0 ][WIDTH - 1 : 0 ] f_rddata;
83
89
84
- // usedw0[] == usedw1[] OR usedw0[] == (usedw1[]-1) combinations are possible
85
- logic [1 : 0 ][USED_W - 2 : 0 ] f_usedw;
86
-
87
-
88
90
// underflow and owerflow protection flags
89
91
logic w0_valid, w1_valid, w2_valid;
90
92
logic r0_valid, r1_valid, r2_valid;
@@ -148,11 +150,11 @@ always_ff @(posedge clk) begin
148
150
end else begin
149
151
if ( wr_ptr ) begin
150
152
if ( wrreq[2 : 0 ] == 3'b010 && w1_valid ) begin
151
- wr_ptr = ~ wr_ptr; // no protection against full
153
+ wr_ptr = ~ wr_ptr;
152
154
end
153
155
end else begin
154
156
if ( wrreq[2 : 0 ] == 3'b010 && w0_valid ) begin
155
- wr_ptr = ~ wr_ptr; // no protection against full
157
+ wr_ptr = ~ wr_ptr;
156
158
end
157
159
end
158
160
end // nrst
221
223
222
224
// internal FIFOs itself =======================================================
223
225
226
+ logic [1 : 0 ][USED_W - 2 : 0 ] f_usedw_i;
227
+ logic [1 : 0 ][USED_W - 1 : 0 ] f_usedw;
228
+
224
229
scfifo # (
225
230
.LPM_WIDTH ( WIDTH ),
226
231
.LPM_NUMWORDS ( DEPTH / 2 ), // must be at least 4
231
236
.ENABLE_ECC ( " FALSE" ),
232
237
.ALLOW_RWCYCLE_WHEN_FULL ( " ON" ),
233
238
.USE_EAB ( " ON" )
234
- ) fifo0 (
239
+ ) internal_fifo0 (
235
240
.clock ( clk ),
236
241
.aclr ( 1'b0 ),
237
242
.sclr ( ~ nrst ),
243
248
.q ( f_rddata[0 ][WIDTH - 1 : 0 ] ),
244
249
.empty ( empty[0 ] ),
245
250
.full ( full[0 ] ),
246
- .usedw ( f_usedw [0 ][USED_W - 2 : 0 ] )
251
+ .usedw ( f_usedw_i [0 ][USED_W - 2 : 0 ] )
247
252
);
248
253
249
254
scfifo # (
256
261
.ENABLE_ECC ( " FALSE" ),
257
262
.ALLOW_RWCYCLE_WHEN_FULL ( " ON" ),
258
263
.USE_EAB ( " ON" )
259
- ) fifo1 (
264
+ ) internal_fifo1 (
260
265
.clock ( clk ),
261
266
.aclr ( 1'b0 ),
262
267
.sclr ( ~ nrst ),
@@ -268,11 +273,18 @@ end
268
273
.q ( f_rddata[1 ][WIDTH - 1 : 0 ] ),
269
274
.empty ( empty[1 ] ),
270
275
.full ( full[1 ] ),
271
- .usedw ( f_usedw [1 ][USED_W - 2 : 0 ] )
276
+ .usedw ( f_usedw_i [1 ][USED_W - 2 : 0 ] )
272
277
);
273
278
274
- assign usedw[USED_W - 1 : 0 ] = f_usedw[0 ][USED_W - 2 : 0 ] + f_usedw[1 ][USED_W - 2 : 0 ];
275
-
279
+ always_comb begin
280
+ f_usedw[0 ][USED_W - 1 : 0 ] = ( full[0 ] )?
281
+ ( 1 << (USED_W - 1 ) ):
282
+ ( { 1'b0 ,f_usedw_i[0 ][USED_W - 2 : 0 ]} );
283
+ f_usedw[1 ][USED_W - 1 : 0 ] = ( full[1 ] )?
284
+ ( 1 << (USED_W - 1 ) ):
285
+ ( { 1'b0 ,f_usedw_i[1 ][USED_W - 2 : 0 ]} );
286
+ usedw[USED_W : 0 ] = f_usedw[0 ][USED_W - 1 : 0 ] + f_usedw[1 ][USED_W - 1 : 0 ];
287
+ end
276
288
277
289
endmodule
278
290
0 commit comments