mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Implement MARK_WHEN_FULL option in FIFOs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
6020d09214
commit
7823b916bf
@ -81,6 +81,10 @@ module axis_async_fifo #
|
|||||||
// When set, s_axis_tready is always asserted
|
// When set, s_axis_tready is always asserted
|
||||||
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
||||||
parameter DROP_WHEN_FULL = 0,
|
parameter DROP_WHEN_FULL = 0,
|
||||||
|
// Mark incoming frames as bad frames when full
|
||||||
|
// When set, s_axis_tready is always asserted
|
||||||
|
// Requires FRAME_FIFO to be clear
|
||||||
|
parameter MARK_WHEN_FULL = 0,
|
||||||
// Enable pause request input
|
// Enable pause request input
|
||||||
parameter PAUSE_ENABLE = 0,
|
parameter PAUSE_ENABLE = 0,
|
||||||
// Pause between frames
|
// Pause between frames
|
||||||
@ -164,10 +168,20 @@ initial begin
|
|||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin
|
if ((DROP_BAD_FRAME || MARK_WHEN_FULL) && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin
|
||||||
$error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)");
|
$error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (MARK_WHEN_FULL && FRAME_FIFO) begin
|
||||||
|
$error("Error: MARK_WHEN_FULL is not compatible with FRAME_FIFO (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (MARK_WHEN_FULL && !LAST_ENABLE) begin
|
||||||
|
$error("Error: MARK_WHEN_FULL set requires LAST_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
localparam KEEP_OFFSET = DATA_WIDTH;
|
localparam KEEP_OFFSET = DATA_WIDTH;
|
||||||
@ -262,6 +276,7 @@ reg s_frame_reg = 1'b0;
|
|||||||
reg m_frame_reg = 1'b0;
|
reg m_frame_reg = 1'b0;
|
||||||
|
|
||||||
reg drop_frame_reg = 1'b0;
|
reg drop_frame_reg = 1'b0;
|
||||||
|
reg mark_frame_reg = 1'b0;
|
||||||
reg send_frame_reg = 1'b0;
|
reg send_frame_reg = 1'b0;
|
||||||
reg overflow_reg = 1'b0;
|
reg overflow_reg = 1'b0;
|
||||||
reg bad_frame_reg = 1'b0;
|
reg bad_frame_reg = 1'b0;
|
||||||
@ -288,17 +303,17 @@ reg good_frame_sync2_reg = 1'b0;
|
|||||||
reg good_frame_sync3_reg = 1'b0;
|
reg good_frame_sync3_reg = 1'b0;
|
||||||
reg good_frame_sync4_reg = 1'b0;
|
reg good_frame_sync4_reg = 1'b0;
|
||||||
|
|
||||||
assign s_axis_tready = (FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : !full) && !s_rst_sync3_reg;
|
assign s_axis_tready = (FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : (!full || MARK_WHEN_FULL)) && !s_rst_sync3_reg;
|
||||||
|
|
||||||
wire [WIDTH-1:0] s_axis;
|
wire [WIDTH-1:0] s_axis;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
||||||
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
||||||
if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast;
|
if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast | mark_frame_reg;
|
||||||
if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid;
|
if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid;
|
||||||
if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest;
|
if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest;
|
||||||
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser;
|
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = mark_frame_reg ? USER_BAD_FRAME_VALUE : s_axis_tuser;
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1];
|
wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1];
|
||||||
@ -468,22 +483,48 @@ always @(posedge s_clk) begin
|
|||||||
end else begin
|
end else begin
|
||||||
// normal FIFO mode
|
// normal FIFO mode
|
||||||
if (s_axis_tready && s_axis_tvalid) begin
|
if (s_axis_tready && s_axis_tvalid) begin
|
||||||
// transfer in
|
|
||||||
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
|
||||||
if (drop_frame_reg && LAST_ENABLE) begin
|
if (drop_frame_reg && LAST_ENABLE) begin
|
||||||
// currently dropping frame
|
// currently dropping frame
|
||||||
// (only for frame transfers interrupted by sink reset)
|
|
||||||
if (s_axis_tlast) begin
|
if (s_axis_tlast) begin
|
||||||
|
// end of frame
|
||||||
|
if (!full && mark_frame_reg && MARK_WHEN_FULL) begin
|
||||||
|
// terminate marked frame
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
|
wr_ptr_temp = wr_ptr_reg + 1;
|
||||||
|
wr_ptr_reg <= wr_ptr_temp;
|
||||||
|
wr_ptr_commit_reg <= wr_ptr_temp;
|
||||||
|
wr_ptr_gray_reg <= bin2gray(wr_ptr_temp);
|
||||||
|
end
|
||||||
// end of frame, clear drop flag
|
// end of frame, clear drop flag
|
||||||
drop_frame_reg <= 1'b0;
|
drop_frame_reg <= 1'b0;
|
||||||
|
overflow_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end else if ((full || mark_frame_reg) && MARK_WHEN_FULL) begin
|
||||||
|
// full or marking frame
|
||||||
|
// drop frame; mark if this isn't the first cycle
|
||||||
|
drop_frame_reg <= 1'b1;
|
||||||
|
mark_frame_reg <= mark_frame_reg || s_frame_reg;
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
drop_frame_reg <= 1'b0;
|
||||||
|
overflow_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
// update pointers
|
// transfer in
|
||||||
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
wr_ptr_temp = wr_ptr_reg + 1;
|
wr_ptr_temp = wr_ptr_reg + 1;
|
||||||
wr_ptr_reg <= wr_ptr_temp;
|
wr_ptr_reg <= wr_ptr_temp;
|
||||||
wr_ptr_commit_reg <= wr_ptr_temp;
|
wr_ptr_commit_reg <= wr_ptr_temp;
|
||||||
wr_ptr_gray_reg <= bin2gray(wr_ptr_temp);
|
wr_ptr_gray_reg <= bin2gray(wr_ptr_temp);
|
||||||
end
|
end
|
||||||
|
end else if ((!full && !drop_frame_reg && mark_frame_reg) && MARK_WHEN_FULL) begin
|
||||||
|
// terminate marked frame
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
|
wr_ptr_temp = wr_ptr_reg + 1;
|
||||||
|
wr_ptr_reg <= wr_ptr_temp;
|
||||||
|
wr_ptr_commit_reg <= wr_ptr_temp;
|
||||||
|
wr_ptr_gray_reg <= bin2gray(wr_ptr_temp);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -509,6 +550,7 @@ always @(posedge s_clk) begin
|
|||||||
s_frame_reg <= 1'b0;
|
s_frame_reg <= 1'b0;
|
||||||
|
|
||||||
drop_frame_reg <= 1'b0;
|
drop_frame_reg <= 1'b0;
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
send_frame_reg <= 1'b0;
|
send_frame_reg <= 1'b0;
|
||||||
overflow_reg <= 1'b0;
|
overflow_reg <= 1'b0;
|
||||||
bad_frame_reg <= 1'b0;
|
bad_frame_reg <= 1'b0;
|
||||||
|
@ -86,6 +86,10 @@ module axis_async_fifo_adapter #
|
|||||||
// When set, s_axis_tready is always asserted
|
// When set, s_axis_tready is always asserted
|
||||||
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
||||||
parameter DROP_WHEN_FULL = 0,
|
parameter DROP_WHEN_FULL = 0,
|
||||||
|
// Mark incoming frames as bad frames when full
|
||||||
|
// When set, s_axis_tready is always asserted
|
||||||
|
// Requires FRAME_FIFO to be clear
|
||||||
|
parameter MARK_WHEN_FULL = 0,
|
||||||
// Enable pause request input
|
// Enable pause request input
|
||||||
parameter PAUSE_ENABLE = 0,
|
parameter PAUSE_ENABLE = 0,
|
||||||
// Pause between frames
|
// Pause between frames
|
||||||
@ -268,6 +272,7 @@ axis_async_fifo #(
|
|||||||
.DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME),
|
.DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME),
|
||||||
.DROP_BAD_FRAME(DROP_BAD_FRAME),
|
.DROP_BAD_FRAME(DROP_BAD_FRAME),
|
||||||
.DROP_WHEN_FULL(DROP_WHEN_FULL),
|
.DROP_WHEN_FULL(DROP_WHEN_FULL),
|
||||||
|
.MARK_WHEN_FULL(MARK_WHEN_FULL),
|
||||||
.PAUSE_ENABLE(PAUSE_ENABLE),
|
.PAUSE_ENABLE(PAUSE_ENABLE),
|
||||||
.FRAME_PAUSE(FRAME_PAUSE)
|
.FRAME_PAUSE(FRAME_PAUSE)
|
||||||
)
|
)
|
||||||
|
@ -81,6 +81,10 @@ module axis_fifo #
|
|||||||
// When set, s_axis_tready is always asserted
|
// When set, s_axis_tready is always asserted
|
||||||
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
||||||
parameter DROP_WHEN_FULL = 0,
|
parameter DROP_WHEN_FULL = 0,
|
||||||
|
// Mark incoming frames as bad frames when full
|
||||||
|
// When set, s_axis_tready is always asserted
|
||||||
|
// Requires FRAME_FIFO to be clear
|
||||||
|
parameter MARK_WHEN_FULL = 0,
|
||||||
// Enable pause request input
|
// Enable pause request input
|
||||||
parameter PAUSE_ENABLE = 0,
|
parameter PAUSE_ENABLE = 0,
|
||||||
// Pause between frames
|
// Pause between frames
|
||||||
@ -156,10 +160,20 @@ initial begin
|
|||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin
|
if ((DROP_BAD_FRAME || MARK_WHEN_FULL) && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin
|
||||||
$error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)");
|
$error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (MARK_WHEN_FULL && FRAME_FIFO) begin
|
||||||
|
$error("Error: MARK_WHEN_FULL is not compatible with FRAME_FIFO (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (MARK_WHEN_FULL && !LAST_ENABLE) begin
|
||||||
|
$error("Error: MARK_WHEN_FULL set requires LAST_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
localparam KEEP_OFFSET = DATA_WIDTH;
|
localparam KEEP_OFFSET = DATA_WIDTH;
|
||||||
@ -188,7 +202,10 @@ wire empty = wr_ptr_commit_reg == rd_ptr_reg;
|
|||||||
// overflow within packet
|
// overflow within packet
|
||||||
wire full_wr = wr_ptr_reg == (wr_ptr_commit_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}});
|
wire full_wr = wr_ptr_reg == (wr_ptr_commit_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}});
|
||||||
|
|
||||||
|
reg s_frame_reg = 1'b0;
|
||||||
|
|
||||||
reg drop_frame_reg = 1'b0;
|
reg drop_frame_reg = 1'b0;
|
||||||
|
reg mark_frame_reg = 1'b0;
|
||||||
reg send_frame_reg = 1'b0;
|
reg send_frame_reg = 1'b0;
|
||||||
reg [ADDR_WIDTH:0] depth_reg = 0;
|
reg [ADDR_WIDTH:0] depth_reg = 0;
|
||||||
reg [ADDR_WIDTH:0] depth_commit_reg = 0;
|
reg [ADDR_WIDTH:0] depth_commit_reg = 0;
|
||||||
@ -196,17 +213,17 @@ reg overflow_reg = 1'b0;
|
|||||||
reg bad_frame_reg = 1'b0;
|
reg bad_frame_reg = 1'b0;
|
||||||
reg good_frame_reg = 1'b0;
|
reg good_frame_reg = 1'b0;
|
||||||
|
|
||||||
assign s_axis_tready = FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : !full;
|
assign s_axis_tready = FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : (!full || MARK_WHEN_FULL);
|
||||||
|
|
||||||
wire [WIDTH-1:0] s_axis;
|
wire [WIDTH-1:0] s_axis;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata;
|
||||||
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep;
|
||||||
if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast;
|
if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast | mark_frame_reg;
|
||||||
if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid;
|
if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid;
|
||||||
if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest;
|
if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest;
|
||||||
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser;
|
if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = mark_frame_reg ? USER_BAD_FRAME_VALUE : s_axis_tuser;
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1];
|
wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1];
|
||||||
@ -245,6 +262,11 @@ always @(posedge clk) begin
|
|||||||
bad_frame_reg <= 1'b0;
|
bad_frame_reg <= 1'b0;
|
||||||
good_frame_reg <= 1'b0;
|
good_frame_reg <= 1'b0;
|
||||||
|
|
||||||
|
if (s_axis_tready && s_axis_tvalid && LAST_ENABLE) begin
|
||||||
|
// track input frame status
|
||||||
|
s_frame_reg <= !s_axis_tlast;
|
||||||
|
end
|
||||||
|
|
||||||
if (FRAME_FIFO) begin
|
if (FRAME_FIFO) begin
|
||||||
// frame FIFO mode
|
// frame FIFO mode
|
||||||
if (s_axis_tready && s_axis_tvalid) begin
|
if (s_axis_tready && s_axis_tvalid) begin
|
||||||
@ -286,7 +308,39 @@ always @(posedge clk) begin
|
|||||||
end else begin
|
end else begin
|
||||||
// normal FIFO mode
|
// normal FIFO mode
|
||||||
if (s_axis_tready && s_axis_tvalid) begin
|
if (s_axis_tready && s_axis_tvalid) begin
|
||||||
// transfer in
|
if (drop_frame_reg && MARK_WHEN_FULL) begin
|
||||||
|
// currently dropping frame
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
// end of frame
|
||||||
|
if (!full && mark_frame_reg) begin
|
||||||
|
// terminate marked frame
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
|
wr_ptr_reg <= wr_ptr_reg + 1;
|
||||||
|
wr_ptr_commit_reg <= wr_ptr_reg + 1;
|
||||||
|
end
|
||||||
|
// end of frame, clear drop flag
|
||||||
|
drop_frame_reg <= 1'b0;
|
||||||
|
overflow_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end else if ((full || mark_frame_reg) && MARK_WHEN_FULL) begin
|
||||||
|
// full or marking frame
|
||||||
|
// drop frame; mark if this isn't the first cycle
|
||||||
|
drop_frame_reg <= 1'b1;
|
||||||
|
mark_frame_reg <= mark_frame_reg || s_frame_reg;
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
drop_frame_reg <= 1'b0;
|
||||||
|
overflow_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
// transfer in
|
||||||
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
|
wr_ptr_reg <= wr_ptr_reg + 1;
|
||||||
|
wr_ptr_commit_reg <= wr_ptr_reg + 1;
|
||||||
|
end
|
||||||
|
end else if ((!full && !drop_frame_reg && mark_frame_reg) && MARK_WHEN_FULL) begin
|
||||||
|
// terminate marked frame
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis;
|
||||||
wr_ptr_reg <= wr_ptr_reg + 1;
|
wr_ptr_reg <= wr_ptr_reg + 1;
|
||||||
wr_ptr_commit_reg <= wr_ptr_reg + 1;
|
wr_ptr_commit_reg <= wr_ptr_reg + 1;
|
||||||
@ -297,7 +351,10 @@ always @(posedge clk) begin
|
|||||||
wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}};
|
wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}};
|
||||||
wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}};
|
wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}};
|
||||||
|
|
||||||
|
s_frame_reg <= 1'b0;
|
||||||
|
|
||||||
drop_frame_reg <= 1'b0;
|
drop_frame_reg <= 1'b0;
|
||||||
|
mark_frame_reg <= 1'b0;
|
||||||
send_frame_reg <= 1'b0;
|
send_frame_reg <= 1'b0;
|
||||||
overflow_reg <= 1'b0;
|
overflow_reg <= 1'b0;
|
||||||
bad_frame_reg <= 1'b0;
|
bad_frame_reg <= 1'b0;
|
||||||
|
@ -86,6 +86,10 @@ module axis_fifo_adapter #
|
|||||||
// When set, s_axis_tready is always asserted
|
// When set, s_axis_tready is always asserted
|
||||||
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
// Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set
|
||||||
parameter DROP_WHEN_FULL = 0,
|
parameter DROP_WHEN_FULL = 0,
|
||||||
|
// Mark incoming frames as bad frames when full
|
||||||
|
// When set, s_axis_tready is always asserted
|
||||||
|
// Requires FRAME_FIFO to be clear
|
||||||
|
parameter MARK_WHEN_FULL = 0,
|
||||||
// Enable pause request input
|
// Enable pause request input
|
||||||
parameter PAUSE_ENABLE = 0,
|
parameter PAUSE_ENABLE = 0,
|
||||||
// Pause between frames
|
// Pause between frames
|
||||||
@ -260,6 +264,7 @@ axis_fifo #(
|
|||||||
.DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME),
|
.DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME),
|
||||||
.DROP_BAD_FRAME(DROP_BAD_FRAME),
|
.DROP_BAD_FRAME(DROP_BAD_FRAME),
|
||||||
.DROP_WHEN_FULL(DROP_WHEN_FULL),
|
.DROP_WHEN_FULL(DROP_WHEN_FULL),
|
||||||
|
.MARK_WHEN_FULL(MARK_WHEN_FULL),
|
||||||
.PAUSE_ENABLE(PAUSE_ENABLE),
|
.PAUSE_ENABLE(PAUSE_ENABLE),
|
||||||
.FRAME_PAUSE(FRAME_PAUSE)
|
.FRAME_PAUSE(FRAME_PAUSE)
|
||||||
)
|
)
|
||||||
|
@ -51,6 +51,7 @@ export PARAM_USER_BAD_FRAME_MASK := 1
|
|||||||
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
||||||
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
||||||
export PARAM_DROP_WHEN_FULL := 0
|
export PARAM_DROP_WHEN_FULL := 0
|
||||||
|
export PARAM_MARK_WHEN_FULL := 0
|
||||||
export PARAM_PAUSE_ENABLE := 1
|
export PARAM_PAUSE_ENABLE := 1
|
||||||
export PARAM_FRAME_PAUSE := 1
|
export PARAM_FRAME_PAUSE := 1
|
||||||
|
|
||||||
|
@ -468,14 +468,14 @@ async def run_test_overflow(dut):
|
|||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.s_clk)
|
await RisingEdge(dut.s_clk)
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
assert tb.source.idle()
|
assert tb.source.idle()
|
||||||
else:
|
else:
|
||||||
assert not tb.source.idle()
|
assert not tb.source.idle()
|
||||||
|
|
||||||
tb.sink.pause = False
|
tb.sink.pause = False
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.s_clk)
|
await RisingEdge(dut.s_clk)
|
||||||
|
|
||||||
@ -484,9 +484,14 @@ async def run_test_overflow(dut):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
|
rx_count += 1
|
||||||
|
|
||||||
assert rx_count < count
|
assert rx_count < count
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -529,8 +534,11 @@ async def run_test_oversize(dut):
|
|||||||
else:
|
else:
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
if dut.MARK_WHEN_FULL.value:
|
||||||
assert not rx_frame.tuser
|
assert rx_frame.tuser
|
||||||
|
else:
|
||||||
|
assert rx_frame.tdata == test_data
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert tb.sink.empty()
|
assert tb.sink.empty()
|
||||||
|
|
||||||
@ -566,7 +574,7 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % id_count
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
cycles = 0
|
cycles = 0
|
||||||
while cycles < 100:
|
while cycles < 100:
|
||||||
cycles += 1
|
cycles += 1
|
||||||
@ -577,9 +585,14 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
test_frame = test_frames.pop(0)
|
test_frame = test_frames.pop(0)
|
||||||
if not rx_frame.tuser and rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
if rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
||||||
break
|
break
|
||||||
|
|
||||||
assert len(test_frames) < 512
|
assert len(test_frames) < 512
|
||||||
@ -653,13 +666,16 @@ rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("s_clk", "m_clk"), [(10, 10), (10, 11), (11, 10)])
|
@pytest.mark.parametrize(("s_clk", "m_clk"), [(10, 10), (10, 11), (11, 10)])
|
||||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame",
|
||||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0), (1, 1, 1, 1)])
|
"drop_when_full", "mark_when_full"),
|
||||||
|
[(0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (1, 1, 0, 0, 0), (1, 1, 1, 0, 0),
|
||||||
|
(1, 1, 1, 1, 0), (0, 0, 0, 0, 1)])
|
||||||
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
||||||
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
||||||
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
||||||
def test_axis_async_fifo(request, data_width, ram_pipeline, output_fifo,
|
def test_axis_async_fifo(request, data_width, ram_pipeline, output_fifo,
|
||||||
frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full, s_clk, m_clk):
|
frame_fifo, drop_oversize_frame, drop_bad_frame,
|
||||||
|
drop_when_full, mark_when_full, s_clk, m_clk):
|
||||||
|
|
||||||
dut = "axis_async_fifo"
|
dut = "axis_async_fifo"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
@ -690,6 +706,7 @@ def test_axis_async_fifo(request, data_width, ram_pipeline, output_fifo,
|
|||||||
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
||||||
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
||||||
parameters['DROP_WHEN_FULL'] = drop_when_full
|
parameters['DROP_WHEN_FULL'] = drop_when_full
|
||||||
|
parameters['MARK_WHEN_FULL'] = mark_when_full
|
||||||
parameters['PAUSE_ENABLE'] = 1
|
parameters['PAUSE_ENABLE'] = 1
|
||||||
parameters['FRAME_PAUSE'] = 1
|
parameters['FRAME_PAUSE'] = 1
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ export PARAM_USER_BAD_FRAME_MASK := 1
|
|||||||
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
||||||
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
||||||
export PARAM_DROP_WHEN_FULL := 0
|
export PARAM_DROP_WHEN_FULL := 0
|
||||||
|
export PARAM_MARK_WHEN_FULL := 0
|
||||||
export PARAM_PAUSE_ENABLE := 1
|
export PARAM_PAUSE_ENABLE := 1
|
||||||
export PARAM_FRAME_PAUSE := 1
|
export PARAM_FRAME_PAUSE := 1
|
||||||
|
|
||||||
|
@ -465,14 +465,14 @@ async def run_test_overflow(dut):
|
|||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.s_clk)
|
await RisingEdge(dut.s_clk)
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
assert tb.source.idle()
|
assert tb.source.idle()
|
||||||
else:
|
else:
|
||||||
assert not tb.source.idle()
|
assert not tb.source.idle()
|
||||||
|
|
||||||
tb.sink.pause = False
|
tb.sink.pause = False
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.s_clk)
|
await RisingEdge(dut.s_clk)
|
||||||
|
|
||||||
@ -481,9 +481,14 @@ async def run_test_overflow(dut):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
|
rx_count += 1
|
||||||
|
|
||||||
assert rx_count < count
|
assert rx_count < count
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -526,8 +531,11 @@ async def run_test_oversize(dut):
|
|||||||
else:
|
else:
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
if dut.MARK_WHEN_FULL.value:
|
||||||
assert not rx_frame.tuser
|
assert rx_frame.tuser
|
||||||
|
else:
|
||||||
|
assert rx_frame.tdata == test_data
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert tb.sink.empty()
|
assert tb.sink.empty()
|
||||||
|
|
||||||
@ -563,7 +571,7 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % id_count
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
cycles = 0
|
cycles = 0
|
||||||
while cycles < 100:
|
while cycles < 100:
|
||||||
cycles += 1
|
cycles += 1
|
||||||
@ -574,9 +582,14 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
test_frame = test_frames.pop(0)
|
test_frame = test_frames.pop(0)
|
||||||
if not rx_frame.tuser and rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
if rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
||||||
break
|
break
|
||||||
|
|
||||||
assert len(test_frames) < 512
|
assert len(test_frames) < 512
|
||||||
@ -649,11 +662,15 @@ tests_dir = os.path.dirname(__file__)
|
|||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame",
|
||||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0), (1, 1, 1, 1)])
|
"drop_when_full", "mark_when_full"),
|
||||||
|
[(0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (1, 1, 0, 0, 0), (1, 1, 1, 0, 0),
|
||||||
|
(1, 1, 1, 1, 0), (0, 0, 0, 0, 1)])
|
||||||
@pytest.mark.parametrize("m_data_width", [8, 16, 32])
|
@pytest.mark.parametrize("m_data_width", [8, 16, 32])
|
||||||
@pytest.mark.parametrize("s_data_width", [8, 16, 32])
|
@pytest.mark.parametrize("s_data_width", [8, 16, 32])
|
||||||
def test_axis_async_fifo_adapter(request, s_data_width, m_data_width, frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full):
|
def test_axis_async_fifo_adapter(request, s_data_width, m_data_width,
|
||||||
|
frame_fifo, drop_oversize_frame, drop_bad_frame,
|
||||||
|
drop_when_full, mark_when_full):
|
||||||
dut = "axis_async_fifo_adapter"
|
dut = "axis_async_fifo_adapter"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
toplevel = dut
|
toplevel = dut
|
||||||
@ -687,6 +704,7 @@ def test_axis_async_fifo_adapter(request, s_data_width, m_data_width, frame_fifo
|
|||||||
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
||||||
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
||||||
parameters['DROP_WHEN_FULL'] = drop_when_full
|
parameters['DROP_WHEN_FULL'] = drop_when_full
|
||||||
|
parameters['MARK_WHEN_FULL'] = mark_when_full
|
||||||
parameters['PAUSE_ENABLE'] = 1
|
parameters['PAUSE_ENABLE'] = 1
|
||||||
parameters['FRAME_PAUSE'] = 1
|
parameters['FRAME_PAUSE'] = 1
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ export PARAM_USER_BAD_FRAME_MASK := 1
|
|||||||
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
||||||
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
||||||
export PARAM_DROP_WHEN_FULL := 0
|
export PARAM_DROP_WHEN_FULL := 0
|
||||||
|
export PARAM_MARK_WHEN_FULL := 0
|
||||||
export PARAM_PAUSE_ENABLE := 1
|
export PARAM_PAUSE_ENABLE := 1
|
||||||
export PARAM_FRAME_PAUSE := 1
|
export PARAM_FRAME_PAUSE := 1
|
||||||
|
|
||||||
|
@ -254,14 +254,14 @@ async def run_test_overflow(dut):
|
|||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
assert tb.source.idle()
|
assert tb.source.idle()
|
||||||
else:
|
else:
|
||||||
assert not tb.source.idle()
|
assert not tb.source.idle()
|
||||||
|
|
||||||
tb.sink.pause = False
|
tb.sink.pause = False
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
@ -270,9 +270,14 @@ async def run_test_overflow(dut):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
|
rx_count += 1
|
||||||
|
|
||||||
assert rx_count < count
|
assert rx_count < count
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -315,8 +320,11 @@ async def run_test_oversize(dut):
|
|||||||
else:
|
else:
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
if dut.MARK_WHEN_FULL.value:
|
||||||
assert not rx_frame.tuser
|
assert rx_frame.tuser
|
||||||
|
else:
|
||||||
|
assert rx_frame.tdata == test_data
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert tb.sink.empty()
|
assert tb.sink.empty()
|
||||||
|
|
||||||
@ -352,7 +360,7 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % id_count
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
cycles = 0
|
cycles = 0
|
||||||
while cycles < 100:
|
while cycles < 100:
|
||||||
cycles += 1
|
cycles += 1
|
||||||
@ -363,11 +371,16 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert len(test_frames) > 0
|
assert len(test_frames) > 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
test_frame = test_frames.pop(0)
|
test_frame = test_frames.pop(0)
|
||||||
if not rx_frame.tuser and rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
if rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
||||||
break
|
break
|
||||||
|
|
||||||
assert len(test_frames) < 512
|
assert len(test_frames) < 512
|
||||||
@ -434,13 +447,16 @@ tests_dir = os.path.dirname(__file__)
|
|||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame",
|
||||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0), (1, 1, 1, 1)])
|
"drop_when_full", "mark_when_full"),
|
||||||
|
[(0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (1, 1, 0, 0, 0), (1, 1, 1, 0, 0),
|
||||||
|
(1, 1, 1, 1, 0), (0, 0, 0, 0, 1)])
|
||||||
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
@pytest.mark.parametrize(("ram_pipeline", "output_fifo"),
|
||||||
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
[(0, 0), (1, 0), (4, 0), (0, 1), (1, 1), (4, 1)])
|
||||||
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
@pytest.mark.parametrize("data_width", [8, 16, 32, 64])
|
||||||
def test_axis_fifo(request, data_width, ram_pipeline, output_fifo,
|
def test_axis_fifo(request, data_width, ram_pipeline, output_fifo,
|
||||||
frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full):
|
frame_fifo, drop_oversize_frame, drop_bad_frame,
|
||||||
|
drop_when_full, mark_when_full):
|
||||||
|
|
||||||
dut = "axis_fifo"
|
dut = "axis_fifo"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
@ -471,6 +487,7 @@ def test_axis_fifo(request, data_width, ram_pipeline, output_fifo,
|
|||||||
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
||||||
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
||||||
parameters['DROP_WHEN_FULL'] = drop_when_full
|
parameters['DROP_WHEN_FULL'] = drop_when_full
|
||||||
|
parameters['MARK_WHEN_FULL'] = mark_when_full
|
||||||
parameters['PAUSE_ENABLE'] = 1
|
parameters['PAUSE_ENABLE'] = 1
|
||||||
parameters['FRAME_PAUSE'] = 1
|
parameters['FRAME_PAUSE'] = 1
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ export PARAM_USER_BAD_FRAME_MASK := 1
|
|||||||
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
export PARAM_DROP_OVERSIZE_FRAME := $(PARAM_FRAME_FIFO)
|
||||||
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
export PARAM_DROP_BAD_FRAME := $(PARAM_DROP_OVERSIZE_FRAME)
|
||||||
export PARAM_DROP_WHEN_FULL := 0
|
export PARAM_DROP_WHEN_FULL := 0
|
||||||
|
export PARAM_MARK_WHEN_FULL := 0
|
||||||
export PARAM_PAUSE_ENABLE := 1
|
export PARAM_PAUSE_ENABLE := 1
|
||||||
export PARAM_FRAME_PAUSE := 1
|
export PARAM_FRAME_PAUSE := 1
|
||||||
|
|
||||||
|
@ -254,14 +254,14 @@ async def run_test_overflow(dut):
|
|||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
assert tb.source.idle()
|
assert tb.source.idle()
|
||||||
else:
|
else:
|
||||||
assert not tb.source.idle()
|
assert not tb.source.idle()
|
||||||
|
|
||||||
tb.sink.pause = False
|
tb.sink.pause = False
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
for k in range((depth//byte_lanes)*3):
|
for k in range((depth//byte_lanes)*3):
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
@ -270,9 +270,14 @@ async def run_test_overflow(dut):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
|
rx_count += 1
|
||||||
|
|
||||||
assert rx_count < count
|
assert rx_count < count
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -315,8 +320,11 @@ async def run_test_oversize(dut):
|
|||||||
else:
|
else:
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
if dut.MARK_WHEN_FULL.value:
|
||||||
assert not rx_frame.tuser
|
assert rx_frame.tuser
|
||||||
|
else:
|
||||||
|
assert rx_frame.tdata == test_data
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert tb.sink.empty()
|
assert tb.sink.empty()
|
||||||
|
|
||||||
@ -352,7 +360,7 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % id_count
|
||||||
|
|
||||||
if dut.DROP_WHEN_FULL.value:
|
if dut.DROP_WHEN_FULL.value or dut.MARK_WHEN_FULL.value:
|
||||||
cycles = 0
|
cycles = 0
|
||||||
while cycles < 100:
|
while cycles < 100:
|
||||||
cycles += 1
|
cycles += 1
|
||||||
@ -363,9 +371,14 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
while not tb.sink.empty():
|
while not tb.sink.empty():
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
|
if dut.MARK_WHEN_FULL.value and rx_frame.tuser:
|
||||||
|
continue
|
||||||
|
|
||||||
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
test_frame = test_frames.pop(0)
|
test_frame = test_frames.pop(0)
|
||||||
if not rx_frame.tuser and rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
if rx_frame.tid == test_frame.tid and rx_frame.tdest == test_frame.tdest and rx_frame.tdata == test_frame.tdata:
|
||||||
break
|
break
|
||||||
|
|
||||||
assert len(test_frames) < 512
|
assert len(test_frames) < 512
|
||||||
@ -432,11 +445,15 @@ tests_dir = os.path.dirname(__file__)
|
|||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"),
|
@pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame",
|
||||||
[(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0), (1, 1, 1, 1)])
|
"drop_when_full", "mark_when_full"),
|
||||||
|
[(0, 0, 0, 0, 0), (1, 0, 0, 0, 0), (1, 1, 0, 0, 0), (1, 1, 1, 0, 0),
|
||||||
|
(1, 1, 1, 1, 0), (0, 0, 0, 0, 1)])
|
||||||
@pytest.mark.parametrize("m_data_width", [8, 16, 32])
|
@pytest.mark.parametrize("m_data_width", [8, 16, 32])
|
||||||
@pytest.mark.parametrize("s_data_width", [8, 16, 32])
|
@pytest.mark.parametrize("s_data_width", [8, 16, 32])
|
||||||
def test_axis_fifo_adapter(request, s_data_width, m_data_width, frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full):
|
def test_axis_fifo_adapter(request, s_data_width, m_data_width,
|
||||||
|
frame_fifo, drop_oversize_frame, drop_bad_frame,
|
||||||
|
drop_when_full, mark_when_full):
|
||||||
dut = "axis_fifo_adapter"
|
dut = "axis_fifo_adapter"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
toplevel = dut
|
toplevel = dut
|
||||||
@ -470,6 +487,7 @@ def test_axis_fifo_adapter(request, s_data_width, m_data_width, frame_fifo, drop
|
|||||||
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
parameters['DROP_OVERSIZE_FRAME'] = drop_oversize_frame
|
||||||
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
parameters['DROP_BAD_FRAME'] = drop_bad_frame
|
||||||
parameters['DROP_WHEN_FULL'] = drop_when_full
|
parameters['DROP_WHEN_FULL'] = drop_when_full
|
||||||
|
parameters['MARK_WHEN_FULL'] = mark_when_full
|
||||||
parameters['PAUSE_ENABLE'] = 1
|
parameters['PAUSE_ENABLE'] = 1
|
||||||
parameters['FRAME_PAUSE'] = 1
|
parameters['FRAME_PAUSE'] = 1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user