Replay buffered TX streamer: Fix gaps in TX

Gaps in transmission were seen when using the replay buffered TX
streamer caused by the Replay block setting the end of burst flag at the
end of every send() call.  This fix adds a flag to the Replay block play
command register to avoid setting the end of burst flag and modifies the
replay buffered TX streamer to use the flag based on the metadata passed
in to the send() call.

Signed-off-by: michael-west <michael.west@ettus.com>


Original-commit: 2419f405775934efa517e025929356ef0a0d181e
This commit is contained in:
michael-west
2023-04-06 15:34:46 -05:00
committed by Aki Tomita
parent a90444c784
commit 0971ae69cb
2 changed files with 19 additions and 6 deletions
@@ -149,7 +149,7 @@ module axis_replay #(
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
localparam [REG_MAJOR_LEN-1:0] COMPAT_MAJOR = 1; localparam [REG_MAJOR_LEN-1:0] COMPAT_MAJOR = 1;
localparam [REG_MINOR_LEN-1:0] COMPAT_MINOR = 1; localparam [REG_MINOR_LEN-1:0] COMPAT_MINOR = 2;
localparam [REG_ITEM_SIZE_LEN-1:0] DEFAULT_ITEM_SIZE = 4; // 4 bytes for sc16 localparam [REG_ITEM_SIZE_LEN-1:0] DEFAULT_ITEM_SIZE = 4; // 4 bytes for sc16
@@ -248,6 +248,7 @@ module axis_replay #(
reg [TIME_W-1:0] reg_play_cmd_time; reg [TIME_W-1:0] reg_play_cmd_time;
reg [CMD_W-1:0] reg_play_cmd; reg [CMD_W-1:0] reg_play_cmd;
reg reg_play_cmd_timed; reg reg_play_cmd_timed;
reg reg_play_cmd_no_eob;
reg reg_play_cmd_valid; reg reg_play_cmd_valid;
wire reg_play_cmd_ready; wire reg_play_cmd_ready;
reg play_cmd_stop; reg play_cmd_stop;
@@ -294,6 +295,7 @@ module axis_replay #(
clear_cmd_fifo <= 0; clear_cmd_fifo <= 0;
reg_play_cmd <= 'bX; reg_play_cmd <= 'bX;
reg_play_cmd_timed <= 'bX; reg_play_cmd_timed <= 'bX;
reg_play_cmd_no_eob <= 'bX;
reg_play_cmd_valid <= 0; reg_play_cmd_valid <= 0;
s_ctrlport_resp_data <= 'bX; s_ctrlport_resp_data <= 'bX;
s_ctrlport_resp_ack <= 0; s_ctrlport_resp_ack <= 0;
@@ -469,6 +471,7 @@ module axis_replay #(
REG_PLAY_CMD : begin REG_PLAY_CMD : begin
reg_play_cmd <= s_ctrlport_req_data[REG_PLAY_CMD_POS+:REG_PLAY_CMD_LEN]; reg_play_cmd <= s_ctrlport_req_data[REG_PLAY_CMD_POS+:REG_PLAY_CMD_LEN];
reg_play_cmd_timed <= s_ctrlport_req_data[REG_PLAY_TIMED_POS]; reg_play_cmd_timed <= s_ctrlport_req_data[REG_PLAY_TIMED_POS];
reg_play_cmd_no_eob <= s_ctrlport_req_data[REG_PLAY_NO_EOB_POS];
reg_play_cmd_valid <= 1'b1; reg_play_cmd_valid <= 1'b1;
if (!play_cmd_stop && s_ctrlport_req_data[REG_PLAY_CMD_LEN-1:0] == PLAY_CMD_STOP) begin if (!play_cmd_stop && s_ctrlport_req_data[REG_PLAY_CMD_LEN-1:0] == PLAY_CMD_STOP) begin
play_cmd_stop <= 1; play_cmd_stop <= 1;
@@ -511,6 +514,7 @@ module axis_replay #(
// Command FIFO Signals // Command FIFO Signals
wire [CMD_W-1:0] cmd_cf; wire [CMD_W-1:0] cmd_cf;
wire cmd_timed_cf; wire cmd_timed_cf;
wire cmd_no_eob_cf;
wire [NUM_WORDS_W-1:0] cmd_num_words_cf; wire [NUM_WORDS_W-1:0] cmd_num_words_cf;
wire [TIME_W-1:0] cmd_time_cf; wire [TIME_W-1:0] cmd_time_cf;
wire [MEM_ADDR_W-1:0] cmd_base_addr_cf; wire [MEM_ADDR_W-1:0] cmd_base_addr_cf;
@@ -519,15 +523,15 @@ module axis_replay #(
reg cmd_fifo_ready; reg cmd_fifo_ready;
axi_fifo_short #( axi_fifo_short #(
.WIDTH (MEM_ADDR_W + MEM_SIZE_W + 1 + CMD_W + NUM_WORDS_W + TIME_W) .WIDTH (MEM_ADDR_W + MEM_SIZE_W + 2 + CMD_W + NUM_WORDS_W + TIME_W)
) command_fifo ( ) command_fifo (
.clk (clk), .clk (clk),
.reset (rst), .reset (rst),
.clear (clear_cmd_fifo), .clear (clear_cmd_fifo),
.i_tdata ({play_base_addr_sr, play_buffer_size_sr, reg_play_cmd_timed, reg_play_cmd, reg_play_cmd_num_words, reg_play_cmd_time}), .i_tdata ({play_base_addr_sr, play_buffer_size_sr, reg_play_cmd_timed, reg_play_cmd_no_eob, reg_play_cmd, reg_play_cmd_num_words, reg_play_cmd_time}),
.i_tvalid (reg_play_cmd_valid), .i_tvalid (reg_play_cmd_valid),
.i_tready (reg_play_cmd_ready), .i_tready (reg_play_cmd_ready),
.o_tdata ({cmd_base_addr_cf, cmd_buffer_size_cf, cmd_timed_cf, cmd_cf, cmd_num_words_cf, cmd_time_cf}), .o_tdata ({cmd_base_addr_cf, cmd_buffer_size_cf, cmd_timed_cf, cmd_no_eob_cf, cmd_cf, cmd_num_words_cf, cmd_time_cf}),
.o_tvalid (cmd_fifo_valid), .o_tvalid (cmd_fifo_valid),
.o_tready (cmd_fifo_ready), .o_tready (cmd_fifo_ready),
.occupied (), .occupied (),
@@ -773,6 +777,7 @@ module axis_replay #(
// //
reg [NUM_WORDS_W-1:0] play_words_remaining; // Number of words left for playback command reg [NUM_WORDS_W-1:0] play_words_remaining; // Number of words left for playback command
reg [CMD_W-1:0] cmd; // Copy of cmd_cf from last command reg [CMD_W-1:0] cmd; // Copy of cmd_cf from last command
reg cmd_eob; // Inverse copy of cmd_no_eob_cf from last command
reg [MEM_ADDR_W-1:0] cmd_base_addr; // Copy of cmd_base_addr_cf from last command reg [MEM_ADDR_W-1:0] cmd_base_addr; // Copy of cmd_base_addr_cf from last command
reg [MEM_SIZE_W-1:0] cmd_buffer_size; // Copy of cmd_buffer_size_cf from last command reg [MEM_SIZE_W-1:0] cmd_buffer_size; // Copy of cmd_buffer_size_cf from last command
reg last_trans; // Is this the last read transaction for the command? reg last_trans; // Is this the last read transaction for the command?
@@ -805,6 +810,7 @@ module axis_replay #(
play_buffer_end <= {MEM_SIZE_W{1'bX}}; play_buffer_end <= {MEM_SIZE_W{1'bX}};
read_ctrl_valid <= 1'bX; read_ctrl_valid <= 1'bX;
cmd <= {CMD_W{1'bX}}; cmd <= {CMD_W{1'bX}};
cmd_eob <= 1'bX;
cmd_base_addr <= {MEM_ADDR_W{1'bX}}; cmd_base_addr <= {MEM_ADDR_W{1'bX}};
cmd_buffer_size <= {MEM_SIZE_W{1'bX}}; cmd_buffer_size <= {MEM_SIZE_W{1'bX}};
play_buffer_avail <= {MEM_SIZE_W{1'bX}}; play_buffer_avail <= {MEM_SIZE_W{1'bX}};
@@ -842,6 +848,7 @@ module axis_replay #(
PLAY_IDLE : begin PLAY_IDLE : begin
// Save needed command info // Save needed command info
cmd <= cmd_cf; cmd <= cmd_cf;
cmd_eob <= ~cmd_no_eob_cf;
cmd_base_addr <= cmd_base_addr_cf; cmd_base_addr <= cmd_base_addr_cf;
cmd_buffer_size <= cmd_buffer_size_cf / BYTES_PER_WORD; cmd_buffer_size <= cmd_buffer_size_cf / BYTES_PER_WORD;
@@ -1046,7 +1053,7 @@ module axis_replay #(
// If read_count is 0, then the next word is also the last word // If read_count is 0, then the next word is also the last word
if (read_count == 0) begin if (read_count == 0) begin
play_fifo_i_tlast <= 1'b1; play_fifo_i_tlast <= 1'b1;
eob <= last_trans; eob <= last_trans & cmd_eob;
end end
end end
@@ -1075,7 +1082,7 @@ module axis_replay #(
// case it's both the last word of the packet and the end of the burst. // case it's both the last word of the packet and the end of the burst.
if (last_trans && read_counter == 1) begin if (last_trans && read_counter == 1) begin
play_fifo_i_tlast <= 1'b1; play_fifo_i_tlast <= 1'b1;
eob <= 1; eob <= cmd_eob;
// Next, check if this is the last word of the packet according to packet // Next, check if this is the last word of the packet according to packet
// length. But note that the next word won't be the last if we're already // length. But note that the next word won't be the last if we're already
@@ -153,6 +153,9 @@ localparam REG_CMD_TIME_LEN = 64;
// //
// [31] : Timed flag. Indicates if the command is timed (1) or not (0). // [31] : Timed flag. Indicates if the command is timed (1) or not (0).
// //
// [30] : No EOB flag. Indicates if EOB should be set at the end of the
// command execution (0) or not (1).
//
// [1:0] : Command field. The command indicates what you want the playback to // [1:0] : Command field. The command indicates what you want the playback to
// do. It can be one of the following: // do. It can be one of the following:
// //
@@ -165,6 +168,9 @@ localparam REG_PLAY_CMD = 'h48;
localparam REG_PLAY_TIMED_POS = 31; localparam REG_PLAY_TIMED_POS = 31;
localparam REG_PLAY_TIMED_LEN = 1; localparam REG_PLAY_TIMED_LEN = 1;
// //
localparam REG_PLAY_NO_EOB_POS = 30;
localparam REG_PLAY_NO_EOB_LEN = 1;
//
localparam REG_PLAY_CMD_POS = 0; localparam REG_PLAY_CMD_POS = 0;
localparam REG_PLAY_CMD_LEN = 2; localparam REG_PLAY_CMD_LEN = 2;