@@ -114,9 +114,13 @@ module axis_async_fifo #
114114 /*
115115 * Status
116116 */
117+ output wire [$clog2(DEPTH):0 ] s_status_depth,
118+ output wire [$clog2(DEPTH):0 ] s_status_depth_commit,
117119 output wire s_status_overflow,
118120 output wire s_status_bad_frame,
119121 output wire s_status_good_frame,
122+ output wire [$clog2(DEPTH):0 ] m_status_depth,
123+ output wire [$clog2(DEPTH):0 ] m_status_depth_commit,
120124 output wire m_status_overflow,
121125 output wire m_status_bad_frame,
122126 output wire m_status_good_frame
@@ -161,12 +165,25 @@ localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0);
161165localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0 );
162166localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0 );
163167
168+ function [ADDR_WIDTH:0 ] bin2gray(input [ADDR_WIDTH:0 ] b);
169+ bin2gray = b ^ (b >> 1 );
170+ endfunction
171+
172+ function [ADDR_WIDTH:0 ] gray2bin(input [ADDR_WIDTH:0 ] g);
173+ integer i;
174+ for (i = 0 ; i <= ADDR_WIDTH; i = i + 1 ) begin
175+ gray2bin[i] = ^(g >> i);
176+ end
177+ endfunction
178+
164179reg [ADDR_WIDTH:0 ] wr_ptr_reg = {ADDR_WIDTH+ 1 {1'b0 }};
165180reg [ADDR_WIDTH:0 ] wr_ptr_commit_reg = {ADDR_WIDTH+ 1 {1'b0 }};
166181reg [ADDR_WIDTH:0 ] wr_ptr_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }};
167182reg [ADDR_WIDTH:0 ] wr_ptr_sync_commit_reg = {ADDR_WIDTH+ 1 {1'b0 }};
168183reg [ADDR_WIDTH:0 ] rd_ptr_reg = {ADDR_WIDTH+ 1 {1'b0 }};
169184reg [ADDR_WIDTH:0 ] rd_ptr_gray_reg = {ADDR_WIDTH+ 1 {1'b0 }};
185+ reg [ADDR_WIDTH:0 ] wr_ptr_conv_reg = {ADDR_WIDTH+ 1 {1'b0 }};
186+ reg [ADDR_WIDTH:0 ] rd_ptr_conv_reg = {ADDR_WIDTH+ 1 {1'b0 }};
170187
171188reg [ADDR_WIDTH:0 ] wr_ptr_temp;
172189reg [ADDR_WIDTH:0 ] rd_ptr_temp;
@@ -241,6 +258,11 @@ reg good_frame_reg = 1'b0;
241258reg m_drop_frame_reg = 1'b0 ;
242259reg m_terminate_frame_reg = 1'b0 ;
243260
261+ reg [ADDR_WIDTH:0 ] s_depth_reg = 0 ;
262+ reg [ADDR_WIDTH:0 ] s_depth_commit_reg = 0 ;
263+ reg [ADDR_WIDTH:0 ] m_depth_reg = 0 ;
264+ reg [ADDR_WIDTH:0 ] m_depth_commit_reg = 0 ;
265+
244266reg overflow_sync1_reg = 1'b0 ;
245267reg overflow_sync2_reg = 1'b0 ;
246268reg overflow_sync3_reg = 1'b0 ;
@@ -280,10 +302,14 @@ wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? (m_terminate_frame_reg
280302
281303wire pipe_ready;
282304
305+ assign s_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1 ) ? {s_depth_reg, {$clog2(KEEP_WIDTH){1'b0 }}} : s_depth_reg;
306+ assign s_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1 ) ? {s_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0 }}} : s_depth_commit_reg;
283307assign s_status_overflow = overflow_reg;
284308assign s_status_bad_frame = bad_frame_reg;
285309assign s_status_good_frame = good_frame_reg;
286310
311+ assign m_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1 ) ? {m_depth_reg, {$clog2(KEEP_WIDTH){1'b0 }}} : m_depth_reg;
312+ assign m_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1 ) ? {m_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0 }}} : m_depth_commit_reg;
287313assign m_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg;
288314assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg;
289315assign m_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg;
@@ -363,7 +389,7 @@ always @(posedge s_clk) begin
363389 wr_ptr_temp = wr_ptr_reg + 1 ;
364390 wr_ptr_reg <= wr_ptr_temp;
365391 wr_ptr_commit_reg <= wr_ptr_temp;
366- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
392+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
367393 end
368394 end else if ((full && DROP_WHEN_FULL) || (full_wr && DROP_OVERSIZE_FRAME) || drop_frame_reg) begin
369395 // full, packet overflow, or currently dropping frame
@@ -373,30 +399,30 @@ always @(posedge s_clk) begin
373399 // end of frame, reset write pointer
374400 wr_ptr_temp = wr_ptr_commit_reg;
375401 wr_ptr_reg <= wr_ptr_temp;
376- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
402+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
377403 drop_frame_reg <= 1'b0 ;
378404 overflow_reg <= 1'b1 ;
379405 end
380406 end else begin
381407 mem[wr_ptr_reg[ADDR_WIDTH- 1 :0 ]] <= s_axis;
382408 wr_ptr_temp = wr_ptr_reg + 1 ;
383409 wr_ptr_reg <= wr_ptr_temp;
384- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
410+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
385411 if (s_axis_tlast || (! DROP_OVERSIZE_FRAME && (full_wr || send_frame_reg))) begin
386412 // end of frame or send frame
387413 send_frame_reg <= ! s_axis_tlast;
388414 if (s_axis_tlast && DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~ (s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin
389415 // bad packet, reset write pointer
390416 wr_ptr_temp = wr_ptr_commit_reg;
391417 wr_ptr_reg <= wr_ptr_temp;
392- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
418+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
393419 bad_frame_reg <= 1'b1 ;
394420 end else begin
395421 // good packet or packet overflow, update write pointer
396422 wr_ptr_temp = wr_ptr_reg + 1 ;
397423 wr_ptr_reg <= wr_ptr_temp;
398424 wr_ptr_commit_reg <= wr_ptr_temp;
399- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
425+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
400426
401427 if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin
402428 // no sync in progress; sync update
@@ -419,7 +445,7 @@ always @(posedge s_clk) begin
419445 wr_ptr_temp = wr_ptr_reg;
420446 wr_ptr_reg <= wr_ptr_temp;
421447 wr_ptr_commit_reg <= wr_ptr_temp;
422- wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1 );
448+ wr_ptr_gray_reg <= bin2gray (wr_ptr_temp);
423449
424450 if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin
425451 // no sync in progress; sync update
@@ -461,6 +487,13 @@ always @(posedge s_clk) begin
461487 end
462488end
463489
490+ // Write-side status
491+ always @(posedge s_clk) begin
492+ rd_ptr_conv_reg <= gray2bin(rd_ptr_gray_sync2_reg);
493+ s_depth_reg <= wr_ptr_reg - rd_ptr_conv_reg;
494+ s_depth_commit_reg <= wr_ptr_commit_reg - rd_ptr_conv_reg;
495+ end
496+
464497// pointer synchronization
465498always @(posedge s_clk) begin
466499 rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg;
@@ -616,6 +649,13 @@ always @(posedge m_clk) begin
616649 end
617650end
618651
652+ // Read-side status
653+ always @(posedge m_clk) begin
654+ wr_ptr_conv_reg <= gray2bin(wr_ptr_gray_sync2_reg);
655+ m_depth_reg <= wr_ptr_conv_reg - rd_ptr_reg;
656+ m_depth_commit_reg <= FRAME_FIFO ? wr_ptr_commit_sync_reg - rd_ptr_reg : wr_ptr_conv_reg - rd_ptr_reg;
657+ end
658+
619659generate
620660
621661if (! OUTPUT_FIFO_ENABLE) begin
0 commit comments