@@ -124,6 +124,7 @@ localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0);
124
124
reg [ADDR_WIDTH:0 ] wr_ptr_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_next;
125
125
reg [ADDR_WIDTH:0 ] wr_ptr_cur_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_cur_next;
126
126
reg [ADDR_WIDTH:0 ] wr_ptr_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_gray_next;
127
+ reg [ADDR_WIDTH:0 ] wr_ptr_cur_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_cur_gray_next;
127
128
reg [ADDR_WIDTH:0 ] wr_addr_reg = {ADDR_WIDTH+ 1 {1'b0 }};
128
129
reg [ADDR_WIDTH:0 ] rd_ptr_reg = {ADDR_WIDTH+ 1 {1'b0 }}, rd_ptr_next;
129
130
reg [ADDR_WIDTH:0 ] rd_ptr_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }}, rd_ptr_gray_next;
@@ -155,11 +156,14 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
155
156
wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) &&
156
157
(wr_ptr_gray_reg[ADDR_WIDTH- 1 ] != rd_ptr_gray_sync2_reg[ADDR_WIDTH- 1 ]) &&
157
158
(wr_ptr_gray_reg[ADDR_WIDTH- 2 :0 ] == rd_ptr_gray_sync2_reg[ADDR_WIDTH- 2 :0 ]));
159
+ wire full_cur = ((wr_ptr_cur_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) &&
160
+ (wr_ptr_cur_gray_reg[ADDR_WIDTH- 1 ] != rd_ptr_gray_sync2_reg[ADDR_WIDTH- 1 ]) &&
161
+ (wr_ptr_cur_gray_reg[ADDR_WIDTH- 2 :0 ] == rd_ptr_gray_sync2_reg[ADDR_WIDTH- 2 :0 ]));
158
162
// empty when pointers match exactly
159
163
wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg;
160
164
// overflow within packet
161
- wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) &&
162
- (wr_ptr_reg[ADDR_WIDTH- 1 :0 ] == wr_ptr_cur_reg[ADDR_WIDTH- 1 :0 ]));
165
+ wire full_wr = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) &&
166
+ (wr_ptr_reg[ADDR_WIDTH- 1 :0 ] == wr_ptr_cur_reg[ADDR_WIDTH- 1 :0 ]));
163
167
164
168
// control signals
165
169
reg write;
@@ -184,7 +188,7 @@ reg good_frame_sync2_reg = 1'b0;
184
188
reg good_frame_sync3_reg = 1'b0 ;
185
189
reg good_frame_sync4_reg = 1'b0 ;
186
190
187
- assign s_axis_tready = (! full || DROP_WHEN_FULL) && ! s_rst_sync3_reg;
191
+ assign s_axis_tready = (FRAME_FIFO ? ( ! full_cur || full_wr || DROP_WHEN_FULL) : ! full ) && ! s_rst_sync3_reg;
188
192
189
193
generate
190
194
assign s_axis[DATA_WIDTH- 1 :0 ] = s_axis_tdata;
@@ -249,41 +253,42 @@ always @* begin
249
253
wr_ptr_next = wr_ptr_reg;
250
254
wr_ptr_cur_next = wr_ptr_cur_reg;
251
255
wr_ptr_gray_next = wr_ptr_gray_reg;
252
-
253
- if (s_axis_tvalid) begin
254
- // input data valid
255
- if (! full || DROP_WHEN_FULL) begin
256
- // not full, perform write
257
- if (! FRAME_FIFO) begin
258
- // normal FIFO mode
259
- write = 1'b1 ;
260
- wr_ptr_next = wr_ptr_reg + 1 ;
261
- wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1 );
262
- end else if (full || full_cur || drop_frame_reg) begin
263
- // full, packet overflow, or currently dropping frame
264
- // drop frame
265
- drop_frame_next = 1'b1 ;
266
- if (s_axis_tlast) begin
267
- // end of frame, reset write pointer
256
+ wr_ptr_cur_gray_next = wr_ptr_cur_gray_reg;
257
+
258
+ if (s_axis_tready && s_axis_tvalid) begin
259
+ // transfer in
260
+ if (! FRAME_FIFO) begin
261
+ // normal FIFO mode
262
+ write = 1'b1 ;
263
+ wr_ptr_next = wr_ptr_reg + 1 ;
264
+ wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1 );
265
+ end else if (full_cur || full_wr || drop_frame_reg) begin
266
+ // full, packet overflow, or currently dropping frame
267
+ // drop frame
268
+ drop_frame_next = 1'b1 ;
269
+ if (s_axis_tlast) begin
270
+ // end of frame, reset write pointer
271
+ wr_ptr_cur_next = wr_ptr_reg;
272
+ wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1 );
273
+ drop_frame_next = 1'b0 ;
274
+ overflow_next = 1'b1 ;
275
+ end
276
+ end else begin
277
+ write = 1'b1 ;
278
+ wr_ptr_cur_next = wr_ptr_cur_reg + 1 ;
279
+ wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1 );
280
+ if (s_axis_tlast) begin
281
+ // end of frame
282
+ if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin
283
+ // bad packet, reset write pointer
268
284
wr_ptr_cur_next = wr_ptr_reg;
269
- drop_frame_next = 1'b0 ;
270
- overflow_next = 1'b1 ;
271
- end
272
- end else begin
273
- write = 1'b1 ;
274
- wr_ptr_cur_next = wr_ptr_cur_reg + 1 ;
275
- if (s_axis_tlast) begin
276
- // end of frame
277
- if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin
278
- // bad packet, reset write pointer
279
- wr_ptr_cur_next = wr_ptr_reg;
280
- bad_frame_next = 1'b1 ;
281
- end else begin
282
- // good packet, update write pointer
283
- wr_ptr_next = wr_ptr_cur_reg + 1 ;
284
- wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1 );
285
- good_frame_next = 1'b1 ;
286
- end
285
+ wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1 );
286
+ bad_frame_next = 1'b1 ;
287
+ end else begin
288
+ // good packet, update write pointer
289
+ wr_ptr_next = wr_ptr_cur_reg + 1 ;
290
+ wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1 );
291
+ good_frame_next = 1'b1 ;
287
292
end
288
293
end
289
294
end
@@ -295,6 +300,7 @@ always @(posedge s_clk) begin
295
300
wr_ptr_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
296
301
wr_ptr_cur_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
297
302
wr_ptr_gray_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
303
+ wr_ptr_cur_gray_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
298
304
299
305
drop_frame_reg <= 1'b0 ;
300
306
overflow_reg <= 1'b0 ;
@@ -304,6 +310,7 @@ always @(posedge s_clk) begin
304
310
wr_ptr_reg <= wr_ptr_next;
305
311
wr_ptr_cur_reg <= wr_ptr_cur_next;
306
312
wr_ptr_gray_reg <= wr_ptr_gray_next;
313
+ wr_ptr_cur_gray_reg <= wr_ptr_cur_gray_next;
307
314
308
315
drop_frame_reg <= drop_frame_next;
309
316
overflow_reg <= overflow_next;
0 commit comments