mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
- Introduced a new testbench for the AXI4 interconnect () to validate fault classification for decode and access errors. - Updated and to reflect changes in bus naming conventions. - Enhanced to include AXI4-Stream interface checks and validate stream data transfers. - Modified to integrate AXI4-Stream interfaces for improved DMA testing. - Added new Python tests () to verify AXI4 to RIBP burst bridge functionality and interconnect fault classification. - Updated existing tests to include AXI4 interfaces and ensure proper error handling and response validation. - Adjusted memory map generation and test setups to accommodate new AXI4 interface requirements.
149 lines
4.8 KiB
Systemverilog
149 lines
4.8 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
|
|
module bus_fault_tb;
|
|
logic clk_i = 1'b0;
|
|
logic rst_n_i = 1'b0;
|
|
logic fault_valid_o;
|
|
logic [31:0] fault_addr_o;
|
|
logic [ 3:0] fault_wstrb_o;
|
|
logic fault_reserved_o;
|
|
logic fault_access_o;
|
|
logic [ 1:0] fault_master_o;
|
|
logic [ 2:0] fault_code_o;
|
|
logic user_bus_idle_o;
|
|
ribp_if mgmt_ribp ();
|
|
rib_if user_rib ();
|
|
rib_if dma_rib ();
|
|
rib_if rib ();
|
|
rib_if apb_rib ();
|
|
|
|
always #5 clk_i = ~clk_i;
|
|
|
|
assign rib.cmd_ready = 1'b1;
|
|
assign rib.w_ready = 1'b1;
|
|
assign rib.rsp_valid = 1'b0;
|
|
assign rib.rdata = 32'hCAFE_BABE;
|
|
assign rib.resp_err = 1'b0;
|
|
assign rib.resp_code = `RIB_RESP_OK;
|
|
assign rib.rsp_beat = '0;
|
|
assign rib.rsp_last = 1'b0;
|
|
assign apb_rib.cmd_ready = 1'b1;
|
|
assign apb_rib.w_ready = 1'b1;
|
|
assign apb_rib.rsp_valid = 1'b0;
|
|
assign apb_rib.rdata = 32'h1234_5678;
|
|
assign apb_rib.resp_err = 1'b0;
|
|
assign apb_rib.resp_code = `RIB_RESP_OK;
|
|
assign apb_rib.rsp_beat = '0;
|
|
assign apb_rib.rsp_last = 1'b1;
|
|
|
|
rib_bus u_bus (
|
|
.clk_i (clk_i),
|
|
.rst_n_i (rst_n_i),
|
|
.mgmt_ribp (mgmt_ribp),
|
|
.user_rib (user_rib),
|
|
.dma_rib (dma_rib),
|
|
.user_bus_enable_i(1'b1),
|
|
.user_bus_idle_o (user_bus_idle_o),
|
|
.rib (rib),
|
|
.apb_rib (apb_rib),
|
|
.perf_enable_i (1'b0),
|
|
.perf_clear_i (1'b0),
|
|
.fault_valid_o (fault_valid_o),
|
|
.fault_addr_o (fault_addr_o),
|
|
.fault_wstrb_o (fault_wstrb_o),
|
|
.fault_reserved_o (fault_reserved_o),
|
|
.fault_access_o (fault_access_o),
|
|
.fault_master_o (fault_master_o),
|
|
.fault_code_o (fault_code_o)
|
|
);
|
|
|
|
task automatic expect_fault(input logic [31:0] address, input logic [3:0] write_strobes,
|
|
input logic reserved, input logic [2:0] expected_code);
|
|
begin
|
|
@(negedge clk_i);
|
|
mgmt_ribp.addr = address;
|
|
mgmt_ribp.wdata = 32'hA5A5_5A5A;
|
|
mgmt_ribp.wstrb = write_strobes;
|
|
mgmt_ribp.valid = 1'b1;
|
|
while (!fault_valid_o) @(posedge clk_i);
|
|
if (fault_addr_o !== address || fault_wstrb_o !== write_strobes ||
|
|
fault_reserved_o !== reserved || fault_access_o || fault_code_o !== expected_code ||
|
|
rib.cmd_valid || apb_rib.cmd_valid) begin
|
|
$fatal(1, "unexpected fault response for address %h", address);
|
|
end
|
|
while (!mgmt_ribp.ready) @(posedge clk_i);
|
|
if (mgmt_ribp.rdata !== 32'd0 || !mgmt_ribp.resp_err) begin
|
|
$fatal(1, "fault response data must be zero");
|
|
end
|
|
@(negedge clk_i);
|
|
mgmt_ribp.valid = 1'b0;
|
|
while (fault_valid_o) @(posedge clk_i);
|
|
end
|
|
endtask
|
|
|
|
task automatic expect_user_denied(input logic [31:0] address, input logic [3:0] write_strobes);
|
|
begin
|
|
@(negedge clk_i);
|
|
user_rib.cmd_addr = address;
|
|
user_rib.cmd_write = |write_strobes;
|
|
user_rib.cmd_len = `RIB_LEN_INCR1;
|
|
user_rib.cmd_valid = 1'b1;
|
|
while (!user_rib.cmd_ready) @(posedge clk_i);
|
|
@(negedge clk_i);
|
|
user_rib.cmd_valid = 1'b0;
|
|
if (|write_strobes) begin
|
|
user_rib.wdata = 32'h5A5A_A5A5;
|
|
user_rib.wstrb = write_strobes;
|
|
user_rib.wlast = 1'b1;
|
|
user_rib.w_valid = 1'b1;
|
|
while (!user_rib.w_ready) @(posedge clk_i);
|
|
@(negedge clk_i);
|
|
user_rib.w_valid = 1'b0;
|
|
end
|
|
while (!fault_valid_o) @(posedge clk_i);
|
|
if (!fault_access_o || fault_master_o != 2'd1 || rib.cmd_valid || apb_rib.cmd_valid) begin
|
|
$fatal(1, "user access was not denied locally");
|
|
end
|
|
if (user_rib.rdata !== 32'd0 || !user_rib.resp_err || !user_rib.rsp_last ||
|
|
user_rib.resp_code !== `RIB_RESP_PROTERR) begin
|
|
$fatal(1, "denied user response data must be zero");
|
|
end
|
|
while (fault_valid_o) @(posedge clk_i);
|
|
end
|
|
endtask
|
|
|
|
initial begin
|
|
mgmt_ribp.valid = 1'b0;
|
|
mgmt_ribp.addr = '0;
|
|
mgmt_ribp.wdata = '0;
|
|
mgmt_ribp.wstrb = '0;
|
|
user_rib.cmd_valid = 1'b0;
|
|
user_rib.cmd_addr = '0;
|
|
user_rib.cmd_write = 1'b0;
|
|
user_rib.cmd_len = `RIB_LEN_INCR1;
|
|
user_rib.w_valid = 1'b0;
|
|
user_rib.wdata = '0;
|
|
user_rib.wstrb = '0;
|
|
user_rib.wlast = 1'b0;
|
|
user_rib.rsp_ready = 1'b1;
|
|
dma_rib.cmd_valid = 1'b0;
|
|
dma_rib.cmd_addr = '0;
|
|
dma_rib.cmd_write = 1'b0;
|
|
dma_rib.cmd_len = `RIB_LEN_INCR1;
|
|
dma_rib.w_valid = 1'b0;
|
|
dma_rib.wdata = '0;
|
|
dma_rib.wstrb = '0;
|
|
dma_rib.wlast = 1'b0;
|
|
dma_rib.rsp_ready = 1'b1;
|
|
|
|
repeat (2) @(posedge clk_i);
|
|
rst_n_i = 1'b1;
|
|
|
|
expect_fault(32'h1000_F000, 4'hF, 1'b1, `RIB_RESP_RESERVED);
|
|
expect_fault(32'hA000_0000, 4'h0, 1'b0, `RIB_RESP_DECERR);
|
|
expect_user_denied(32'h1000_B000, 4'hF);
|
|
$display("bus fault responder test passed");
|
|
$finish;
|
|
end
|
|
endmodule
|