mirror of
https://github.com/alexforencich/verilog-axi.git
synced 2025-01-14 06:42:55 +08:00
Add error reporting to DMA modules
This commit is contained in:
parent
db826e489b
commit
ee9c719bf4
@ -66,6 +66,7 @@ module axi_cdma #
|
||||
* AXI descriptor status output
|
||||
*/
|
||||
output wire [TAG_WIDTH-1:0] m_axis_desc_status_tag,
|
||||
output wire [3:0] m_axis_desc_status_error,
|
||||
output wire m_axis_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -147,6 +148,25 @@ initial begin
|
||||
end
|
||||
end
|
||||
|
||||
localparam [1:0]
|
||||
AXI_RESP_OKAY = 2'b00,
|
||||
AXI_RESP_EXOKAY = 2'b01,
|
||||
AXI_RESP_SLVERR = 2'b10,
|
||||
AXI_RESP_DECERR = 2'b11;
|
||||
|
||||
localparam [3:0]
|
||||
DMA_ERROR_NONE = 4'd0,
|
||||
DMA_ERROR_TIMEOUT = 4'd1,
|
||||
DMA_ERROR_PARITY = 4'd2,
|
||||
DMA_ERROR_AXI_RD_SLVERR = 4'd4,
|
||||
DMA_ERROR_AXI_RD_DECERR = 4'd5,
|
||||
DMA_ERROR_AXI_WR_SLVERR = 4'd6,
|
||||
DMA_ERROR_AXI_WR_DECERR = 4'd7,
|
||||
DMA_ERROR_PCIE_FLR = 4'd8,
|
||||
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
|
||||
|
||||
localparam [1:0]
|
||||
READ_STATE_IDLE = 2'd0,
|
||||
READ_STATE_START = 2'd1,
|
||||
@ -194,14 +214,18 @@ reg first_input_cycle_reg = 1'b0, first_input_cycle_next;
|
||||
reg first_output_cycle_reg = 1'b0, first_output_cycle_next;
|
||||
reg output_last_cycle_reg = 1'b0, output_last_cycle_next;
|
||||
reg last_transfer_reg = 1'b0, last_transfer_next;
|
||||
reg [1:0] rresp_reg = AXI_RESP_OKAY, rresp_next;
|
||||
reg [1:0] bresp_reg = AXI_RESP_OKAY, bresp_next;
|
||||
|
||||
reg [TAG_WIDTH-1:0] tag_reg = {TAG_WIDTH{1'b0}}, tag_next;
|
||||
|
||||
reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_wr_ptr_reg = 0;
|
||||
reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_rd_ptr_reg = 0, status_fifo_rd_ptr_next;
|
||||
reg [TAG_WIDTH-1:0] status_fifo_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
|
||||
reg [1:0] status_fifo_resp[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
|
||||
reg status_fifo_last[(2**STATUS_FIFO_ADDR_WIDTH)-1:0];
|
||||
reg [TAG_WIDTH-1:0] status_fifo_wr_tag;
|
||||
reg [1:0] status_fifo_wr_resp;
|
||||
reg status_fifo_wr_last;
|
||||
|
||||
reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] active_count_reg = 0;
|
||||
@ -212,6 +236,7 @@ reg dec_active;
|
||||
reg s_axis_desc_ready_reg = 1'b0, s_axis_desc_ready_next;
|
||||
|
||||
reg [TAG_WIDTH-1:0] m_axis_desc_status_tag_reg = {TAG_WIDTH{1'b0}}, m_axis_desc_status_tag_next;
|
||||
reg [3:0] m_axis_desc_status_error_reg = 4'd0, m_axis_desc_status_error_next;
|
||||
reg m_axis_desc_status_valid_reg = 1'b0, m_axis_desc_status_valid_next;
|
||||
|
||||
reg [AXI_ADDR_WIDTH-1:0] m_axi_araddr_reg = {AXI_ADDR_WIDTH{1'b0}}, m_axi_araddr_next;
|
||||
@ -239,6 +264,7 @@ wire m_axi_wready_int_early;
|
||||
assign s_axis_desc_ready = s_axis_desc_ready_reg;
|
||||
|
||||
assign m_axis_desc_status_tag = m_axis_desc_status_tag_reg;
|
||||
assign m_axis_desc_status_error = m_axis_desc_status_error_reg;
|
||||
assign m_axis_desc_status_valid = m_axis_desc_status_valid_reg;
|
||||
|
||||
assign m_axi_arid = {AXI_ID_WIDTH{1'b0}};
|
||||
@ -418,6 +444,7 @@ always @* begin
|
||||
axi_state_next = AXI_STATE_IDLE;
|
||||
|
||||
m_axis_desc_status_tag_next = m_axis_desc_status_tag_reg;
|
||||
m_axis_desc_status_error_next = m_axis_desc_status_error_reg;
|
||||
m_axis_desc_status_valid_next = 1'b0;
|
||||
|
||||
m_axi_awaddr_next = m_axi_awaddr_reg;
|
||||
@ -454,7 +481,20 @@ always @* begin
|
||||
|
||||
dec_active = 1'b0;
|
||||
|
||||
if (m_axi_rready && m_axi_rvalid && (m_axi_rresp == AXI_RESP_SLVERR || m_axi_rresp == AXI_RESP_DECERR)) begin
|
||||
rresp_next = m_axi_rresp;
|
||||
end else begin
|
||||
rresp_next = rresp_reg;
|
||||
end
|
||||
|
||||
if (m_axi_bready && m_axi_bvalid && (m_axi_bresp == AXI_RESP_SLVERR || m_axi_bresp == AXI_RESP_DECERR)) begin
|
||||
bresp_next = m_axi_bresp;
|
||||
end else begin
|
||||
bresp_next = bresp_reg;
|
||||
end
|
||||
|
||||
status_fifo_wr_tag = tag_reg;
|
||||
status_fifo_wr_resp = rresp_next;
|
||||
status_fifo_wr_last = 1'b0;
|
||||
|
||||
case (axi_state_reg)
|
||||
@ -545,8 +585,13 @@ always @* begin
|
||||
|
||||
status_fifo_we = 1'b1;
|
||||
status_fifo_wr_tag = tag_reg;
|
||||
status_fifo_wr_resp = rresp_next;
|
||||
status_fifo_wr_last = last_transfer_reg;
|
||||
|
||||
if (last_transfer_reg) begin
|
||||
rresp_next = AXI_RESP_OKAY;
|
||||
end
|
||||
|
||||
m_axi_rready_next = 1'b0;
|
||||
axi_state_next = AXI_STATE_IDLE;
|
||||
end else begin
|
||||
@ -565,10 +610,25 @@ always @* begin
|
||||
if (m_axi_bready && m_axi_bvalid) begin
|
||||
// got write completion, pop and return status
|
||||
m_axis_desc_status_tag_next = status_fifo_tag[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
if (status_fifo_resp[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] == AXI_RESP_SLVERR) begin
|
||||
m_axis_desc_status_error_next = DMA_ERROR_AXI_RD_SLVERR;
|
||||
end else if (status_fifo_resp[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] == AXI_RESP_DECERR) begin
|
||||
m_axis_desc_status_error_next = DMA_ERROR_AXI_RD_DECERR;
|
||||
end else if (bresp_next == AXI_RESP_SLVERR) begin
|
||||
m_axis_desc_status_error_next = DMA_ERROR_AXI_WR_SLVERR;
|
||||
end else if (bresp_next == AXI_RESP_DECERR) begin
|
||||
m_axis_desc_status_error_next = DMA_ERROR_AXI_WR_DECERR;
|
||||
end else begin
|
||||
m_axis_desc_status_error_next = DMA_ERROR_NONE;
|
||||
end
|
||||
m_axis_desc_status_valid_next = status_fifo_last[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
status_fifo_rd_ptr_next = status_fifo_rd_ptr_reg + 1;
|
||||
m_axi_bready_next = 1'b0;
|
||||
|
||||
if (status_fifo_last[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]]) begin
|
||||
bresp_next = AXI_RESP_OKAY;
|
||||
end
|
||||
|
||||
dec_active = 1'b1;
|
||||
end else begin
|
||||
// wait for write completion
|
||||
@ -584,6 +644,7 @@ always @(posedge clk) begin
|
||||
s_axis_desc_ready_reg <= s_axis_desc_ready_next;
|
||||
|
||||
m_axis_desc_status_tag_reg <= m_axis_desc_status_tag_next;
|
||||
m_axis_desc_status_error_reg <= m_axis_desc_status_error_next;
|
||||
m_axis_desc_status_valid_reg <= m_axis_desc_status_valid_next;
|
||||
|
||||
m_axi_awaddr_reg <= m_axi_awaddr_next;
|
||||
@ -624,6 +685,8 @@ always @(posedge clk) begin
|
||||
first_output_cycle_reg <= first_output_cycle_next;
|
||||
output_last_cycle_reg <= output_last_cycle_next;
|
||||
last_transfer_reg <= last_transfer_next;
|
||||
rresp_reg <= rresp_next;
|
||||
bresp_reg <= bresp_next;
|
||||
|
||||
tag_reg <= tag_next;
|
||||
|
||||
@ -633,6 +696,7 @@ always @(posedge clk) begin
|
||||
|
||||
if (status_fifo_we) begin
|
||||
status_fifo_tag[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_tag;
|
||||
status_fifo_resp[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_resp;
|
||||
status_fifo_last[status_fifo_wr_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]] <= status_fifo_wr_last;
|
||||
status_fifo_wr_ptr_reg <= status_fifo_wr_ptr_reg + 1;
|
||||
end
|
||||
@ -652,8 +716,6 @@ always @(posedge clk) begin
|
||||
read_state_reg <= READ_STATE_IDLE;
|
||||
axi_state_reg <= AXI_STATE_IDLE;
|
||||
|
||||
axi_cmd_valid_reg <= 1'b0;
|
||||
|
||||
s_axis_desc_ready_reg <= 1'b0;
|
||||
m_axis_desc_status_valid_reg <= 1'b0;
|
||||
|
||||
@ -662,6 +724,11 @@ always @(posedge clk) begin
|
||||
m_axi_arvalid_reg <= 1'b0;
|
||||
m_axi_rready_reg <= 1'b0;
|
||||
|
||||
axi_cmd_valid_reg <= 1'b0;
|
||||
|
||||
rresp_reg <= AXI_RESP_OKAY;
|
||||
bresp_reg <= AXI_RESP_OKAY;
|
||||
|
||||
status_fifo_wr_ptr_reg <= 0;
|
||||
status_fifo_rd_ptr_reg <= 0;
|
||||
|
||||
|
@ -65,6 +65,7 @@ module axi_cdma_desc_mux #
|
||||
* Descriptor status input (from AXI CDMA core)
|
||||
*/
|
||||
input wire [M_TAG_WIDTH-1:0] s_axis_desc_status_tag,
|
||||
input wire [3:0] s_axis_desc_status_error,
|
||||
input wire s_axis_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -81,6 +82,7 @@ module axi_cdma_desc_mux #
|
||||
* Descriptor status output
|
||||
*/
|
||||
output wire [PORTS*S_TAG_WIDTH-1:0] m_axis_desc_status_tag,
|
||||
output wire [PORTS*4-1:0] m_axis_desc_status_error,
|
||||
output wire [PORTS-1:0] m_axis_desc_status_valid
|
||||
);
|
||||
|
||||
@ -238,9 +240,11 @@ end
|
||||
|
||||
// descriptor status demux
|
||||
reg [S_TAG_WIDTH-1:0] m_axis_desc_status_tag_reg = {S_TAG_WIDTH{1'b0}};
|
||||
reg [3:0] m_axis_desc_status_error_reg = 4'd0;
|
||||
reg [PORTS-1:0] m_axis_desc_status_valid_reg = {PORTS{1'b0}};
|
||||
|
||||
assign m_axis_desc_status_tag = {PORTS{m_axis_desc_status_tag_reg}};
|
||||
assign m_axis_desc_status_error = {PORTS{m_axis_desc_status_error_reg}};
|
||||
assign m_axis_desc_status_valid = m_axis_desc_status_valid_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
@ -251,6 +255,7 @@ always @(posedge clk) begin
|
||||
end
|
||||
|
||||
m_axis_desc_status_tag_reg <= s_axis_desc_status_tag;
|
||||
m_axis_desc_status_error_reg <= s_axis_desc_status_error;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -91,6 +91,7 @@ module axi_dma #
|
||||
* AXI read descriptor status output
|
||||
*/
|
||||
output wire [TAG_WIDTH-1:0] m_axis_read_desc_status_tag,
|
||||
output wire [3:0] m_axis_read_desc_status_error,
|
||||
output wire m_axis_read_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -122,6 +123,7 @@ module axi_dma #
|
||||
output wire [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_id,
|
||||
output wire [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_dest,
|
||||
output wire [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_user,
|
||||
output wire [3:0] m_axis_write_desc_status_error,
|
||||
output wire m_axis_write_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -224,6 +226,7 @@ axi_dma_rd_inst (
|
||||
* AXI read descriptor status output
|
||||
*/
|
||||
.m_axis_read_desc_status_tag(m_axis_read_desc_status_tag),
|
||||
.m_axis_read_desc_status_error(m_axis_read_desc_status_error),
|
||||
.m_axis_read_desc_status_valid(m_axis_read_desc_status_valid),
|
||||
|
||||
/*
|
||||
@ -306,6 +309,7 @@ axi_dma_wr_inst (
|
||||
.m_axis_write_desc_status_id(m_axis_write_desc_status_id),
|
||||
.m_axis_write_desc_status_dest(m_axis_write_desc_status_dest),
|
||||
.m_axis_write_desc_status_user(m_axis_write_desc_status_user),
|
||||
.m_axis_write_desc_status_error(m_axis_write_desc_status_error),
|
||||
.m_axis_write_desc_status_valid(m_axis_write_desc_status_valid),
|
||||
|
||||
/*
|
||||
|
@ -83,6 +83,7 @@ module axi_dma_desc_mux #
|
||||
input wire [AXIS_ID_WIDTH-1:0] s_axis_desc_status_id,
|
||||
input wire [AXIS_DEST_WIDTH-1:0] s_axis_desc_status_dest,
|
||||
input wire [AXIS_USER_WIDTH-1:0] s_axis_desc_status_user,
|
||||
input wire [3:0] s_axis_desc_status_error,
|
||||
input wire s_axis_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -105,6 +106,7 @@ module axi_dma_desc_mux #
|
||||
output wire [PORTS*AXIS_ID_WIDTH-1:0] m_axis_desc_status_id,
|
||||
output wire [PORTS*AXIS_DEST_WIDTH-1:0] m_axis_desc_status_dest,
|
||||
output wire [PORTS*AXIS_USER_WIDTH-1:0] m_axis_desc_status_user,
|
||||
output wire [PORTS*4-1:0] m_axis_desc_status_error,
|
||||
output wire [PORTS-1:0] m_axis_desc_status_valid
|
||||
);
|
||||
|
||||
@ -284,6 +286,7 @@ reg [S_TAG_WIDTH-1:0] m_axis_desc_status_tag_reg = {S_TAG_WIDTH{1'b0}};
|
||||
reg [AXIS_ID_WIDTH-1:0] m_axis_desc_status_id_reg = {AXIS_ID_WIDTH{1'b0}};
|
||||
reg [AXIS_DEST_WIDTH-1:0] m_axis_desc_status_dest_reg = {AXIS_DEST_WIDTH{1'b0}};
|
||||
reg [AXIS_USER_WIDTH-1:0] m_axis_desc_status_user_reg = {AXIS_USER_WIDTH{1'b0}};
|
||||
reg [3:0] m_axis_desc_status_error_reg = 4'd0;
|
||||
reg [PORTS-1:0] m_axis_desc_status_valid_reg = {PORTS{1'b0}};
|
||||
|
||||
assign m_axis_desc_status_len = {PORTS{m_axis_desc_status_len_reg}};
|
||||
@ -291,6 +294,7 @@ assign m_axis_desc_status_tag = {PORTS{m_axis_desc_status_tag_reg}};
|
||||
assign m_axis_desc_status_id = AXIS_ID_ENABLE ? {PORTS{m_axis_desc_status_id_reg}} : {AXIS_ID_WIDTH*PORTS{1'b0}};
|
||||
assign m_axis_desc_status_dest = AXIS_DEST_ENABLE ? {PORTS{m_axis_desc_status_dest_reg}} : {AXIS_DEST_WIDTH*PORTS{1'b0}};
|
||||
assign m_axis_desc_status_user = AXIS_USER_ENABLE ? {PORTS{m_axis_desc_status_user_reg}} : {AXIS_USER_WIDTH*PORTS{1'b0}};
|
||||
assign m_axis_desc_status_error = {PORTS{m_axis_desc_status_error_reg}};
|
||||
assign m_axis_desc_status_valid = m_axis_desc_status_valid_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
@ -305,6 +309,7 @@ always @(posedge clk) begin
|
||||
m_axis_desc_status_id_reg <= s_axis_desc_status_id;
|
||||
m_axis_desc_status_dest_reg <= s_axis_desc_status_dest;
|
||||
m_axis_desc_status_user_reg <= s_axis_desc_status_user;
|
||||
m_axis_desc_status_error_reg <= s_axis_desc_status_error;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -91,6 +91,7 @@ module axi_dma_rd #
|
||||
* AXI read descriptor status output
|
||||
*/
|
||||
output wire [TAG_WIDTH-1:0] m_axis_read_desc_status_tag,
|
||||
output wire [3:0] m_axis_read_desc_status_error,
|
||||
output wire m_axis_read_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -183,6 +184,25 @@ initial begin
|
||||
end
|
||||
end
|
||||
|
||||
localparam [1:0]
|
||||
AXI_RESP_OKAY = 2'b00,
|
||||
AXI_RESP_EXOKAY = 2'b01,
|
||||
AXI_RESP_SLVERR = 2'b10,
|
||||
AXI_RESP_DECERR = 2'b11;
|
||||
|
||||
localparam [3:0]
|
||||
DMA_ERROR_NONE = 4'd0,
|
||||
DMA_ERROR_TIMEOUT = 4'd1,
|
||||
DMA_ERROR_PARITY = 4'd2,
|
||||
DMA_ERROR_AXI_RD_SLVERR = 4'd4,
|
||||
DMA_ERROR_AXI_RD_DECERR = 4'd5,
|
||||
DMA_ERROR_AXI_WR_SLVERR = 4'd6,
|
||||
DMA_ERROR_AXI_WR_DECERR = 4'd7,
|
||||
DMA_ERROR_PCIE_FLR = 4'd8,
|
||||
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
|
||||
|
||||
localparam [0:0]
|
||||
AXI_STATE_IDLE = 1'd0,
|
||||
AXI_STATE_START = 1'd1;
|
||||
@ -223,6 +243,7 @@ reg output_active_reg = 1'b0, output_active_next;
|
||||
reg bubble_cycle_reg = 1'b0, bubble_cycle_next;
|
||||
reg first_cycle_reg = 1'b0, first_cycle_next;
|
||||
reg output_last_cycle_reg = 1'b0, output_last_cycle_next;
|
||||
reg [1:0] rresp_reg = AXI_RESP_OKAY, rresp_next;
|
||||
|
||||
reg [TAG_WIDTH-1:0] tag_reg = {TAG_WIDTH{1'b0}}, tag_next;
|
||||
reg [AXIS_ID_WIDTH-1:0] axis_id_reg = {AXIS_ID_WIDTH{1'b0}}, axis_id_next;
|
||||
@ -232,6 +253,7 @@ reg [AXIS_USER_WIDTH-1:0] axis_user_reg = {AXIS_USER_WIDTH{1'b0}}, axis_user_nex
|
||||
reg s_axis_read_desc_ready_reg = 1'b0, s_axis_read_desc_ready_next;
|
||||
|
||||
reg [TAG_WIDTH-1:0] m_axis_read_desc_status_tag_reg = {TAG_WIDTH{1'b0}}, m_axis_read_desc_status_tag_next;
|
||||
reg [3:0] m_axis_read_desc_status_error_reg = 4'd0, m_axis_read_desc_status_error_next;
|
||||
reg m_axis_read_desc_status_valid_reg = 1'b0, m_axis_read_desc_status_valid_next;
|
||||
|
||||
reg [AXI_ADDR_WIDTH-1:0] m_axi_araddr_reg = {AXI_ADDR_WIDTH{1'b0}}, m_axi_araddr_next;
|
||||
@ -257,6 +279,7 @@ wire m_axis_read_data_tready_int_early;
|
||||
assign s_axis_read_desc_ready = s_axis_read_desc_ready_reg;
|
||||
|
||||
assign m_axis_read_desc_status_tag = m_axis_read_desc_status_tag_reg;
|
||||
assign m_axis_read_desc_status_error = m_axis_read_desc_status_error_reg;
|
||||
assign m_axis_read_desc_status_valid = m_axis_read_desc_status_valid_reg;
|
||||
|
||||
assign m_axi_arid = {AXI_ID_WIDTH{1'b0}};
|
||||
@ -384,6 +407,7 @@ always @* begin
|
||||
axis_state_next = AXIS_STATE_IDLE;
|
||||
|
||||
m_axis_read_desc_status_tag_next = m_axis_read_desc_status_tag_reg;
|
||||
m_axis_read_desc_status_error_next = m_axis_read_desc_status_error_reg;
|
||||
m_axis_read_desc_status_valid_next = 1'b0;
|
||||
|
||||
m_axis_read_data_tdata_int = shift_axi_rdata;
|
||||
@ -414,6 +438,12 @@ always @* begin
|
||||
axis_dest_next = axis_dest_reg;
|
||||
axis_user_next = axis_user_reg;
|
||||
|
||||
if (m_axi_rready && m_axi_rvalid && (m_axi_rresp == AXI_RESP_SLVERR || m_axi_rresp == AXI_RESP_DECERR)) begin
|
||||
rresp_next = m_axi_rresp;
|
||||
end else begin
|
||||
rresp_next = rresp_reg;
|
||||
end
|
||||
|
||||
case (axis_state_reg)
|
||||
AXIS_STATE_IDLE: begin
|
||||
// idle state - load new descriptor to start operation
|
||||
@ -490,8 +520,17 @@ always @* begin
|
||||
m_axis_read_data_tlast_int = 1'b1;
|
||||
|
||||
m_axis_read_desc_status_tag_next = tag_reg;
|
||||
if (rresp_next == AXI_RESP_SLVERR) begin
|
||||
m_axis_read_desc_status_error_next = DMA_ERROR_AXI_RD_SLVERR;
|
||||
end else if (rresp_next == AXI_RESP_DECERR) begin
|
||||
m_axis_read_desc_status_error_next = DMA_ERROR_AXI_RD_DECERR;
|
||||
end else begin
|
||||
m_axis_read_desc_status_error_next = DMA_ERROR_NONE;
|
||||
end
|
||||
m_axis_read_desc_status_valid_next = 1'b1;
|
||||
|
||||
rresp_next = AXI_RESP_OKAY;
|
||||
|
||||
m_axi_rready_next = 1'b0;
|
||||
axis_state_next = AXIS_STATE_IDLE;
|
||||
end else begin
|
||||
@ -513,8 +552,9 @@ always @(posedge clk) begin
|
||||
|
||||
s_axis_read_desc_ready_reg <= s_axis_read_desc_ready_next;
|
||||
|
||||
m_axis_read_desc_status_valid_reg <= m_axis_read_desc_status_valid_next;
|
||||
m_axis_read_desc_status_tag_reg <= m_axis_read_desc_status_tag_next;
|
||||
m_axis_read_desc_status_error_reg <= m_axis_read_desc_status_error_next;
|
||||
m_axis_read_desc_status_valid_reg <= m_axis_read_desc_status_valid_next;
|
||||
|
||||
m_axi_araddr_reg <= m_axi_araddr_next;
|
||||
m_axi_arlen_reg <= m_axi_arlen_next;
|
||||
@ -545,6 +585,7 @@ always @(posedge clk) begin
|
||||
bubble_cycle_reg <= bubble_cycle_next;
|
||||
first_cycle_reg <= first_cycle_next;
|
||||
output_last_cycle_reg <= output_last_cycle_next;
|
||||
rresp_reg <= rresp_next;
|
||||
|
||||
tag_reg <= tag_next;
|
||||
axis_id_reg <= axis_id_next;
|
||||
@ -566,6 +607,8 @@ always @(posedge clk) begin
|
||||
m_axis_read_desc_status_valid_reg <= 1'b0;
|
||||
m_axi_arvalid_reg <= 1'b0;
|
||||
m_axi_rready_reg <= 1'b0;
|
||||
|
||||
rresp_reg <= AXI_RESP_OKAY;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -92,6 +92,7 @@ module axi_dma_wr #
|
||||
output wire [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_id,
|
||||
output wire [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_dest,
|
||||
output wire [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_user,
|
||||
output wire [3:0] m_axis_write_desc_status_error,
|
||||
output wire m_axis_write_desc_status_valid,
|
||||
|
||||
/*
|
||||
@ -190,6 +191,25 @@ initial begin
|
||||
end
|
||||
end
|
||||
|
||||
localparam [1:0]
|
||||
AXI_RESP_OKAY = 2'b00,
|
||||
AXI_RESP_EXOKAY = 2'b01,
|
||||
AXI_RESP_SLVERR = 2'b10,
|
||||
AXI_RESP_DECERR = 2'b11;
|
||||
|
||||
localparam [3:0]
|
||||
DMA_ERROR_NONE = 4'd0,
|
||||
DMA_ERROR_TIMEOUT = 4'd1,
|
||||
DMA_ERROR_PARITY = 4'd2,
|
||||
DMA_ERROR_AXI_RD_SLVERR = 4'd4,
|
||||
DMA_ERROR_AXI_RD_DECERR = 4'd5,
|
||||
DMA_ERROR_AXI_WR_SLVERR = 4'd6,
|
||||
DMA_ERROR_AXI_WR_DECERR = 4'd7,
|
||||
DMA_ERROR_PCIE_FLR = 4'd8,
|
||||
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
|
||||
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
|
||||
|
||||
localparam [2:0]
|
||||
STATE_IDLE = 3'd0,
|
||||
STATE_START = 3'd1,
|
||||
@ -223,6 +243,7 @@ reg first_cycle_reg = 1'b0, first_cycle_next;
|
||||
reg input_last_cycle_reg = 1'b0, input_last_cycle_next;
|
||||
reg output_last_cycle_reg = 1'b0, output_last_cycle_next;
|
||||
reg last_transfer_reg = 1'b0, last_transfer_next;
|
||||
reg [1:0] bresp_reg = AXI_RESP_OKAY, bresp_next;
|
||||
|
||||
reg [TAG_WIDTH-1:0] tag_reg = {TAG_WIDTH{1'b0}}, tag_next;
|
||||
reg [AXIS_ID_WIDTH-1:0] axis_id_reg = {AXIS_ID_WIDTH{1'b0}}, axis_id_next;
|
||||
@ -256,6 +277,7 @@ reg [TAG_WIDTH-1:0] m_axis_write_desc_status_tag_reg = {TAG_WIDTH{1'b0}}, m_axis
|
||||
reg [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_id_reg = {AXIS_ID_WIDTH{1'b0}}, m_axis_write_desc_status_id_next;
|
||||
reg [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_dest_reg = {AXIS_DEST_WIDTH{1'b0}}, m_axis_write_desc_status_dest_next;
|
||||
reg [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_user_reg = {AXIS_USER_WIDTH{1'b0}}, m_axis_write_desc_status_user_next;
|
||||
reg [3:0] m_axis_write_desc_status_error_reg = 4'd0, m_axis_write_desc_status_error_next;
|
||||
reg m_axis_write_desc_status_valid_reg = 1'b0, m_axis_write_desc_status_valid_next;
|
||||
|
||||
reg [AXI_ADDR_WIDTH-1:0] m_axi_awaddr_reg = {AXI_ADDR_WIDTH{1'b0}}, m_axi_awaddr_next;
|
||||
@ -291,6 +313,7 @@ assign m_axis_write_desc_status_tag = m_axis_write_desc_status_tag_reg;
|
||||
assign m_axis_write_desc_status_id = m_axis_write_desc_status_id_reg;
|
||||
assign m_axis_write_desc_status_dest = m_axis_write_desc_status_dest_reg;
|
||||
assign m_axis_write_desc_status_user = m_axis_write_desc_status_user_reg;
|
||||
assign m_axis_write_desc_status_error = m_axis_write_desc_status_error_reg;
|
||||
assign m_axis_write_desc_status_valid = m_axis_write_desc_status_valid_reg;
|
||||
|
||||
assign s_axis_write_data_tready = s_axis_write_data_tready_reg;
|
||||
@ -345,6 +368,7 @@ always @* begin
|
||||
m_axis_write_desc_status_id_next = m_axis_write_desc_status_id_reg;
|
||||
m_axis_write_desc_status_dest_next = m_axis_write_desc_status_dest_reg;
|
||||
m_axis_write_desc_status_user_next = m_axis_write_desc_status_user_reg;
|
||||
m_axis_write_desc_status_error_next = m_axis_write_desc_status_error_reg;
|
||||
m_axis_write_desc_status_valid_next = 1'b0;
|
||||
|
||||
s_axis_write_data_tready_next = 1'b0;
|
||||
@ -397,6 +421,12 @@ always @* begin
|
||||
status_fifo_wr_user = axis_user_reg;
|
||||
status_fifo_wr_last = 1'b0;
|
||||
|
||||
if (m_axi_bready && m_axi_bvalid && (m_axi_bresp == AXI_RESP_SLVERR || m_axi_bresp == AXI_RESP_DECERR)) begin
|
||||
bresp_next = m_axi_bresp;
|
||||
end else begin
|
||||
bresp_next = bresp_reg;
|
||||
end
|
||||
|
||||
case (state_reg)
|
||||
STATE_IDLE: begin
|
||||
// idle state - load new descriptor to start operation
|
||||
@ -729,10 +759,21 @@ always @* begin
|
||||
m_axis_write_desc_status_id_next = status_fifo_id[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_write_desc_status_dest_next = status_fifo_dest[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
m_axis_write_desc_status_user_next = status_fifo_user[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
if (bresp_next == AXI_RESP_SLVERR) begin
|
||||
m_axis_write_desc_status_error_next = DMA_ERROR_AXI_WR_SLVERR;
|
||||
end else if (bresp_next == AXI_RESP_DECERR) begin
|
||||
m_axis_write_desc_status_error_next = DMA_ERROR_AXI_WR_DECERR;
|
||||
end else begin
|
||||
m_axis_write_desc_status_error_next = DMA_ERROR_NONE;
|
||||
end
|
||||
m_axis_write_desc_status_valid_next = status_fifo_last[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]];
|
||||
status_fifo_rd_ptr_next = status_fifo_rd_ptr_reg + 1;
|
||||
m_axi_bready_next = 1'b0;
|
||||
|
||||
if (status_fifo_last[status_fifo_rd_ptr_reg[STATUS_FIFO_ADDR_WIDTH-1:0]]) begin
|
||||
bresp_next = AXI_RESP_OKAY;
|
||||
end
|
||||
|
||||
dec_active = 1'b1;
|
||||
end else begin
|
||||
// wait for write completion
|
||||
@ -751,6 +792,7 @@ always @(posedge clk) begin
|
||||
m_axis_write_desc_status_id_reg <= m_axis_write_desc_status_id_next;
|
||||
m_axis_write_desc_status_dest_reg <= m_axis_write_desc_status_dest_next;
|
||||
m_axis_write_desc_status_user_reg <= m_axis_write_desc_status_user_next;
|
||||
m_axis_write_desc_status_error_reg <= m_axis_write_desc_status_error_next;
|
||||
m_axis_write_desc_status_valid_reg <= m_axis_write_desc_status_valid_next;
|
||||
|
||||
s_axis_write_data_tready_reg <= s_axis_write_data_tready_next;
|
||||
@ -775,6 +817,7 @@ always @(posedge clk) begin
|
||||
input_last_cycle_reg <= input_last_cycle_next;
|
||||
output_last_cycle_reg <= output_last_cycle_next;
|
||||
last_transfer_reg <= last_transfer_next;
|
||||
bresp_reg <= bresp_next;
|
||||
|
||||
tag_reg <= tag_next;
|
||||
axis_id_reg <= axis_id_next;
|
||||
@ -825,6 +868,8 @@ always @(posedge clk) begin
|
||||
m_axi_awvalid_reg <= 1'b0;
|
||||
m_axi_bready_reg <= 1'b0;
|
||||
|
||||
bresp_reg <= AXI_RESP_OKAY;
|
||||
|
||||
save_axis_tlast_reg <= 1'b0;
|
||||
shift_axis_extra_cycle_reg <= 1'b0;
|
||||
|
||||
|
@ -42,7 +42,7 @@ DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Des
|
||||
)
|
||||
|
||||
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
|
||||
signals=["tag", "valid"]
|
||||
signals=["tag", "error", "valid"]
|
||||
)
|
||||
|
||||
|
||||
@ -123,6 +123,7 @@ async def run_test(dut, data_in=None, idle_inserter=None, backpressure_inserter=
|
||||
|
||||
tb.log.info("status: %s", status)
|
||||
assert int(status.tag) == cur_tag
|
||||
assert int(status.error) == 0
|
||||
|
||||
tb.log.debug("%s", tb.axi_ram.hexdump_str((write_addr & ~0xf)-16, (((write_addr & 0xf)+length-1) & ~0xf)+48))
|
||||
|
||||
|
@ -45,7 +45,7 @@ DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Des
|
||||
)
|
||||
|
||||
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
|
||||
signals=["tag", "valid"],
|
||||
signals=["tag", "error", "valid"],
|
||||
optional_signals=["len", "id", "dest", "user"]
|
||||
)
|
||||
|
||||
@ -144,6 +144,7 @@ async def run_test_write(dut, data_in=None, idle_inserter=None, backpressure_ins
|
||||
assert int(status.len) == min(len(test_data), len(test_data2))
|
||||
assert int(status.tag) == cur_tag
|
||||
assert int(status.id) == cur_tag
|
||||
assert int(status.error) == 0
|
||||
|
||||
tb.log.debug("%s", tb.axi_ram.hexdump_str((addr & ~0xf)-16, (((addr & 0xf)+length-1) & ~0xf)+48))
|
||||
|
||||
@ -197,6 +198,7 @@ async def run_test_read(dut, data_in=None, idle_inserter=None, backpressure_inse
|
||||
tb.log.info("read_data: %s", read_data)
|
||||
|
||||
assert int(status.tag) == cur_tag
|
||||
assert int(status.error) == 0
|
||||
assert read_data.tdata == test_data
|
||||
assert read_data.tid == cur_tag
|
||||
|
||||
|
@ -44,7 +44,7 @@ DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Des
|
||||
)
|
||||
|
||||
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
|
||||
signals=["tag", "valid"],
|
||||
signals=["tag", "error", "valid"],
|
||||
optional_signals=["len", "id", "dest", "user"]
|
||||
)
|
||||
|
||||
@ -129,6 +129,7 @@ async def run_test_read(dut, data_in=None, idle_inserter=None, backpressure_inse
|
||||
tb.log.info("read_data: %s", read_data)
|
||||
|
||||
assert int(status.tag) == cur_tag
|
||||
assert int(status.error) == 0
|
||||
assert read_data.tdata == test_data
|
||||
assert read_data.tid == cur_tag
|
||||
|
||||
|
@ -44,7 +44,7 @@ DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream("Des
|
||||
)
|
||||
|
||||
DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream("DescStatus",
|
||||
signals=["tag", "valid"],
|
||||
signals=["tag", "error", "valid"],
|
||||
optional_signals=["len", "id", "dest", "user"]
|
||||
)
|
||||
|
||||
@ -132,6 +132,7 @@ async def run_test_write(dut, data_in=None, idle_inserter=None, backpressure_ins
|
||||
assert int(status.len) == min(len(test_data), len(test_data2))
|
||||
assert int(status.tag) == cur_tag
|
||||
assert int(status.id) == cur_tag
|
||||
assert int(status.error) == 0
|
||||
|
||||
tb.log.debug("%s", tb.axi_ram.hexdump_str((addr & ~0xf)-16, (((addr & 0xf)+length-1) & ~0xf)+48))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user