@@ -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_sync_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_sync_gray_next;
127
128
reg [ADDR_WIDTH:0 ] wr_ptr_cur_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }}, wr_ptr_cur_gray_next;
128
129
reg [ADDR_WIDTH:0 ] wr_addr_reg = {ADDR_WIDTH+ 1 {1'b0 }};
129
130
reg [ADDR_WIDTH:0 ] rd_ptr_reg = {ADDR_WIDTH+ 1 {1'b0 }}, rd_ptr_next;
@@ -135,6 +136,14 @@ reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}};
135
136
reg [ADDR_WIDTH:0 ] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+ 1 {1'b0 }};
136
137
reg [ADDR_WIDTH:0 ] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+ 1 {1'b0 }};
137
138
139
+ reg wr_ptr_update_valid_reg = 1'b0 , wr_ptr_update_valid_next;
140
+ reg wr_ptr_update_reg = 1'b0 , wr_ptr_update_next;
141
+ reg wr_ptr_update_sync1_reg = 1'b0 ;
142
+ reg wr_ptr_update_sync2_reg = 1'b0 ;
143
+ reg wr_ptr_update_sync3_reg = 1'b0 ;
144
+ reg wr_ptr_update_ack_sync1_reg = 1'b0 ;
145
+ reg wr_ptr_update_ack_sync2_reg = 1'b0 ;
146
+
138
147
reg s_rst_sync1_reg = 1'b1 ;
139
148
reg s_rst_sync2_reg = 1'b1 ;
140
149
reg s_rst_sync3_reg = 1'b1 ;
@@ -160,7 +169,7 @@ wire full_cur = ((wr_ptr_cur_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_
160
169
(wr_ptr_cur_gray_reg[ADDR_WIDTH- 1 ] != rd_ptr_gray_sync2_reg[ADDR_WIDTH- 1 ]) &&
161
170
(wr_ptr_cur_gray_reg[ADDR_WIDTH- 2 :0 ] == rd_ptr_gray_sync2_reg[ADDR_WIDTH- 2 :0 ]));
162
171
// empty when pointers match exactly
163
- wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg;
172
+ wire empty = rd_ptr_gray_reg == (FRAME_FIFO ? wr_ptr_gray_sync1_reg : wr_ptr_gray_sync2_reg) ;
164
173
// overflow within packet
165
174
wire full_wr = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) &&
166
175
(wr_ptr_reg[ADDR_WIDTH- 1 :0 ] == wr_ptr_cur_reg[ADDR_WIDTH- 1 :0 ]));
@@ -253,8 +262,22 @@ always @* begin
253
262
wr_ptr_next = wr_ptr_reg;
254
263
wr_ptr_cur_next = wr_ptr_cur_reg;
255
264
wr_ptr_gray_next = wr_ptr_gray_reg;
265
+ wr_ptr_sync_gray_next = wr_ptr_sync_gray_reg;
256
266
wr_ptr_cur_gray_next = wr_ptr_cur_gray_reg;
257
267
268
+ wr_ptr_update_valid_next = wr_ptr_update_valid_reg;
269
+ wr_ptr_update_next = wr_ptr_update_reg;
270
+
271
+ if (FRAME_FIFO && wr_ptr_update_valid_reg) begin
272
+ // have updated pointer to sync
273
+ if (wr_ptr_update_next == wr_ptr_update_ack_sync2_reg) begin
274
+ // no sync in progress; sync update
275
+ wr_ptr_update_valid_next = 1'b0 ;
276
+ wr_ptr_sync_gray_next = wr_ptr_gray_reg;
277
+ wr_ptr_update_next = ! wr_ptr_update_ack_sync2_reg;
278
+ end
279
+ end
280
+
258
281
if (s_axis_tready && s_axis_tvalid) begin
259
282
// transfer in
260
283
if (! FRAME_FIFO) begin
@@ -288,6 +311,17 @@ always @* begin
288
311
// good packet, update write pointer
289
312
wr_ptr_next = wr_ptr_cur_reg + 1 ;
290
313
wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1 );
314
+
315
+ if (wr_ptr_update_next == wr_ptr_update_ack_sync2_reg) begin
316
+ // no sync in progress; sync update
317
+ wr_ptr_update_valid_next = 1'b0 ;
318
+ wr_ptr_sync_gray_next = wr_ptr_gray_next;
319
+ wr_ptr_update_next = ! wr_ptr_update_ack_sync2_reg;
320
+ end else begin
321
+ // sync in progress; flag it for later
322
+ wr_ptr_update_valid_next = 1'b1 ;
323
+ end
324
+
291
325
good_frame_next = 1'b1 ;
292
326
end
293
327
end
@@ -300,8 +334,12 @@ always @(posedge s_clk) begin
300
334
wr_ptr_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
301
335
wr_ptr_cur_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
302
336
wr_ptr_gray_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
337
+ wr_ptr_sync_gray_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
303
338
wr_ptr_cur_gray_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
304
339
340
+ wr_ptr_update_valid_reg <= 1'b0 ;
341
+ wr_ptr_update_reg <= 1'b0 ;
342
+
305
343
drop_frame_reg <= 1'b0 ;
306
344
overflow_reg <= 1'b0 ;
307
345
bad_frame_reg <= 1'b0 ;
@@ -310,8 +348,12 @@ always @(posedge s_clk) begin
310
348
wr_ptr_reg <= wr_ptr_next;
311
349
wr_ptr_cur_reg <= wr_ptr_cur_next;
312
350
wr_ptr_gray_reg <= wr_ptr_gray_next;
351
+ wr_ptr_sync_gray_reg <= wr_ptr_sync_gray_next;
313
352
wr_ptr_cur_gray_reg <= wr_ptr_cur_gray_next;
314
353
354
+ wr_ptr_update_valid_reg <= wr_ptr_update_valid_next;
355
+ wr_ptr_update_reg <= wr_ptr_update_next;
356
+
315
357
drop_frame_reg <= drop_frame_next;
316
358
overflow_reg <= overflow_next;
317
359
bad_frame_reg <= bad_frame_next;
@@ -334,19 +376,33 @@ always @(posedge s_clk) begin
334
376
if (s_rst_sync3_reg) begin
335
377
rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
336
378
rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
379
+ wr_ptr_update_ack_sync1_reg <= 1'b0 ;
380
+ wr_ptr_update_ack_sync2_reg <= 1'b0 ;
337
381
end else begin
338
382
rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg;
339
383
rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg;
384
+ wr_ptr_update_ack_sync1_reg <= wr_ptr_update_sync3_reg;
385
+ wr_ptr_update_ack_sync2_reg <= wr_ptr_update_ack_sync1_reg;
340
386
end
341
387
end
342
388
343
389
always @(posedge m_clk) begin
344
390
if (m_rst_sync3_reg) begin
345
391
wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
346
392
wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+ 1 {1'b0 }};
393
+ wr_ptr_update_sync1_reg <= 1'b0 ;
394
+ wr_ptr_update_sync2_reg <= 1'b0 ;
395
+ wr_ptr_update_sync3_reg <= 1'b0 ;
347
396
end else begin
348
- wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg;
397
+ if (! FRAME_FIFO) begin
398
+ wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg;
399
+ end else if (wr_ptr_update_sync2_reg ^ wr_ptr_update_sync3_reg) begin
400
+ wr_ptr_gray_sync1_reg <= wr_ptr_sync_gray_reg;
401
+ end
349
402
wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg;
403
+ wr_ptr_update_sync1_reg <= wr_ptr_update_reg;
404
+ wr_ptr_update_sync2_reg <= wr_ptr_update_sync1_reg;
405
+ wr_ptr_update_sync3_reg <= wr_ptr_update_sync2_reg;
350
406
end
351
407
end
352
408
0 commit comments