Skip to content

Commit 10da93f

Browse files
committed
Add depth status outputs to FIFOs
Signed-off-by: Alex Forencich <[email protected]>
1 parent 2be72bb commit 10da93f

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

rtl/axis_async_fifo.v

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
161165
localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0);
162166
localparam 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+
164179
reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}};
165180
reg [ADDR_WIDTH:0] wr_ptr_commit_reg = {ADDR_WIDTH+1{1'b0}};
166181
reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}};
167182
reg [ADDR_WIDTH:0] wr_ptr_sync_commit_reg = {ADDR_WIDTH+1{1'b0}};
168183
reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}};
169184
reg [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

171188
reg [ADDR_WIDTH:0] wr_ptr_temp;
172189
reg [ADDR_WIDTH:0] rd_ptr_temp;
@@ -241,6 +258,11 @@ reg good_frame_reg = 1'b0;
241258
reg m_drop_frame_reg = 1'b0;
242259
reg 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+
244266
reg overflow_sync1_reg = 1'b0;
245267
reg overflow_sync2_reg = 1'b0;
246268
reg 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

281303
wire 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;
283307
assign s_status_overflow = overflow_reg;
284308
assign s_status_bad_frame = bad_frame_reg;
285309
assign 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;
287313
assign m_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg;
288314
assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg;
289315
assign 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
462488
end
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
465498
always @(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
617650
end
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+
619659
generate
620660

621661
if (!OUTPUT_FIFO_ENABLE) begin

rtl/axis_async_fifo_adapter.v

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,13 @@ module axis_async_fifo_adapter #
119119
/*
120120
* Status
121121
*/
122+
output wire [$clog2(DEPTH):0] s_status_depth,
123+
output wire [$clog2(DEPTH):0] s_status_depth_commit,
122124
output wire s_status_overflow,
123125
output wire s_status_bad_frame,
124126
output wire s_status_good_frame,
127+
output wire [$clog2(DEPTH):0] m_status_depth,
128+
output wire [$clog2(DEPTH):0] m_status_depth_commit,
125129
output wire m_status_overflow,
126130
output wire m_status_bad_frame,
127131
output wire m_status_good_frame
@@ -350,9 +354,13 @@ fifo_inst (
350354
.m_axis_tdest(post_fifo_axis_tdest),
351355
.m_axis_tuser(post_fifo_axis_tuser),
352356
// Status
357+
.s_status_depth(s_status_depth),
358+
.s_status_depth_commit(s_status_depth_commit),
353359
.s_status_overflow(s_status_overflow),
354360
.s_status_bad_frame(s_status_bad_frame),
355361
.s_status_good_frame(s_status_good_frame),
362+
.m_status_depth(m_status_depth),
363+
.m_status_depth_commit(m_status_depth_commit),
356364
.m_status_overflow(m_status_overflow),
357365
.m_status_bad_frame(m_status_bad_frame),
358366
.m_status_good_frame(m_status_good_frame)

rtl/axis_fifo.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ module axis_fifo #
113113
/*
114114
* Status
115115
*/
116+
output wire [$clog2(DEPTH):0] status_depth,
117+
output wire [$clog2(DEPTH):0] status_depth_commit,
116118
output wire status_overflow,
117119
output wire status_bad_frame,
118120
output wire status_good_frame
@@ -178,6 +180,8 @@ wire full_wr = wr_ptr_reg == (wr_ptr_commit_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}});
178180

179181
reg drop_frame_reg = 1'b0;
180182
reg send_frame_reg = 1'b0;
183+
reg [ADDR_WIDTH:0] depth_reg = 0;
184+
reg [ADDR_WIDTH:0] depth_commit_reg = 0;
181185
reg overflow_reg = 1'b0;
182186
reg bad_frame_reg = 1'b0;
183187
reg good_frame_reg = 1'b0;
@@ -208,6 +212,8 @@ wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? m_axis[USER_OFFSET +:
208212

209213
wire pipe_ready;
210214

215+
assign status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {depth_reg, {$clog2(KEEP_WIDTH){1'b0}}} : depth_reg;
216+
assign status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0}}} : depth_commit_reg;
211217
assign status_overflow = overflow_reg;
212218
assign status_bad_frame = bad_frame_reg;
213219
assign status_good_frame = good_frame_reg;
@@ -272,6 +278,12 @@ always @(posedge clk) begin
272278
end
273279
end
274280

281+
// Status
282+
always @(posedge clk) begin
283+
depth_reg <= wr_ptr_reg - rd_ptr_reg;
284+
depth_commit_reg <= wr_ptr_commit_reg - rd_ptr_reg;
285+
end
286+
275287
// Read logic
276288
integer j;
277289

rtl/axis_fifo_adapter.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ module axis_fifo_adapter #
118118
/*
119119
* Status
120120
*/
121+
output wire [$clog2(DEPTH):0] status_depth,
122+
output wire [$clog2(DEPTH):0] status_depth_commit,
121123
output wire status_overflow,
122124
output wire status_bad_frame,
123125
output wire status_good_frame
@@ -343,6 +345,8 @@ fifo_inst (
343345
.m_axis_tdest(post_fifo_axis_tdest),
344346
.m_axis_tuser(post_fifo_axis_tuser),
345347
// Status
348+
.status_depth(status_depth),
349+
.status_depth_commit(status_depth_commit),
346350
.status_overflow(status_overflow),
347351
.status_bad_frame(status_bad_frame),
348352
.status_good_frame(status_good_frame)

0 commit comments

Comments
 (0)