Improve frame drop logic in frame FIFOs, add DROP_WHEN_FULL option to disable input tready signal

This commit is contained in:
Alex Forencich 2015-02-28 19:32:08 -08:00
parent 8582ab0749
commit 6e2eda256d
8 changed files with 44 additions and 20 deletions

View File

@ -32,7 +32,8 @@ THE SOFTWARE.
module axis_async_frame_fifo #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 8
parameter DATA_WIDTH = 8,
parameter DROP_WHEN_FULL = 0
)
(
/*
@ -70,6 +71,8 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}};
reg drop_frame = 1'b0;
reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
@ -92,12 +95,12 @@ wire empty = rd_ptr_gray == wr_ptr_gray_sync3;
wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) &&
(wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0]));
wire write = input_axis_tvalid & ~full;
wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL);
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign input_axis_tready = (~full | DROP_WHEN_FULL);
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
@ -105,10 +108,12 @@ always @(posedge input_clk or posedge input_rst) begin
if (input_rst) begin
wr_ptr <= 0;
end else if (write) begin
if (full_cur) begin
if (full | full_cur | drop_frame) begin
// buffer full, hold current pointer, drop packet at end
drop_frame <= 1;
if (input_axis_tlast) begin
wr_ptr_cur <= wr_ptr;
drop_frame <= 0;
end
end else begin
mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in;

View File

@ -33,7 +33,8 @@ module axis_async_frame_fifo_64 #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter DROP_WHEN_FULL = 0
)
(
/*
@ -73,6 +74,8 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}};
reg drop_frame = 1'b0;
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
@ -95,12 +98,12 @@ wire empty = rd_ptr_gray == wr_ptr_gray_sync3;
wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) &&
(wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0]));
wire write = input_axis_tvalid & ~full;
wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL);
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign input_axis_tready = (~full | DROP_WHEN_FULL);
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
@ -108,10 +111,12 @@ always @(posedge input_clk or posedge input_rst) begin
if (input_rst) begin
wr_ptr <= 0;
end else if (write) begin
if (full_cur) begin
if (full | full_cur | drop_frame) begin
// buffer full, hold current pointer, drop packet at end
drop_frame <= 1;
if (input_axis_tlast) begin
wr_ptr_cur <= wr_ptr;
drop_frame <= 0;
end
end else begin
mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in;

View File

@ -32,7 +32,8 @@ THE SOFTWARE.
module axis_frame_fifo #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 8
parameter DATA_WIDTH = 8,
parameter DROP_WHEN_FULL = 0
)
(
input wire clk,
@ -60,6 +61,8 @@ reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}};
reg drop_frame = 1'b0;
reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
@ -80,12 +83,12 @@ wire empty = wr_ptr == rd_ptr;
wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) &&
(wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0]));
wire write = input_axis_tvalid & ~full;
wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL);
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign input_axis_tready = (~full | DROP_WHEN_FULL);
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
@ -93,10 +96,12 @@ always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
end else if (write) begin
if (full_cur) begin
if (full | full_cur | drop_frame) begin
// buffer full, hold current pointer, drop packet at end
drop_frame <= 1;
if (input_axis_tlast) begin
wr_ptr_cur <= wr_ptr;
drop_frame <= 0;
end
end else begin
mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in;

View File

@ -33,7 +33,8 @@ module axis_frame_fifo_64 #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter DROP_WHEN_FULL = 0
)
(
input wire clk,
@ -63,6 +64,8 @@ reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}};
reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}};
reg drop_frame = 1'b0;
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
@ -83,12 +86,12 @@ wire empty = wr_ptr == rd_ptr;
wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) &&
(wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0]));
wire write = input_axis_tvalid & ~full;
wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL);
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign input_axis_tready = (~full | DROP_WHEN_FULL);
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
@ -96,10 +99,12 @@ always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
end else if (write) begin
if (full_cur) begin
if (full | full_cur | drop_frame) begin
// buffer full, hold current pointer, drop packet at end
drop_frame <= 1;
if (input_axis_tlast) begin
wr_ptr_cur <= wr_ptr;
drop_frame <= 0;
end
end else begin
mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in;

View File

@ -71,7 +71,8 @@ end
axis_async_frame_fifo #(
.ADDR_WIDTH(9),
.DATA_WIDTH(8)
.DATA_WIDTH(8),
.DROP_WHEN_FULL(0)
)
UUT (
// AXI input

View File

@ -75,7 +75,8 @@ end
axis_async_frame_fifo_64 #(
.ADDR_WIDTH(6),
.DATA_WIDTH(64)
.DATA_WIDTH(64),
.DROP_WHEN_FULL(0)
)
UUT (
// AXI input

View File

@ -67,7 +67,8 @@ end
axis_frame_fifo #(
.ADDR_WIDTH(9),
.DATA_WIDTH(8)
.DATA_WIDTH(8),
.DROP_WHEN_FULL(0)
)
UUT (
.clk(clk),

View File

@ -71,7 +71,8 @@ end
axis_frame_fifo_64 #(
.ADDR_WIDTH(6),
.DATA_WIDTH(64)
.DATA_WIDTH(64),
.DROP_WHEN_FULL(0)
)
UUT (
.clk(clk),