rtl: rework dma AXIS cmd&status

This commit is contained in:
Phil
2026-06-24 13:32:42 +03:00
parent 3cc1235eea
commit cf45646812
3 changed files with 660 additions and 831 deletions

View File

@ -1,19 +1,10 @@
// SPDX-License-Identifier: MIT
// AXIS compat wrapper above axi_dma_if_wrapper.
//
// Compatibility wrapper over axi_dma_if_wrapper.
//
// Uses 4 axis_if channels for statuses and descs
// s_axis_desc_cmd = one-beat command stream carrying read + write desc
// m_axis_desc_status = one-beat status stream carrying read + write status
//
// payload packing is LSB-first and one descriptor/status occupies one AXIS beat.
// tkeep/tstrb/tlast/id/dest/user on descriptor inputs are ignored.
// status outputs drive tkeep/tstrb to all ones, tlast to 1, and id/dest/user to 0.
//
// !!!!!: the original alexforencich axi_dma status outputs have
// no ready/backpressure signal. This wrapper adds a oneentry holding register
// for each status axis output, but if a downstream is not ready long enough for a
// second status to arrive while the first one is still pending, the core cannot
// be backpressured. In normal use keep status sinks ready, or add an external
// FIFO if long stalls are possible.
// read_enable and write_enable select which descriptor is used
`default_nettype none
@ -41,102 +32,83 @@ module axi_dma_axis_compat #(
parameter int unsigned ENABLE_SG = 0,
parameter int unsigned ENABLE_UNALIGNED = 0,
// Payload widths for descriptor/status AXIS streams.
parameter int unsigned READ_DESC_PAYLOAD_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH,
parameter int unsigned READ_DESC_AXIS_DATA_WIDTH = ((READ_DESC_PAYLOAD_WIDTH + 7) / 8) * 8,
parameter int unsigned READ_DESC_STATUS_PAYLOAD_WIDTH = TAG_WIDTH + 4,
parameter int unsigned READ_DESC_STATUS_AXIS_DATA_WIDTH = ((READ_DESC_STATUS_PAYLOAD_WIDTH + 7) / 8) * 8,
parameter int unsigned WRITE_DESC_PAYLOAD_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH,
parameter int unsigned WRITE_DESC_AXIS_DATA_WIDTH = ((WRITE_DESC_PAYLOAD_WIDTH + 7) / 8) * 8,
parameter int unsigned WRITE_DESC_STATUS_PAYLOAD_WIDTH = LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH + 4,
parameter int unsigned WRITE_DESC_STATUS_AXIS_DATA_WIDTH = ((WRITE_DESC_STATUS_PAYLOAD_WIDTH + 7) / 8) * 8
// Raw packed command/status widths. rounded up to full bytes
parameter int unsigned READ_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH,
parameter int unsigned WRITE_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH,
parameter int unsigned DESC_CMD_RAW_WIDTH = READ_DESC_WIDTH + WRITE_DESC_WIDTH,
parameter int unsigned DESC_CMD_DATA_WIDTH = ((DESC_CMD_RAW_WIDTH + 7) / 8) * 8,
parameter int unsigned DESC_CMD_KEEP_WIDTH = DESC_CMD_DATA_WIDTH / 8,
parameter int unsigned READ_STATUS_WIDTH = TAG_WIDTH + 4,
parameter int unsigned WRITE_STATUS_WIDTH = LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH + 4,
parameter int unsigned DESC_STATUS_RAW_WIDTH = READ_STATUS_WIDTH + WRITE_STATUS_WIDTH,
parameter int unsigned DESC_STATUS_DATA_WIDTH = ((DESC_STATUS_RAW_WIDTH + 7) / 8) * 8,
parameter int unsigned DESC_STATUS_KEEP_WIDTH = DESC_STATUS_DATA_WIDTH / 8,
parameter int unsigned DESC_STATUS_USER_WIDTH = 2
)(
input logic clk,
input logic rst,
/*
* AXI read descriptor input, encoded as one AXIS beat.
* tdata layout, LSB first:
* addr | len | tag | id | dest | user
*/
axis_if.slave s_axis_read_desc,
// Unified command stream. One beat carries both read and write descriptors.
// Which parts are used is selected by read_enable/write_enable.
axis_if.slave s_axis_desc_cmd,
/*
* AXI read descriptor status output, encoded as one AXIS beat.
* tdata layout, LSB first:
* tag | error
*/
axis_if.master m_axis_read_desc_status,
// Unified status stream. One beat can carry read status, write status, or both.
// m_axis_desc_status.tuser[0] = read status valid in this beat
// m_axis_desc_status.tuser[1] = write status valid in this beat
axis_if.master m_axis_desc_status,
/*
* AXI stream read data output.
*/
// Original DMA data streams and AXI memory master, still exposed as normal
// generic interfaces.
axis_if.master m_axis_read_data,
/*
* AXI write descriptor input, encoded as one AXIS beat.
* tdata layout, LSB first:
* addr | len | tag
*/
axis_if.slave s_axis_write_desc,
/*
* AXI write descriptor status output, encoded as one AXIS beat.
* tdata layout, LSB first:
* len | tag | id | dest | user | error
*/
axis_if.master m_axis_write_desc_status,
/*
* AXI stream write data input.
*/
axis_if.slave s_axis_write_data,
/*
* AXI memory master interface.
*/
axi4_if.master m_axi,
/*
* Configuration.
*/
input logic read_enable,
input logic write_enable,
input logic write_abort
);
localparam int unsigned RD_ADDR_LSB = 0;
localparam int unsigned RD_LEN_LSB = RD_ADDR_LSB + AXI_ADDR_WIDTH;
localparam int unsigned RD_TAG_LSB = RD_LEN_LSB + LEN_WIDTH;
localparam int unsigned RD_ID_LSB = RD_TAG_LSB + TAG_WIDTH;
localparam int unsigned RD_DEST_LSB = RD_ID_LSB + AXIS_ID_WIDTH;
localparam int unsigned RD_USER_LSB = RD_DEST_LSB + AXIS_DEST_WIDTH;
// --------------------------------------------------------------------------
// packing layout
// --------------------------------------------------------------------------
// s_axis_desc_cmd.tdata:
// [READ_DESC_*] read descriptor
// [WRITE_DESC_*] write descriptor
//
// m_axis_desc_status.tdata:
// [READ_STATUS_*] read descriptor status
// [WRITE_STATUS_*] write descriptor status
//
// offsets are LSB-first. padding in upper bits (if required)
localparam int unsigned RDS_TAG_LSB = 0;
localparam int unsigned RDS_ERROR_LSB = RDS_TAG_LSB + TAG_WIDTH;
localparam int unsigned RD_ADDR_LSB = 0;
localparam int unsigned RD_LEN_LSB = RD_ADDR_LSB + AXI_ADDR_WIDTH;
localparam int unsigned RD_TAG_LSB = RD_LEN_LSB + LEN_WIDTH;
localparam int unsigned RD_ID_LSB = RD_TAG_LSB + TAG_WIDTH;
localparam int unsigned RD_DEST_LSB = RD_ID_LSB + AXIS_ID_WIDTH;
localparam int unsigned RD_USER_LSB = RD_DEST_LSB + AXIS_DEST_WIDTH;
localparam int unsigned WD_ADDR_LSB = 0;
localparam int unsigned WD_LEN_LSB = WD_ADDR_LSB + AXI_ADDR_WIDTH;
localparam int unsigned WD_TAG_LSB = WD_LEN_LSB + LEN_WIDTH;
localparam int unsigned WR_BASE_LSB = READ_DESC_WIDTH;
localparam int unsigned WR_ADDR_LSB = WR_BASE_LSB;
localparam int unsigned WR_LEN_LSB = WR_ADDR_LSB + AXI_ADDR_WIDTH;
localparam int unsigned WR_TAG_LSB = WR_LEN_LSB + LEN_WIDTH;
localparam int unsigned WDS_LEN_LSB = 0;
localparam int unsigned WDS_TAG_LSB = WDS_LEN_LSB + LEN_WIDTH;
localparam int unsigned WDS_ID_LSB = WDS_TAG_LSB + TAG_WIDTH;
localparam int unsigned WDS_DEST_LSB = WDS_ID_LSB + AXIS_ID_WIDTH;
localparam int unsigned WDS_USER_LSB = WDS_DEST_LSB + AXIS_DEST_WIDTH;
localparam int unsigned WDS_ERROR_LSB = WDS_USER_LSB + AXIS_USER_WIDTH;
localparam int unsigned RD_STS_TAG_LSB = 0;
localparam int unsigned RD_STS_ERROR_LSB = RD_STS_TAG_LSB + TAG_WIDTH;
localparam int unsigned READ_DESC_AXIS_KEEP_WIDTH = READ_DESC_AXIS_DATA_WIDTH / 8;
localparam int unsigned READ_DESC_STATUS_AXIS_KEEP_WIDTH = READ_DESC_STATUS_AXIS_DATA_WIDTH / 8;
localparam int unsigned WRITE_DESC_AXIS_KEEP_WIDTH = WRITE_DESC_AXIS_DATA_WIDTH / 8;
localparam int unsigned WRITE_DESC_STATUS_AXIS_KEEP_WIDTH = WRITE_DESC_STATUS_AXIS_DATA_WIDTH / 8;
localparam int unsigned WR_STS_BASE_LSB = READ_STATUS_WIDTH;
localparam int unsigned WR_STS_LEN_LSB = WR_STS_BASE_LSB;
localparam int unsigned WR_STS_TAG_LSB = WR_STS_LEN_LSB + LEN_WIDTH;
localparam int unsigned WR_STS_ID_LSB = WR_STS_TAG_LSB + TAG_WIDTH;
localparam int unsigned WR_STS_DEST_LSB = WR_STS_ID_LSB + AXIS_ID_WIDTH;
localparam int unsigned WR_STS_USER_LSB = WR_STS_DEST_LSB + AXIS_DEST_WIDTH;
localparam int unsigned WR_STS_ERROR_LSB = WR_STS_USER_LSB + AXIS_USER_WIDTH;
logic rstn;
assign rstn = ~rst;
wire rstn = ~rst;
// --------------------------------------------------------------------------
// Internal DMA-specific descriptor/status interfaces expected by
// axi_dma_if_wrapper.
// Internal DMA-specific descriptor/status interfaces
// --------------------------------------------------------------------------
axi_dma_read_desc_if #(
@ -179,125 +151,33 @@ module axi_dma_axis_compat #(
);
// --------------------------------------------------------------------------
// AXIS read descriptor input -> DMA-specific read descriptor interface.
// Command AXIS -> read/write descriptors
// --------------------------------------------------------------------------
assign read_desc_if.req.addr = s_axis_read_desc.req.t.data[RD_ADDR_LSB +: AXI_ADDR_WIDTH];
assign read_desc_if.req.len = s_axis_read_desc.req.t.data[RD_LEN_LSB +: LEN_WIDTH];
assign read_desc_if.req.tag = s_axis_read_desc.req.t.data[RD_TAG_LSB +: TAG_WIDTH];
assign read_desc_if.req.id = s_axis_read_desc.req.t.data[RD_ID_LSB +: AXIS_ID_WIDTH];
assign read_desc_if.req.dest = s_axis_read_desc.req.t.data[RD_DEST_LSB +: AXIS_DEST_WIDTH];
assign read_desc_if.req.user = s_axis_read_desc.req.t.data[RD_USER_LSB +: AXIS_USER_WIDTH];
assign read_desc_if.req.valid = s_axis_read_desc.req.t.valid;
assign s_axis_read_desc.resp.ready = read_desc_if.resp.ready;
wire cmd_valid = s_axis_desc_cmd.req.t.valid;
wire cmd_ready = (!read_enable || read_desc_if.resp.ready) &&
(!write_enable || write_desc_if.resp.ready);
// Only assert a descriptor valid when the complete command can be accepted.
// This prevents partial consumption when both read and write are enabled.
assign read_desc_if.req.valid = cmd_valid && read_enable && (!write_enable || write_desc_if.resp.ready);
assign write_desc_if.req.valid = cmd_valid && write_enable && (!read_enable || read_desc_if.resp.ready);
assign s_axis_desc_cmd.resp.ready = cmd_ready;
assign read_desc_if.req.addr = s_axis_desc_cmd.req.t.data[RD_ADDR_LSB +: AXI_ADDR_WIDTH];
assign read_desc_if.req.len = s_axis_desc_cmd.req.t.data[RD_LEN_LSB +: LEN_WIDTH];
assign read_desc_if.req.tag = s_axis_desc_cmd.req.t.data[RD_TAG_LSB +: TAG_WIDTH];
assign read_desc_if.req.id = s_axis_desc_cmd.req.t.data[RD_ID_LSB +: AXIS_ID_WIDTH];
assign read_desc_if.req.dest = s_axis_desc_cmd.req.t.data[RD_DEST_LSB +: AXIS_DEST_WIDTH];
assign read_desc_if.req.user = s_axis_desc_cmd.req.t.data[RD_USER_LSB +: AXIS_USER_WIDTH];
assign write_desc_if.req.addr = s_axis_desc_cmd.req.t.data[WR_ADDR_LSB +: AXI_ADDR_WIDTH];
assign write_desc_if.req.len = s_axis_desc_cmd.req.t.data[WR_LEN_LSB +: LEN_WIDTH];
assign write_desc_if.req.tag = s_axis_desc_cmd.req.t.data[WR_TAG_LSB +: TAG_WIDTH];
// --------------------------------------------------------------------------
// AXIS write descriptor input -> DMA-specific write descriptor interface.
// --------------------------------------------------------------------------
assign write_desc_if.req.addr = s_axis_write_desc.req.t.data[WD_ADDR_LSB +: AXI_ADDR_WIDTH];
assign write_desc_if.req.len = s_axis_write_desc.req.t.data[WD_LEN_LSB +: LEN_WIDTH];
assign write_desc_if.req.tag = s_axis_write_desc.req.t.data[WD_TAG_LSB +: TAG_WIDTH];
assign write_desc_if.req.valid = s_axis_write_desc.req.t.valid;
assign s_axis_write_desc.resp.ready = write_desc_if.resp.ready;
// --------------------------------------------------------------------------
// DMA-specific read status -> AXIS read status output.
// --------------------------------------------------------------------------
logic [READ_DESC_STATUS_AXIS_DATA_WIDTH-1:0] read_status_payload;
logic [READ_DESC_STATUS_AXIS_DATA_WIDTH-1:0] read_status_data_q;
logic read_status_valid_q;
always_comb begin
read_status_payload = '0;
read_status_payload[RDS_TAG_LSB +: TAG_WIDTH] = read_desc_status_if.req.tag;
read_status_payload[RDS_ERROR_LSB +: 4] = read_desc_status_if.req.error;
end
always_ff @(posedge clk) begin
if (rst) begin
read_status_valid_q <= 1'b0;
read_status_data_q <= '0;
end else begin
if (!read_status_valid_q || m_axis_read_desc_status.resp.ready) begin
read_status_valid_q <= read_desc_status_if.req.valid;
if (read_desc_status_if.req.valid) begin
read_status_data_q <= read_status_payload;
end else begin
read_status_data_q <= '0;
end
end
end
end
always_comb begin
m_axis_read_desc_status.req.t.data = '0;
m_axis_read_desc_status.req.t.keep = '0;
m_axis_read_desc_status.req.t.strb = '0;
m_axis_read_desc_status.req.t.last = read_status_valid_q;
m_axis_read_desc_status.req.t.id = '0;
m_axis_read_desc_status.req.t.dest = '0;
m_axis_read_desc_status.req.t.user = '0;
m_axis_read_desc_status.req.t.valid = read_status_valid_q;
m_axis_read_desc_status.req.t.data[READ_DESC_STATUS_AXIS_DATA_WIDTH-1:0] = read_status_data_q;
m_axis_read_desc_status.req.t.keep[READ_DESC_STATUS_AXIS_KEEP_WIDTH-1:0] = {READ_DESC_STATUS_AXIS_KEEP_WIDTH{read_status_valid_q}};
m_axis_read_desc_status.req.t.strb[READ_DESC_STATUS_AXIS_KEEP_WIDTH-1:0] = {READ_DESC_STATUS_AXIS_KEEP_WIDTH{read_status_valid_q}};
end
// --------------------------------------------------------------------------
// DMA-specific write status -> AXIS write status output.
// --------------------------------------------------------------------------
logic [WRITE_DESC_STATUS_AXIS_DATA_WIDTH-1:0] write_status_payload;
logic [WRITE_DESC_STATUS_AXIS_DATA_WIDTH-1:0] write_status_data_q;
logic write_status_valid_q;
always_comb begin
write_status_payload = '0;
write_status_payload[WDS_LEN_LSB +: LEN_WIDTH] = write_desc_status_if.req.len;
write_status_payload[WDS_TAG_LSB +: TAG_WIDTH] = write_desc_status_if.req.tag;
write_status_payload[WDS_ID_LSB +: AXIS_ID_WIDTH] = write_desc_status_if.req.id;
write_status_payload[WDS_DEST_LSB +: AXIS_DEST_WIDTH] = write_desc_status_if.req.dest;
write_status_payload[WDS_USER_LSB +: AXIS_USER_WIDTH] = write_desc_status_if.req.user;
write_status_payload[WDS_ERROR_LSB +: 4] = write_desc_status_if.req.error;
end
always_ff @(posedge clk) begin
if (rst) begin
write_status_valid_q <= 1'b0;
write_status_data_q <= '0;
end else begin
if (!write_status_valid_q || m_axis_write_desc_status.resp.ready) begin
write_status_valid_q <= write_desc_status_if.req.valid;
if (write_desc_status_if.req.valid) begin
write_status_data_q <= write_status_payload;
end else begin
write_status_data_q <= '0;
end
end
end
end
always_comb begin
m_axis_write_desc_status.req.t.data = '0;
m_axis_write_desc_status.req.t.keep = '0;
m_axis_write_desc_status.req.t.strb = '0;
m_axis_write_desc_status.req.t.last = write_status_valid_q;
m_axis_write_desc_status.req.t.id = '0;
m_axis_write_desc_status.req.t.dest = '0;
m_axis_write_desc_status.req.t.user = '0;
m_axis_write_desc_status.req.t.valid = write_status_valid_q;
m_axis_write_desc_status.req.t.data[WRITE_DESC_STATUS_AXIS_DATA_WIDTH-1:0] = write_status_data_q;
m_axis_write_desc_status.req.t.keep[WRITE_DESC_STATUS_AXIS_KEEP_WIDTH-1:0] = {WRITE_DESC_STATUS_AXIS_KEEP_WIDTH{write_status_valid_q}};
m_axis_write_desc_status.req.t.strb[WRITE_DESC_STATUS_AXIS_KEEP_WIDTH-1:0] = {WRITE_DESC_STATUS_AXIS_KEEP_WIDTH{write_status_valid_q}};
end
// --------------------------------------------------------------------------
// Lower-level wrapper: DMA-specific descriptor/status interfaces inside,
// ordinary AXIS data and AXI memory interfaces unchanged.
// Lower DMA wrapper
// --------------------------------------------------------------------------
axi_dma_if_wrapper #(
@ -307,6 +187,7 @@ module axi_dma_axis_compat #(
.AXI_ID_WIDTH (AXI_ID_WIDTH),
.AXI_USER_WIDTH (AXI_USER_WIDTH),
.AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN),
.AXIS_DATA_WIDTH (AXIS_DATA_WIDTH),
.AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE),
.AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH),
@ -317,29 +198,134 @@ module axi_dma_axis_compat #(
.AXIS_DEST_WIDTH (AXIS_DEST_WIDTH),
.AXIS_USER_ENABLE (AXIS_USER_ENABLE),
.AXIS_USER_WIDTH (AXIS_USER_WIDTH),
.LEN_WIDTH (LEN_WIDTH),
.TAG_WIDTH (TAG_WIDTH),
.ENABLE_SG (ENABLE_SG),
.ENABLE_UNALIGNED (ENABLE_UNALIGNED)
) u_axi_dma_if_wrapper (
.clk (clk),
.rst (rst),
.clk (clk),
.rst (rst),
.s_axis_read_desc (read_desc_if),
.m_axis_read_desc_status (read_desc_status_if),
.m_axis_read_data (m_axis_read_data),
.s_axis_read_desc (read_desc_if),
.m_axis_read_desc_status (read_desc_status_if),
.m_axis_read_data (m_axis_read_data),
.s_axis_write_desc (write_desc_if),
.m_axis_write_desc_status (write_desc_status_if),
.s_axis_write_data (s_axis_write_data),
.s_axis_write_desc (write_desc_if),
.m_axis_write_desc_status (write_desc_status_if),
.s_axis_write_data (s_axis_write_data),
.m_axi (m_axi),
.m_axi (m_axi),
.read_enable (read_enable),
.write_enable (write_enable),
.write_abort (write_abort)
.read_enable (read_enable),
.write_enable (write_enable),
.write_abort (write_abort)
);
// --------------------------------------------------------------------------
// Status capture and unified AXIS output
// --------------------------------------------------------------------------
// Forencich descriptor status channels have valid but no ready. A regular
// AXI-Stream output can be stalled
// this wrapper stores one pending read status and one pending write status.
// if you need more, please attack a fifo
logic rd_status_pending;
logic [TAG_WIDTH-1:0] rd_status_tag_q;
logic [3:0] rd_status_error_q;
logic wr_status_pending;
logic [LEN_WIDTH-1:0] wr_status_len_q;
logic [TAG_WIDTH-1:0] wr_status_tag_q;
logic [AXIS_ID_WIDTH-1:0] wr_status_id_q;
logic [AXIS_DEST_WIDTH-1:0] wr_status_dest_q;
logic [AXIS_USER_WIDTH-1:0] wr_status_user_q;
logic [3:0] wr_status_error_q;
wire status_valid = rd_status_pending || wr_status_pending;
wire status_fire = status_valid && m_axis_desc_status.resp.ready;
always_ff @(posedge clk) begin
if (rst) begin
rd_status_pending <= 1'b0;
wr_status_pending <= 1'b0;
rd_status_tag_q <= '0;
rd_status_error_q <= '0;
wr_status_len_q <= '0;
wr_status_tag_q <= '0;
wr_status_id_q <= '0;
wr_status_dest_q <= '0;
wr_status_user_q <= '0;
wr_status_error_q <= '0;
end else begin
if (status_fire) begin
rd_status_pending <= 1'b0;
wr_status_pending <= 1'b0;
end
if (read_desc_status_if.req.valid) begin
`ifndef SYNTHESIS
if (rd_status_pending && !status_fire) begin
$error("axi_dma_axis_compat: read status overflow; add a FIFO or do not backpressure status output");
end
`endif
rd_status_pending <= 1'b1;
rd_status_tag_q <= read_desc_status_if.req.tag;
rd_status_error_q <= read_desc_status_if.req.error;
end
if (write_desc_status_if.req.valid) begin
`ifndef SYNTHESIS
if (wr_status_pending && !status_fire) begin
$error("axi_dma_axis_compat: write status overflow; add a FIFO or do not backpressure status output");
end
`endif
wr_status_pending <= 1'b1;
wr_status_len_q <= write_desc_status_if.req.len;
wr_status_tag_q <= write_desc_status_if.req.tag;
wr_status_id_q <= write_desc_status_if.req.id;
wr_status_dest_q <= write_desc_status_if.req.dest;
wr_status_user_q <= write_desc_status_if.req.user;
wr_status_error_q <= write_desc_status_if.req.error;
end
end
end
logic [DESC_STATUS_DATA_WIDTH-1:0] status_tdata;
logic [DESC_STATUS_USER_WIDTH-1:0] status_tuser;
always_comb begin
status_tdata = '0;
status_tuser = '0;
if (rd_status_pending) begin
status_tdata[RD_STS_TAG_LSB +: TAG_WIDTH] = rd_status_tag_q;
status_tdata[RD_STS_ERROR_LSB +: 4] = rd_status_error_q;
status_tuser[0] = 1'b1;
end
if (wr_status_pending) begin
status_tdata[WR_STS_LEN_LSB +: LEN_WIDTH] = wr_status_len_q;
status_tdata[WR_STS_TAG_LSB +: TAG_WIDTH] = wr_status_tag_q;
status_tdata[WR_STS_ID_LSB +: AXIS_ID_WIDTH] = wr_status_id_q;
status_tdata[WR_STS_DEST_LSB +: AXIS_DEST_WIDTH] = wr_status_dest_q;
status_tdata[WR_STS_USER_LSB +: AXIS_USER_WIDTH] = wr_status_user_q;
status_tdata[WR_STS_ERROR_LSB +: 4] = wr_status_error_q;
status_tuser[1] = 1'b1;
end
end
assign m_axis_desc_status.req.t.data = status_tdata;
assign m_axis_desc_status.req.t.keep = {DESC_STATUS_KEEP_WIDTH{1'b1}};
assign m_axis_desc_status.req.t.strb = {DESC_STATUS_KEEP_WIDTH{1'b1}};
assign m_axis_desc_status.req.t.last = 1'b1;
assign m_axis_desc_status.req.t.id = '0;
assign m_axis_desc_status.req.t.dest = '0;
assign m_axis_desc_status.req.t.user = status_tuser;
assign m_axis_desc_status.req.t.valid = status_valid;
endmodule : axi_dma_axis_compat
`default_nettype wire