Files
retroSoC/tests/rtl/fabric_monitor_tb.sv
T
maksyuki d164a562ad feate: add fabric monitor and enhance AXI4 data crossbar tests
- Introduced  and its corresponding testbench  to monitor fabric interactions.
- Updated  to include additional checks for ACL and QoS, enhancing the test coverage.
- Modified  to include the new fabric monitor file.
- Created a new test file  to validate the functionality of the fabric monitor.
- Updated  to integrate the fabric monitor interface.
- Adjusted  to reflect changes in the AXI4 data crossbar test output.
- Enhanced  to ensure proper generation of connections for the fabric monitor.
- Updated user extension tests to account for new local SRAM and stream definitions.
2026-08-31 10:02:19 +08:00

190 lines
6.7 KiB
Systemverilog

`timescale 1ns / 1ps
module fabric_monitor_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic [ 7:0] master_read_accept_i = '0;
logic [ 7:0] master_write_accept_i = '0;
logic [ 7:0] master_read_beat_i = '0;
logic [ 7:0] master_write_beat_i = '0;
logic [ 7:0] master_wait_i = '0;
logic [ 7:0] master_promotion_i = '0;
logic [ 7:0][2:0] master_read_outstanding_i = '0;
logic [ 7:0][2:0] master_write_outstanding_i = '0;
logic [ 5:0] target_read_accept_i = '0;
logic [ 5:0] target_write_accept_i = '0;
logic [ 5:0] target_read_beat_i = '0;
logic [ 5:0] target_write_beat_i = '0;
logic [ 5:0] target_wait_i = '0;
logic [ 5:0] target_timeout_i = '0;
logic [ 5:0] target_isolated_i = '0;
logic [ 5:0][2:0] target_read_outstanding_i = '0;
logic [ 5:0][2:0] target_write_outstanding_i = '0;
logic fault_valid_i = 1'b0;
logic [31:0] read_data;
apb4_if apb4 (
.pclk (clk_i),
.presetn(rst_n_i)
);
always #5 clk_i = ~clk_i;
fabric_monitor u_dut (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.idle_i (1'b0),
.recovery_i (1'b1),
.flush_busy_i (1'b0),
.flush_i (target_timeout_i[5]),
.outstanding_read_i (8'd2),
.outstanding_write_i (8'd1),
.fault_valid_i (fault_valid_i),
.fault_master_i (3'd5),
.fault_target_i (3'd2),
.fault_addr_i (32'h4000_0040),
.fault_write_i (1'b1),
.fault_reason_i (4'd5),
.master_read_accept_i (master_read_accept_i),
.master_write_accept_i (master_write_accept_i),
.master_read_beat_i (master_read_beat_i),
.master_write_beat_i (master_write_beat_i),
.master_wait_i (master_wait_i),
.master_promotion_i (master_promotion_i),
.master_read_outstanding_i (master_read_outstanding_i),
.master_write_outstanding_i(master_write_outstanding_i),
.target_read_accept_i (target_read_accept_i),
.target_write_accept_i (target_write_accept_i),
.target_read_beat_i (target_read_beat_i),
.target_write_beat_i (target_write_beat_i),
.target_wait_i (target_wait_i),
.target_timeout_i (target_timeout_i),
.target_isolated_i (target_isolated_i),
.target_read_outstanding_i (target_read_outstanding_i),
.target_write_outstanding_i(target_write_outstanding_i),
.apb4 (apb4)
);
task automatic apb_write(input logic [11:0] offset, input logic [31:0] data);
begin
@(negedge clk_i);
apb4.paddr = {20'd0, offset};
apb4.pwrite = 1'b1;
apb4.pwdata = data;
apb4.pstrb = 4'hF;
apb4.psel = 1'b1;
apb4.penable = 1'b1;
do @(posedge clk_i); while (!apb4.pready);
if (apb4.pslverr) $fatal(1, "fabric monitor write failed at %h", offset);
@(negedge clk_i);
apb4.psel = 1'b0;
apb4.penable = 1'b0;
apb4.pwrite = 1'b0;
apb4.pstrb = '0;
end
endtask
task automatic apb_read(input logic [11:0] offset, output logic [31:0] data);
begin
@(negedge clk_i);
apb4.paddr = {20'd0, offset};
apb4.pwrite = 1'b0;
apb4.pstrb = '0;
apb4.psel = 1'b1;
apb4.penable = 1'b1;
do @(posedge clk_i); while (!apb4.pready);
if (apb4.pslverr) $fatal(1, "fabric monitor read failed at %h", offset);
data = apb4.prdata;
@(negedge clk_i);
apb4.psel = 1'b0;
apb4.penable = 1'b0;
end
endtask
initial begin
apb4.paddr = '0;
apb4.pprot = '0;
apb4.psel = 1'b0;
apb4.penable = 1'b0;
apb4.pwrite = 1'b0;
apb4.pwdata = '0;
apb4.pstrb = '0;
repeat (3) @(posedge clk_i);
rst_n_i = 1'b1;
apb_write(12'h00C, 32'h0000_0001);
@(negedge clk_i);
master_read_accept_i[0] = 1'b1;
master_read_beat_i[0] = 1'b1;
master_promotion_i[0] = 1'b1;
master_read_outstanding_i[0] = 3'd3;
target_read_accept_i[2] = 1'b1;
target_read_beat_i[2] = 1'b1;
target_read_outstanding_i[2] = 3'd2;
@(negedge clk_i);
master_read_accept_i = '0;
master_read_beat_i = '0;
master_promotion_i = '0;
target_read_accept_i = '0;
target_read_beat_i = '0;
repeat (3) begin
master_wait_i[0] = 1'b1;
target_wait_i[2] = 1'b1;
@(negedge clk_i);
end
master_wait_i = '0;
target_wait_i = '0;
target_timeout_i[2] = 1'b1;
target_isolated_i[2] = 1'b1;
fault_valid_i = 1'b1;
@(negedge clk_i);
target_timeout_i[2] = 1'b0;
fault_valid_i = 1'b0;
target_timeout_i[5] = 1'b1;
@(negedge clk_i);
target_timeout_i[5] = 1'b0;
apb_write(12'h00C, 32'h0000_0009);
apb_read(12'h100, read_data);
if (read_data != 32'd1) $fatal(1, "master read request count mismatch");
apb_read(12'h110, read_data);
if (read_data != 32'd3) $fatal(1, "master wait count mismatch");
apb_read(12'h114, read_data);
if (read_data != 32'd3) $fatal(1, "master max wait mismatch");
apb_read(12'h118, read_data);
if (read_data != 32'd1) $fatal(1, "master promotion count mismatch");
apb_read(12'h11C, read_data);
if (read_data[2:0] != 3'd3) $fatal(1, "master high-water mismatch");
apb_read(12'h340, read_data);
if (read_data != 32'd1) $fatal(1, "target read request count mismatch");
apb_read(12'h350, read_data);
if (read_data != 32'd3) $fatal(1, "target wait count mismatch");
apb_read(12'h354, read_data);
if (read_data != 32'd1) $fatal(1, "target timeout count mismatch");
apb_read(12'h358, read_data);
if (read_data != 32'd1) $fatal(1, "target isolation mismatch");
apb_read(12'h01C, read_data);
if (read_data != 32'd1) $fatal(1, "flush count mismatch");
apb_read(12'h018, read_data);
if (read_data != 32'h4000_0040) $fatal(1, "fault address mismatch");
apb_read(12'h014, read_data);
if (read_data != 32'h0000_0557) $fatal(1, "sticky fault attribution mismatch");
apb_read(12'h020, read_data);
if (read_data != 32'd1) $fatal(1, "fault count mismatch");
apb_write(12'h00C, 32'h0000_0005);
apb_read(12'h100, read_data);
if (read_data != 32'd0) $fatal(1, "snapshot did not clear");
apb_read(12'h014, read_data);
if (read_data != 32'd0) $fatal(1, "sticky fault did not clear");
$display("Fabric Monitor counter, snapshot, and clear test passed");
$finish;
end
initial begin
repeat (400) @(posedge clk_i);
$fatal(1, "Fabric Monitor test timed out");
end
endmodule