mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: enhance DMA functionality with TCD and CRC support
- Added TCD head and count registers to DMA definition and register files. - Introduced CRC expected and result registers for enhanced error checking. - Updated DMA version to 2.0 to reflect new features. - Modified DMA testbench to validate new TCD and CRC functionalities. - Enhanced README and filelists to include new dependencies and configurations. - Updated formal verification and runtime tests to accommodate new DMA features.
This commit is contained in:
28 files changed
+1078
-271
No files matched your search
@@ -8,6 +8,7 @@ module dma_error_tb;
|
||||
localparam logic [31:0] ErrorSource = 32'hDEAD_0000;
|
||||
localparam logic [31:0] StreamSource = 32'h4000_3000;
|
||||
localparam logic [31:0] StreamDestination = 32'h4000_4000;
|
||||
localparam logic [31:0] TcdBase = 32'h4000_8000;
|
||||
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
@@ -17,6 +18,9 @@ module dma_error_tb;
|
||||
logic [NumChannels*32-1:0] byte_count_i = '0;
|
||||
logic [NumChannels*32-1:0] request_sel_i = '0;
|
||||
logic [NumChannels*32-1:0] burst_cfg_i = '0;
|
||||
logic [NumChannels*32-1:0] tcd_head_i = '0;
|
||||
logic [NumChannels*32-1:0] tcd_count_i = '0;
|
||||
logic [NumChannels*32-1:0] crc_expected_i = '0;
|
||||
logic [ NumChannels-1:0] start_i = '0;
|
||||
logic [ NumChannels-1:0] suspend_i = '0;
|
||||
logic [ NumChannels-1:0] resume_i = '0;
|
||||
@@ -38,6 +42,7 @@ module dma_error_tb;
|
||||
logic [NumChannels*32-1:0] bytes_done_o;
|
||||
logic [NumChannels*32-1:0] stall_cycles_lo_o;
|
||||
logic [NumChannels*32-1:0] stall_cycles_hi_o;
|
||||
logic [NumChannels*32-1:0] crc_result_o;
|
||||
logic first_error_valid_o;
|
||||
logic [ 1:0] first_error_channel_o;
|
||||
logic [ 8:0] first_error_status_o;
|
||||
@@ -65,6 +70,7 @@ module dma_error_tb;
|
||||
integer stream_rx_count = 0;
|
||||
logic [ 31:0] written_addr [0:127];
|
||||
logic [ 31:0] written_data [0:127];
|
||||
logic [ 3:0] written_strb [0:127];
|
||||
logic [ 31:0] stream_tx_data [ 0:7];
|
||||
logic stream_tx_last [ 0:7];
|
||||
logic rx_driver_valid_q = 1'b0;
|
||||
@@ -73,6 +79,7 @@ module dma_error_tb;
|
||||
logic rx_driver_last_q = 1'b0;
|
||||
logic stream_tx_ready_enable = 1'b1;
|
||||
logic write_accept_enable = 1'b1;
|
||||
logic [ 31:0] tcd_mem [ 0:15];
|
||||
|
||||
dma_req_if req ();
|
||||
axi4_if axi4 (
|
||||
@@ -103,7 +110,11 @@ module dma_error_tb;
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
function automatic logic [31:0] model_read_data(input logic [31:0] address);
|
||||
model_read_data = 32'hA500_0000 + ((address - SourceBase) >> 2);
|
||||
if ((address >= TcdBase) && (address < (TcdBase + 32'd64))) begin
|
||||
model_read_data = tcd_mem[(address-TcdBase)>>2];
|
||||
end else begin
|
||||
model_read_data = 32'hA500_0000 + ((address - SourceBase) >> 2);
|
||||
end
|
||||
endfunction
|
||||
|
||||
assign axi4.arready = !read_active_q && cycle_q[0];
|
||||
@@ -198,6 +209,7 @@ module dma_error_tb;
|
||||
if (axi4.wvalid && axi4.wready) begin
|
||||
written_addr[write_count] <= write_addr_q + (write_index_q << 2);
|
||||
written_data[write_count] <= axi4.wdata;
|
||||
written_strb[write_count] <= axi4.wstrb;
|
||||
write_count <= write_count + 1;
|
||||
if (axi4.wlast) begin
|
||||
if ((write_index_q + 1'b1) != write_beats_q) begin
|
||||
@@ -243,6 +255,9 @@ module dma_error_tb;
|
||||
.global_reset_i (1'b0),
|
||||
.global_error_clear_i (1'b0),
|
||||
.ch_cfg_i (ch_cfg_i),
|
||||
.tcd_head_i (tcd_head_i),
|
||||
.tcd_count_i (tcd_count_i),
|
||||
.crc_expected_i (crc_expected_i),
|
||||
.src_addr_i (src_addr_i),
|
||||
.dst_addr_i (dst_addr_i),
|
||||
.byte_count_i (byte_count_i),
|
||||
@@ -269,6 +284,7 @@ module dma_error_tb;
|
||||
.bytes_done_o (bytes_done_o),
|
||||
.stall_cycles_lo_o (stall_cycles_lo_o),
|
||||
.stall_cycles_hi_o (stall_cycles_hi_o),
|
||||
.crc_result_o (crc_result_o),
|
||||
.first_error_valid_o (first_error_valid_o),
|
||||
.first_error_channel_o(first_error_channel_o),
|
||||
.first_error_status_o (first_error_status_o),
|
||||
@@ -380,12 +396,61 @@ module dma_error_tb;
|
||||
end
|
||||
end
|
||||
|
||||
error_mode = 1'b1;
|
||||
for (integer index = 0; index < 16; index++) begin
|
||||
tcd_mem[index] = 32'd0;
|
||||
end
|
||||
tcd_mem[1] = CopySource + 32'h200;
|
||||
tcd_mem[2] = CopyDestination + 32'h200;
|
||||
tcd_mem[3] = 32'd8;
|
||||
tcd_mem[7] = 32'h0101_0007;
|
||||
tcd_head_i[0+:32] = TcdBase;
|
||||
tcd_count_i[0+:32] = 32'd1;
|
||||
write_before = write_count;
|
||||
start_channel(0);
|
||||
wait_terminal(0);
|
||||
tcd_head_i[0+:32] = 32'd0;
|
||||
tcd_count_i[0+:32] = 32'd0;
|
||||
if (error_o[0] || (write_count != (write_before + 2)) ||
|
||||
(written_data[write_before] != model_read_data(
|
||||
CopySource + 32'h200
|
||||
)) || (written_data[write_before+1] != model_read_data(
|
||||
CopySource + 32'h204
|
||||
))) begin
|
||||
$fatal(1, "DMA TCD fetch transfer failed count=%0d", write_count);
|
||||
end
|
||||
|
||||
configure_channel(0, 3'd0, 4'd0, CopySource, 1'b1, CopyDestination + 32'h100, 1'b1, 32'd6, 2'd1,
|
||||
5'd16);
|
||||
write_before = write_count;
|
||||
start_channel(0);
|
||||
wait_terminal(0);
|
||||
if (error_o[0] || (write_count != (write_before + 2)) ||
|
||||
(written_strb[write_before] != 4'hF) ||
|
||||
(written_strb[write_before + 1] != 4'h3) || (bytes_done_o[0 +: 32] != 32'd6)) begin
|
||||
$fatal(1, "DMA tail-byte transfer failed count=%0d done=%0d strb=%h/%h", write_count,
|
||||
bytes_done_o[0+:32], written_strb[write_before], written_strb[write_before+1]);
|
||||
end
|
||||
|
||||
configure_channel(0, 3'd0, 4'd0, CopySource, 1'b1, CopyDestination + 32'h300, 1'b1, 32'd8, 2'd1,
|
||||
5'd16);
|
||||
ch_cfg_i[10] = 1'b1;
|
||||
ch_cfg_i[11] = 1'b1;
|
||||
crc_expected_i[0+:32] = 32'h943F_F353;
|
||||
start_channel(0);
|
||||
wait_terminal(0);
|
||||
if (error_o[0] || (crc_result_o[0+:32] != 32'h943F_F353)) begin
|
||||
$fatal(1, "DMA CRC check failed result=%h", crc_result_o[0+:32]);
|
||||
end
|
||||
ch_cfg_i[10] = 1'b0;
|
||||
ch_cfg_i[11] = 1'b0;
|
||||
crc_expected_i[0+:32] = 32'd0;
|
||||
|
||||
error_mode = 1'b1;
|
||||
configure_channel(1, 3'd0, 4'd0, ErrorSource, 1'b1, 32'h4000_5000, 1'b1, 32'd4, 2'd3, 5'd1);
|
||||
start_channel(1);
|
||||
wait_terminal(1);
|
||||
if (!error_o[1] || !first_error_valid_o || (first_error_channel_o != 2'd1) ||
|
||||
(write_count != 20)) begin
|
||||
(write_count != 26)) begin
|
||||
$fatal(1, "DMA read error was not isolated to its channel");
|
||||
end
|
||||
error_mode = 1'b0;
|
||||
@@ -409,7 +474,7 @@ module dma_error_tb;
|
||||
drive_rx_beat(32'h5100_0001, 4'hF, 1'b1);
|
||||
wait_terminal(3);
|
||||
if (error_o[3] || (stream_rx_count != 2) || !stream_last_o[3] ||
|
||||
(written_data[20] != 32'h5100_0000) || (written_data[21] != 32'h5100_0001)) begin
|
||||
(written_data[26] != 32'h5100_0000) || (written_data[27] != 32'h5100_0001)) begin
|
||||
$fatal(1, "DMA AXI4-Stream RX did not write the programmed byte count");
|
||||
end
|
||||
|
||||
|
||||
@@ -206,6 +206,25 @@ module dma_reg_tb;
|
||||
if (value != 32'h444D_4134) begin
|
||||
$fatal(1, "DMA IP identification mismatch");
|
||||
end
|
||||
apb_read(32'h004, value);
|
||||
if (value != 32'h0002_0000) begin
|
||||
$fatal(1, "DMA V2 version mismatch: %h", value);
|
||||
end
|
||||
apb_read(32'h008, value);
|
||||
if ((value[0] != 1'b1) || (value[15:8] != 8'd4)) begin
|
||||
$fatal(1, "DMA capability descriptor/channel mismatch: %h", value);
|
||||
end
|
||||
apb_write(32'h2C8, 32'h4000_8000, 4'hF, 1'b0);
|
||||
apb_write(32'h2CC, 32'h0000_0001, 4'hF, 1'b0);
|
||||
apb_write(32'h2D0, 32'h1234_5678, 4'hF, 1'b0);
|
||||
apb_read(32'h2C8, value);
|
||||
if (value != 32'h4000_8000) begin
|
||||
$fatal(1, "DMA TCD head register mismatch: %h", value);
|
||||
end
|
||||
apb_read(32'h2D0, value);
|
||||
if (value != 32'h1234_5678) begin
|
||||
$fatal(1, "DMA CRC expected register mismatch: %h", value);
|
||||
end
|
||||
apb_write(32'h02c, 32'h1, 4'hF, 1'b1);
|
||||
apb_write(32'h104, 32'h0000_0160, 4'h1, 1'b0);
|
||||
apb_write(32'h108, 32'h4000_0000, 4'hF, 1'b0);
|
||||
|
||||
Reference in new issue
Block a user