Files
retroSoC/tests/rtl/extension_dma_master_tb.sv
T
maksyuki 98eb8ebad6 feat: add comprehensive tests for AXI4 components and lifecycle controllers
- Implemented tests for AXI4 async bridge functionality, including transfer and warm flush scenarios.
- Added tests for AXI4 data crossbar to validate concurrent outstanding requests and ACL handling.
- Introduced clock frequency monitor tests to ensure detection of clock stop and restart events.
- Developed tests for extension DMA master to verify copy operations, tail strobe behavior, and timeout handling.
- Created tests for HP lifecycle controller to validate drain, flush, and forced reset functionalities.
- Updated existing test scripts to include new RTL components and ensure proper simulation configurations.
2026-08-30 13:15:10 +08:00

126 lines
3.4 KiB
Systemverilog

`timescale 1ns / 1ps
module extension_dma_master_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic start_i = 1'b0;
logic abort_i = 1'b0;
logic quiesce_i = 1'b0;
logic [31:0] src_addr_i = 32'h3000_0000;
logic [31:0] dst_addr_i = 32'h3000_0100;
logic [31:0] len_i = 32'd12;
logic [31:0] timeout_i = 32'd16;
logic busy_o;
logic done_o;
logic err_o;
logic [31:0] fault_addr_o;
axi4_if #(
.ADDR_WIDTH(32),
.DATA_WIDTH(64),
.ID_WIDTH (3),
.USER_WIDTH(1)
) axi4 (
.aclk (clk_i),
.aresetn(rst_n_i)
);
always #5 clk_i = ~clk_i;
extension_dma_master u_dut (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.start_i (start_i),
.abort_i (abort_i),
.quiesce_i (quiesce_i),
.src_addr_i (src_addr_i),
.dst_addr_i (dst_addr_i),
.len_i (len_i),
.timeout_i (timeout_i),
.busy_o (busy_o),
.done_o (done_o),
.err_o (err_o),
.fault_addr_o(fault_addr_o),
.axi4 (axi4)
);
task automatic start_dma;
begin
@(negedge clk_i);
start_i = 1'b1;
@(negedge clk_i);
start_i = 1'b0;
end
endtask
task automatic serve_beat(input logic [31:0] expected_src, input logic [31:0] expected_dst,
input logic [63:0] data, input logic [7:0] expected_strobe);
begin
wait (axi4.arvalid);
if (axi4.araddr != expected_src) $fatal(1, "DMA read address mismatch");
@(posedge clk_i);
@(negedge clk_i);
axi4.rid = 3'd0;
axi4.rdata = data;
axi4.rresp = 2'b00;
axi4.rlast = 1'b1;
axi4.rvalid = 1'b1;
do @(posedge clk_i); while (!axi4.rready);
@(negedge clk_i);
axi4.rvalid = 1'b0;
wait (axi4.awvalid);
if (axi4.awaddr != expected_dst) $fatal(1, "DMA write address mismatch");
@(posedge clk_i);
wait (axi4.wvalid);
if ((axi4.wdata != data) || (axi4.wstrb != expected_strobe) || !axi4.wlast) begin
$fatal(1, "DMA write data or tail strobe mismatch");
end
@(posedge clk_i);
@(negedge clk_i);
axi4.bid = 3'd0;
axi4.bresp = 2'b00;
axi4.bvalid = 1'b1;
do @(posedge clk_i); while (!axi4.bready);
@(negedge clk_i);
axi4.bvalid = 1'b0;
end
endtask
initial begin
axi4.awready = 1'b1;
axi4.wready = 1'b1;
axi4.bid = '0;
axi4.bresp = '0;
axi4.buser = '0;
axi4.bvalid = 1'b0;
axi4.arready = 1'b1;
axi4.rid = '0;
axi4.rdata = '0;
axi4.rresp = '0;
axi4.rlast = 1'b1;
axi4.ruser = '0;
axi4.rvalid = 1'b0;
repeat (2) @(posedge clk_i);
rst_n_i = 1'b1;
start_dma();
serve_beat(32'h3000_0000, 32'h3000_0100, 64'h1122_3344_5566_7788, 8'hFF);
serve_beat(32'h3000_0008, 32'h3000_0108, 64'hAABB_CCDD_EEFF_0011, 8'h0F);
wait (done_o);
if (err_o || busy_o) $fatal(1, "successful DMA copy reported an error");
@(negedge clk_i);
timeout_i = 32'd4;
len_i = 32'd8;
axi4.arready = 1'b0;
start_dma();
wait (done_o);
if (!err_o || (fault_addr_o != src_addr_i)) begin
$fatal(1, "DMA no-progress timeout was not attributed to the source address");
end
$display("Extension DMA copy, tail strobe, and timeout test passed");
$finish;
end
endmodule