diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index be237424..1c8aed29 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -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; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2a200f69..4d3fd6f7 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -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; diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index d037adfe..0890c898 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -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; diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index f55dcf01..e42a7693 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -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; diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 916b8735..c41570cb 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -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 diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 62e3ad7a..f9249e7d 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -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 diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 69ae4851..d0a13fb9 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -67,7 +67,8 @@ end axis_frame_fifo #( .ADDR_WIDTH(9), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index c7048e3f..30d87298 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -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),