feat: add APU-P1 support and enhance test coverage

- Introduced new task  in  for handling high-performance APU writes with access fault checks.
- Updated  to support an expanded resource count, including ownership and IRQ routing for the new APU resource.
- Enhanced  to validate IRQ expectations for the newly added APU resource.
- Created  for directed verification of APU-P1 APB4 register shell and integrated IRQ ownership topology.
- Added  to ensure synchronization between RTL and SDK register ABI.
- Modified  to parameterize tests for product modes, improving flexibility in testing.
- Updated  to reflect changes in APU memory mapping and ensure correct assertions.
- Enhanced  to validate the complete IRQ and resource allocations for the APU.
This commit is contained in:
maksyuki committed 2026-09-02 22:00:45 +08:00
1 parent eb47bdef4c
commit 52f619b9dc
41 files changed
+2385 -134

No files matched your search

+2 -2
View File
@@ -16,7 +16,7 @@ module apb4_topology_tb;
begin
s_decode_addr = address;
#1;
if (s_psel_comb !== (20'd1 << slot)) begin
if (s_psel_comb !== (28'd1 << slot)) begin
$fatal(1, "unexpected APB4 target slot for %h: got %b", address, s_psel_comb);
end
end
@@ -44,7 +44,7 @@ module apb4_topology_tb;
expect_select(`SOC_ADDR_APB4_SDIO1_BASE, 18);
expect_select(`SOC_ADDR_APB4_CRYPTO_BASE, 19);
expect_disabled(`SOC_ADDR_APB4_GA_BASE);
expect_disabled(`SOC_ADDR_APB4_APU_BASE);
expect_select(`SOC_ADDR_APB4_APU_BASE, 27);
$display("SoC topology APB4 routing test passed");
$finish;
end
+271
View File
@@ -0,0 +1,271 @@
`timescale 1ns / 1ps
`include "apu_define.svh"
`include "soc_irq_config.svh"
module apu_irq_topology_tb;
localparam logic [31:0] ApuBase = 32'h1001_3000;
localparam logic [11:0] Resource7Owner = 12'h1e0;
localparam logic [11:0] Resource7Control = 12'h1e4;
localparam logic [11:0] Resource7Fault = 12'h1ec;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic s_apu_idle;
logic s_apu_irq_raw;
logic [ 7:0] s_resource_idle;
logic [ 7:0] s_resource_block_ack;
logic [ 7:0] s_resource_irq_raw;
logic [ 7:0][1:0] s_resource_owner;
logic [ 7:0] s_resource_owner_lock;
logic [ 7:0] s_resource_quiesce;
logic [ 7:0] s_resource_reset;
logic [ 7:0] s_resource_irq_lp;
logic [ 7:0] s_resource_irq_hp;
logic [ 6:0] s_resource_irq_lp_compact;
logic [ 6:0] s_resource_irq_hp_compact;
logic s_resource_fault_irq;
logic s_cache_clean;
logic [`SOC_IRQ_APB4_PERIPH_WIDTH-1:0] s_apb4_periph_irq;
logic [`SOC_IRQ_APB4_SYSTEM_WIDTH-1:0] s_apb4_system_irq;
logic [ `SOC_IRQ_VECTOR_WIDTH-1:0] s_irq;
logic [ 31:0] s_hp_plic_source;
logic [ 1:0] s_hp_plic_context_irq;
logic [ 31:0] s_value;
apb4_if u_apu_apb4_if (
.pclk (clk_i),
.presetn(rst_n_i)
);
apb4_if u_resource_apb4_if (
.pclk (clk_i),
.presetn(rst_n_i)
);
apb4_if u_plic_apb4_if (
.pclk (clk_i),
.presetn(rst_n_i)
);
always #5 clk_i = ~clk_i;
assign s_resource_idle = {s_apu_idle, 7'h7f};
assign s_resource_block_ack = {
s_apu_idle && (s_resource_quiesce[7] || s_resource_reset[7]), 7'd0
};
assign s_resource_irq_raw = {s_apu_irq_raw, 7'd0};
assign s_resource_irq_lp_compact = {s_resource_irq_lp[7:6], s_resource_irq_lp[4:0]};
assign s_resource_irq_hp_compact = {s_resource_irq_hp[7:6], s_resource_irq_hp[4:0]};
assign s_apb4_periph_irq = {s_resource_irq_lp_compact[6], 23'd0};
assign s_apb4_system_irq = '0;
assign s_hp_plic_source = {21'd0, s_resource_irq_hp_compact[6], 10'd0};
`include "soc_irq_wiring.svh"
apb4_apu u_apu (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.owner_i (s_resource_owner[7]),
.owner_lock_i (s_resource_owner_lock[7]),
.quiesce_i (s_resource_quiesce[7]),
.resource_reset_i(s_resource_reset[7]),
.apb4 (u_apu_apb4_if),
.idle_o (s_apu_idle),
.irq_o (s_apu_irq_raw)
);
resource_controller #(
.ResourceCount(8)
) u_resource_controller (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.idle_i (s_resource_idle),
.block_ack_i (s_resource_block_ack),
.irq_i (s_resource_irq_raw),
.cache_request_i(1'b0),
.cache_clean_o (s_cache_clean),
.owner_o (s_resource_owner),
.owner_lock_o (s_resource_owner_lock),
.quiesce_o (s_resource_quiesce),
.reset_o (s_resource_reset),
.irq_lp_o (s_resource_irq_lp),
.irq_hp_o (s_resource_irq_hp),
.fault_irq_o (s_resource_fault_irq),
.apb4 (u_resource_apb4_if)
);
apb4_plic u_hp_plic (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.source_i (s_hp_plic_source),
.apb4 (u_plic_apb4_if),
.context_irq_o(s_hp_plic_context_irq)
);
task automatic drive_apb_idle;
begin
u_apu_apb4_if.paddr = 32'd0;
u_apu_apb4_if.pprot = 3'd0;
u_apu_apb4_if.psel = 1'b0;
u_apu_apb4_if.penable = 1'b0;
u_apu_apb4_if.pwrite = 1'b0;
u_apu_apb4_if.pwdata = 32'd0;
u_apu_apb4_if.pstrb = 4'd0;
u_resource_apb4_if.paddr = 32'd0;
u_resource_apb4_if.pprot = 3'd0;
u_resource_apb4_if.psel = 1'b0;
u_resource_apb4_if.penable = 1'b0;
u_resource_apb4_if.pwrite = 1'b0;
u_resource_apb4_if.pwdata = 32'd0;
u_resource_apb4_if.pstrb = 4'd0;
u_plic_apb4_if.paddr = 32'd0;
u_plic_apb4_if.pprot = 3'd0;
u_plic_apb4_if.psel = 1'b0;
u_plic_apb4_if.penable = 1'b0;
u_plic_apb4_if.pwrite = 1'b0;
u_plic_apb4_if.pwdata = 32'd0;
u_plic_apb4_if.pstrb = 4'd0;
end
endtask
task automatic apu_write(input logic [11:0] offset_i, input logic [31:0] data_i);
begin
@(negedge clk_i);
u_apu_apb4_if.paddr = ApuBase + offset_i;
u_apu_apb4_if.pwdata = data_i;
u_apu_apb4_if.pstrb = 4'hf;
u_apu_apb4_if.pwrite = 1'b1;
u_apu_apb4_if.psel = 1'b1;
u_apu_apb4_if.penable = 1'b0;
@(negedge clk_i);
u_apu_apb4_if.penable = 1'b1;
while (!u_apu_apb4_if.pready) @(negedge clk_i);
if (u_apu_apb4_if.pslverr) $fatal(1, "APU topology write failed at %h", offset_i);
@(negedge clk_i);
u_apu_apb4_if.psel = 1'b0;
u_apu_apb4_if.penable = 1'b0;
u_apu_apb4_if.pwrite = 1'b0;
u_apu_apb4_if.pstrb = 4'd0;
end
endtask
task automatic resource_write(input logic [11:0] offset_i, input logic [31:0] data_i,
input logic expected_err_i);
begin
@(negedge clk_i);
u_resource_apb4_if.paddr = {20'd0, offset_i};
u_resource_apb4_if.pwdata = data_i;
u_resource_apb4_if.pstrb = 4'hf;
u_resource_apb4_if.pwrite = 1'b1;
u_resource_apb4_if.psel = 1'b1;
u_resource_apb4_if.penable = 1'b0;
@(negedge clk_i);
u_resource_apb4_if.penable = 1'b1;
while (!u_resource_apb4_if.pready) @(negedge clk_i);
if (u_resource_apb4_if.pslverr != expected_err_i) begin
$fatal(1, "Resource topology write response mismatch at %h", offset_i);
end
@(negedge clk_i);
u_resource_apb4_if.psel = 1'b0;
u_resource_apb4_if.penable = 1'b0;
u_resource_apb4_if.pwrite = 1'b0;
u_resource_apb4_if.pstrb = 4'd0;
end
endtask
task automatic plic_write(input logic [25:0] offset_i, input logic [31:0] data_i);
begin
@(negedge clk_i);
u_plic_apb4_if.paddr = {6'd0, offset_i};
u_plic_apb4_if.pwdata = data_i;
u_plic_apb4_if.pstrb = 4'hf;
u_plic_apb4_if.pwrite = 1'b1;
u_plic_apb4_if.psel = 1'b1;
u_plic_apb4_if.penable = 1'b0;
@(negedge clk_i);
u_plic_apb4_if.penable = 1'b1;
while (!u_plic_apb4_if.pready) @(negedge clk_i);
if (u_plic_apb4_if.pslverr) $fatal(1, "PLIC topology write failed at %h", offset_i);
@(negedge clk_i);
u_plic_apb4_if.psel = 1'b0;
u_plic_apb4_if.penable = 1'b0;
u_plic_apb4_if.pwrite = 1'b0;
u_plic_apb4_if.pstrb = 4'd0;
end
endtask
task automatic plic_read(input logic [25:0] offset_i, output logic [31:0] data_o);
begin
@(negedge clk_i);
u_plic_apb4_if.paddr = {6'd0, offset_i};
u_plic_apb4_if.pstrb = 4'd0;
u_plic_apb4_if.pwrite = 1'b0;
u_plic_apb4_if.psel = 1'b1;
u_plic_apb4_if.penable = 1'b0;
@(negedge clk_i);
u_plic_apb4_if.penable = 1'b1;
while (!u_plic_apb4_if.pready) @(negedge clk_i);
if (u_plic_apb4_if.pslverr) $fatal(1, "PLIC topology read failed at %h", offset_i);
data_o = u_plic_apb4_if.prdata;
@(negedge clk_i);
u_plic_apb4_if.psel = 1'b0;
u_plic_apb4_if.penable = 1'b0;
end
endtask
initial begin
drive_apb_idle();
repeat (4) @(posedge clk_i);
rst_n_i = 1'b1;
plic_write(26'h000028, 32'd3);
plic_write(26'h002000, 32'h0000_0400);
plic_write(26'h200000, 32'd0);
apu_write(`APB4_APU__IRQ_ENABLE, 32'h0000_0001);
apu_write(`APB4_APU__IRQ_TEST, 32'h0000_0001);
repeat (2) @(posedge clk_i);
#1;
if ((s_resource_owner[7] != 2'd0) || !s_resource_irq_lp[7] || s_resource_irq_hp[7] ||
!s_apb4_periph_irq[23] || !s_irq[31] || s_hp_plic_source[10] ||
s_hp_plic_context_irq[0]) begin
$fatal(1, "APU event was not delivered exclusively to LP IRQ31");
end
resource_write(Resource7Control, 32'h0000_0001, 1'b0);
resource_write(Resource7Owner, 32'h0000_0101, 1'b0);
repeat (2) @(posedge clk_i);
#1;
if ((s_resource_owner[7] != 2'd1) || !s_resource_owner_lock[7] ||
s_resource_irq_lp[7] || !s_resource_irq_hp[7] || s_apb4_periph_irq[23] ||
s_irq[31] || !s_hp_plic_source[10] || !s_hp_plic_context_irq[0]) begin
$fatal(1, "APU event was not delivered exclusively to HP PLIC source 10");
end
plic_read(26'h200004, s_value);
if (s_value != 32'd10) $fatal(1, "HP PLIC did not claim APU source 10");
resource_write(Resource7Owner, 32'd0, 1'b1);
if ((s_resource_owner[7] != 2'd1) || !s_resource_owner_lock[7] || !s_resource_fault_irq) begin
$fatal(1, "APU owner lock did not preserve HP ownership");
end
resource_write(Resource7Fault, 32'h0000_0001, 1'b0);
if (s_resource_fault_irq) $fatal(1, "APU resource fault did not clear");
resource_write(Resource7Control, 32'h0000_0003, 1'b0);
repeat (2) @(posedge clk_i);
#1;
if (s_resource_irq_lp[7] || s_resource_irq_hp[7] || s_apb4_periph_irq[23] || s_irq[31] ||
s_hp_plic_source[10]) begin
$fatal(1, "APU resource reset did not mask both interrupt routes");
end
if (s_resource_fault_irq || s_cache_clean) begin
$fatal(1, "APU topology test left an unrelated controller output asserted");
end
$display("APU-P1 integrated IRQ ownership topology passed");
$finish;
end
initial begin
repeat (1000) @(posedge clk_i);
$fatal(1, "APU-P1 IRQ ownership topology timed out");
end
endmodule
+542
View File
@@ -0,0 +1,542 @@
`timescale 1ns / 1ps
`include "apu_define.svh"
module apu_reg_tb;
localparam logic [31:0] ApuBase = 32'h1001_3000;
localparam int unsigned RegisterCount = 95;
localparam logic [1:0] AccessRo = 2'd0;
localparam logic [1:0] AccessWo = 2'd1;
localparam logic [1:0] AccessRw = 2'd2;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic [ 1:0] owner_i = 2'd0;
logic owner_lock_i = 1'b0;
logic quiesce_i = 1'b0;
logic resource_reset_i = 1'b0;
logic idle_o;
logic irq_o;
logic [31:0] s_value;
logic [11:0] s_reg_offset [RegisterCount];
logic [ 1:0] s_reg_access [RegisterCount];
logic [31:0] s_reg_reset [RegisterCount];
logic s_reg_full_strobe [RegisterCount];
int unsigned s_reg_count;
apb4_if apb4 (
.pclk (clk_i),
.presetn(rst_n_i)
);
always #5 clk_i = ~clk_i;
apb4_apu u_dut (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.owner_i (owner_i),
.owner_lock_i (owner_lock_i),
.quiesce_i (quiesce_i),
.resource_reset_i(resource_reset_i),
.apb4 (apb4),
.idle_o (idle_o),
.irq_o (irq_o)
);
function automatic logic [31:0] legal_write_value(input logic [11:0] offset_i);
case (offset_i)
`APB4_APU__IRQ_STATE: legal_write_value = 32'h0000_07ff;
`APB4_APU__IRQ_ENABLE: legal_write_value = 32'h0000_0005;
`APB4_APU__ERROR_STATUS: legal_write_value = 32'h0000_0001;
`APB4_APU__SEQUENCER_TIMEOUT: legal_write_value = 32'h1234_5678;
`APB4_APU__STREAM_ROUTE: legal_write_value = 32'd0;
`APB4_APU__READ_BASE: legal_write_value = 32'h3000_0000;
`APB4_APU__READ_LIMIT: legal_write_value = 32'h3000_ffff;
`APB4_APU__WRITE_BASE: legal_write_value = 32'h3001_0000;
`APB4_APU__WRITE_LIMIT: legal_write_value = 32'h3001_ffff;
`APB4_APU__DMA_TIMEOUT: legal_write_value = 32'h8765_4321;
`APB4_APU__MC_IMAGE_ADDRESS: legal_write_value = 32'h3002_0000;
`APB4_APU__MC_IMAGE_SIZE: legal_write_value = 32'h0000_0040;
`APB4_APU__MC_EXPECTED_CRC: legal_write_value = 32'ha5a5_5a5a;
`APB4_APU__JOB_CONTROL: legal_write_value = 32'h0000_0121;
`APB4_APU__JOB_INPUT_ADDRESS: legal_write_value = 32'h3003_0000;
`APB4_APU__JOB_INPUT_LENGTH: legal_write_value = 32'h0000_0100;
`APB4_APU__JOB_OUTPUT_ADDRESS: legal_write_value = 32'h3003_1000;
`APB4_APU__JOB_OUTPUT_CAPACITY: legal_write_value = 32'h0000_1000;
`APB4_APU__JOB_INPUT_CONFIG: legal_write_value = 32'h0012_3456;
`APB4_APU__JOB_OUTPUT_CONFIG: legal_write_value = 32'h0001_2345;
`APB4_APU__JOB_FLAGS: legal_write_value = 32'h0000_0001;
`APB4_APU__RING_BASE: legal_write_value = 32'h3004_0000;
`APB4_APU__RING_SIZE: legal_write_value = 32'h0000_0008;
`APB4_APU__RING_TAIL: legal_write_value = 32'h0000_0003;
`APB4_APU__RING_CONTROL: legal_write_value = 32'h0000_0001;
`APB4_APU__RING_COALESCE: legal_write_value = 32'h0004_0002;
`APB4_APU__KWS_MODEL_ADDRESS: legal_write_value = 32'h3005_0000;
`APB4_APU__KWS_MODEL_SIZE: legal_write_value = 32'h0000_0100;
`APB4_APU__KWS_MODEL_EXPECTED_CRC: legal_write_value = 32'h5a5a_a5a5;
`APB4_APU__KWS_CONTROL: legal_write_value = 32'h0000_0004;
`APB4_APU__KWS_CONFIG: legal_write_value = 32'h0000_0590;
`APB4_APU__PERF_CONTROL: legal_write_value = 32'h0000_0001;
default: legal_write_value = 32'd0;
endcase
endfunction
function automatic logic [31:0] legal_readback_value(input logic [11:0] offset_i);
case (offset_i)
`APB4_APU__IRQ_STATE, `APB4_APU__ERROR_STATUS, `APB4_APU__STREAM_ROUTE,
`APB4_APU__KWS_CONTROL:
legal_readback_value = 32'd0;
default: legal_readback_value = legal_write_value(offset_i);
endcase
endfunction
function automatic logic [31:0] reset_or_preserved_value(input logic [11:0] offset_i,
input logic [31:0] reset_i);
case (offset_i)
`APB4_APU__READ_BASE, `APB4_APU__READ_LIMIT, `APB4_APU__WRITE_BASE, `APB4_APU__WRITE_LIMIT:
reset_or_preserved_value = legal_write_value(offset_i);
default: reset_or_preserved_value = reset_i;
endcase
endfunction
task automatic add_register(input logic [11:0] offset_i, input logic [1:0] access_i,
input logic [31:0] reset_i, input logic full_strobe_i);
begin
if (s_reg_count >= RegisterCount) $fatal(1, "APU register table overflow");
s_reg_offset[s_reg_count] = offset_i;
s_reg_access[s_reg_count] = access_i;
s_reg_reset[s_reg_count] = reset_i;
s_reg_full_strobe[s_reg_count] = full_strobe_i;
s_reg_count++;
end
endtask
task automatic initialize_register_table;
begin
s_reg_count = 0;
add_register(`APB4_APU__IP_ID, AccessRo, 32'h4150_5530, 1'b0);
add_register(`APB4_APU__IP_VERSION, AccessRo, 32'h0001_0000, 1'b0);
add_register(`APB4_APU__CAPABILITY0, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__CAPABILITY1, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__COMMAND, AccessWo, 32'd0, 1'b1);
add_register(`APB4_APU__STATUS, AccessRo, 32'h0000_0100, 1'b0);
add_register(`APB4_APU__IRQ_STATE, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__IRQ_ENABLE, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__IRQ_TEST, AccessWo, 32'd0, 1'b1);
add_register(`APB4_APU__ERROR_STATUS, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__ERROR_ADDRESS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__ERROR_DETAIL, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__SEQUENCER_TIMEOUT, AccessRw, 32'h0000_ffff, 1'b0);
add_register(`APB4_APU__STREAM_ROUTE, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__STREAM_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__OWNER_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__READ_BASE, AccessRw, 32'hffff_ffff, 1'b1);
add_register(`APB4_APU__READ_LIMIT, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__WRITE_BASE, AccessRw, 32'hffff_ffff, 1'b1);
add_register(`APB4_APU__WRITE_LIMIT, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__DMA_TIMEOUT, AccessRw, 32'h0000_ffff, 1'b0);
add_register(`APB4_APU__ABI_DIGEST, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__SEQUENCER_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__SEQUENCER_RETIRED, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_IMAGE_ADDRESS, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__MC_IMAGE_SIZE, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__MC_EXPECTED_CRC, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__MC_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_ABI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_BUILD_ID_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_BUILD_ID_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_LOCK, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_ACTUAL_CRC, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__MC_LOAD_COUNT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_CONTROL, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_INPUT_ADDRESS, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__JOB_INPUT_LENGTH, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__JOB_OUTPUT_ADDRESS, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__JOB_OUTPUT_CAPACITY, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__JOB_INPUT_CONFIG, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_OUTPUT_CONFIG, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_FLAGS, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_INPUT_USED, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_OUTPUT_BYTES, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_FRAMES, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_SOURCE_INFO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_CYCLES, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__JOB_DETAIL, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__RING_BASE, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__RING_SIZE, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__RING_HEAD, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__RING_TAIL, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__RING_CONTROL, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__RING_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__RING_COMPLETED, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__RING_COALESCE, AccessRw, 32'h0001_0001, 1'b1);
add_register(`APB4_APU__RING_DOORBELL, AccessWo, 32'd0, 1'b1);
add_register(`APB4_APU__KWS_MODEL_ADDRESS, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__KWS_MODEL_SIZE, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__KWS_MODEL_EXPECTED_CRC, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__KWS_CONTROL, AccessRw, 32'd0, 1'b1);
add_register(`APB4_APU__KWS_CONFIG, AccessRw, 32'h0000_0380, 1'b0);
add_register(`APB4_APU__KWS_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_RESULT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_TIMESTAMP_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_TIMESTAMP_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_FRAME_COUNT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_INFERENCE_COUNT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_HIT_COUNT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_OVERRUN_COUNT, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_MODEL_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__KWS_MODEL_ACTUAL_CRC, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_CONTROL, AccessRw, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_STATUS, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_ACTIVE_CYCLES_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_ACTIVE_CYCLES_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_INPUT_BYTES_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_INPUT_BYTES_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_OUTPUT_BYTES_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_OUTPUT_BYTES_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DECODED_FRAMES_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DECODED_FRAMES_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DMA_READ_STALLS_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DMA_READ_STALLS_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DMA_WRITE_STALLS_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_DMA_WRITE_STALLS_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_STREAM_STALLS_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_STREAM_STALLS_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_SEQUENCER_INSTR_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_SEQUENCER_INSTR_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_KWS_CYCLES_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_KWS_CYCLES_HI, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_FAULTS_LO, AccessRo, 32'd0, 1'b0);
add_register(`APB4_APU__PERF_FAULTS_HI, AccessRo, 32'd0, 1'b0);
if (s_reg_count != RegisterCount) begin
$fatal(1, "APU register table has %0d entries, expected %0d", s_reg_count, RegisterCount);
end
end
endtask
task automatic drive_apb_idle;
begin
apb4.paddr = 32'd0;
apb4.pprot = 3'd0;
apb4.psel = 1'b0;
apb4.penable = 1'b0;
apb4.pwrite = 1'b0;
apb4.pwdata = 32'd0;
apb4.pstrb = 4'd0;
end
endtask
task automatic hard_reset;
begin
@(negedge clk_i);
drive_apb_idle();
owner_i = 2'd0;
owner_lock_i = 1'b0;
quiesce_i = 1'b0;
resource_reset_i = 1'b0;
rst_n_i = 1'b0;
repeat (2) @(posedge clk_i);
@(negedge clk_i);
rst_n_i = 1'b1;
end
endtask
task automatic apb_write(input logic [11:0] offset_i, input logic [31:0] data_i,
input logic [3:0] strobe_i, input logic expected_err_i);
int unsigned s_wait_cycles;
logic s_response_err;
begin
@(negedge clk_i);
apb4.paddr = ApuBase + offset_i;
apb4.pwdata = data_i;
apb4.pstrb = strobe_i;
apb4.pwrite = 1'b1;
apb4.psel = 1'b1;
apb4.penable = 1'b0;
#1;
if (apb4.pready) $fatal(1, "APU PREADY asserted during write setup at %h", offset_i);
@(negedge clk_i);
apb4.penable = 1'b1;
s_wait_cycles = 0;
#1;
while (!apb4.pready) begin
s_wait_cycles++;
if (s_wait_cycles > 4) $fatal(1, "APU write wait timeout at %h", offset_i);
@(negedge clk_i);
#1;
end
if (s_wait_cycles != 1) begin
$fatal(1, "APU write wait count mismatch at %h: %0d", offset_i, s_wait_cycles);
end
if (apb4.pslverr != expected_err_i) $fatal(1, "APU write response mismatch at %h", offset_i);
s_response_err = apb4.pslverr;
#2;
if (!apb4.pready || (apb4.pslverr != s_response_err)) begin
$fatal(1, "APU write response was not retained through completion at %h", offset_i);
end
@(negedge clk_i);
drive_apb_idle();
end
endtask
task automatic apb_read(input logic [11:0] offset_i, output logic [31:0] data_o,
input logic expected_err_i);
int unsigned s_wait_cycles;
logic [31:0] s_response_data;
logic s_response_err;
begin
@(negedge clk_i);
apb4.paddr = ApuBase + offset_i;
apb4.pstrb = 4'd0;
apb4.pwrite = 1'b0;
apb4.psel = 1'b1;
apb4.penable = 1'b0;
#1;
if (apb4.pready) $fatal(1, "APU PREADY asserted during read setup at %h", offset_i);
@(negedge clk_i);
apb4.penable = 1'b1;
s_wait_cycles = 0;
#1;
while (!apb4.pready) begin
s_wait_cycles++;
if (s_wait_cycles > 4) $fatal(1, "APU read wait timeout at %h", offset_i);
@(negedge clk_i);
#1;
end
if (s_wait_cycles != 1) begin
$fatal(1, "APU read wait count mismatch at %h: %0d", offset_i, s_wait_cycles);
end
if (apb4.pslverr != expected_err_i) $fatal(1, "APU read response mismatch at %h", offset_i);
s_response_data = apb4.prdata;
s_response_err = apb4.pslverr;
#2;
if (!apb4.pready || (apb4.prdata != s_response_data) ||
(apb4.pslverr != s_response_err)) begin
$fatal(1, "APU read response was not retained through completion at %h", offset_i);
end
data_o = s_response_data;
@(negedge clk_i);
drive_apb_idle();
end
endtask
task automatic expect_read(input logic [11:0] offset_i, input logic [31:0] expected_i);
begin
apb_read(offset_i, s_value, 1'b0);
if (s_value != expected_i) begin
$fatal(1, "APU read mismatch at %h: got %h expected %h", offset_i, s_value, expected_i);
end
end
endtask
task automatic program_rw_registers;
begin
for (int unsigned register_index = 0; register_index < RegisterCount; register_index++) begin
if (s_reg_access[register_index] == AccessRw) begin
apb_write(s_reg_offset[register_index], legal_write_value(s_reg_offset[register_index]),
4'hf, 1'b0);
end
end
end
endtask
task automatic check_reset_state(input logic preserve_acl_i);
logic [31:0] s_expected;
begin
for (int unsigned register_index = 0; register_index < RegisterCount; register_index++) begin
if (s_reg_access[register_index] != AccessWo) begin
s_expected = preserve_acl_i ?
reset_or_preserved_value(s_reg_offset[register_index], s_reg_reset[register_index]) :
s_reg_reset[register_index];
expect_read(s_reg_offset[register_index], s_expected);
end
end
end
endtask
task automatic check_rejected_write(input logic [11:0] offset_i,
input logic [31:0] rejected_value_i,
input logic [5:0] error_code_i);
logic [31:0] s_before;
begin
hard_reset();
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678, 4'hf, 1'b0);
if ((offset_i != `APB4_APU__COMMAND) && (offset_i != `APB4_APU__IRQ_TEST) &&
(offset_i != `APB4_APU__RING_DOORBELL)) begin
apb_read(offset_i, s_before, 1'b0);
end else begin
s_before = 32'd0;
end
apb_write(offset_i, rejected_value_i, 4'hf, 1'b1);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678);
expect_read(`APB4_APU__ERROR_STATUS, 32'd1 | (32'(error_code_i) << 1));
expect_read(`APB4_APU__ERROR_ADDRESS, ApuBase + offset_i);
if ((offset_i != `APB4_APU__COMMAND) && (offset_i != `APB4_APU__IRQ_TEST) &&
(offset_i != `APB4_APU__RING_DOORBELL) && (offset_i != `APB4_APU__IRQ_STATE) &&
(offset_i != `APB4_APU__ERROR_STATUS) && (offset_i != `APB4_APU__ERROR_ADDRESS) &&
(offset_i != `APB4_APU__ERROR_DETAIL)) begin
expect_read(offset_i, s_before);
end
end
endtask
initial begin
initialize_register_table();
drive_apb_idle();
hard_reset();
if (!idle_o || irq_o) $fatal(1, "APU reset lifecycle outputs mismatch");
for (int unsigned register_index = 0; register_index < RegisterCount; register_index++) begin
hard_reset();
if (s_reg_access[register_index] == AccessWo) begin
apb_read(s_reg_offset[register_index], s_value, 1'b1);
end else begin
expect_read(s_reg_offset[register_index], s_reg_reset[register_index]);
end
end
for (int unsigned register_index = 0; register_index < RegisterCount; register_index++) begin
hard_reset();
case (s_reg_access[register_index])
AccessRo: begin
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678, 4'hf, 1'b0);
apb_write(s_reg_offset[register_index], 32'd0, 4'hf, 1'b1);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678);
if ((s_reg_offset[register_index] != `APB4_APU__ERROR_ADDRESS) &&
(s_reg_offset[register_index] != `APB4_APU__ERROR_DETAIL)) begin
expect_read(s_reg_offset[register_index], s_reg_reset[register_index]);
end
end
AccessWo: begin
apb_read(s_reg_offset[register_index], s_value, 1'b1);
hard_reset();
if (s_reg_offset[register_index] == `APB4_APU__COMMAND) begin
apb_write(s_reg_offset[register_index], 32'h0000_0004, 4'hf, 1'b0);
end else if (s_reg_offset[register_index] == `APB4_APU__IRQ_TEST) begin
apb_write(s_reg_offset[register_index], 32'd0, 4'hf, 1'b0);
end else begin
apb_write(s_reg_offset[register_index], 32'h0000_0001, 4'hf, 1'b1);
end
end
AccessRw: begin
apb_write(s_reg_offset[register_index], legal_write_value(s_reg_offset[register_index]),
4'hf, 1'b0);
expect_read(s_reg_offset[register_index], legal_readback_value(
s_reg_offset[register_index]));
end
default: $fatal(1, "APU register table has invalid access class");
endcase
end
hard_reset();
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h0000_00aa, 4'h1, 1'b0);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h0000_ffaa);
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h0000_bb00, 4'h2, 1'b0);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h0000_bbaa);
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h00cc_0000, 4'h4, 1'b0);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h00cc_bbaa);
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'hdd00_0000, 4'h8, 1'b0);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'hddcc_bbaa);
for (int unsigned register_index = 0; register_index < RegisterCount; register_index++) begin
if (s_reg_full_strobe[register_index]) begin
hard_reset();
apb_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678, 4'hf, 1'b0);
apb_write(s_reg_offset[register_index], legal_write_value(s_reg_offset[register_index]),
4'h7, 1'b1);
expect_read(`APB4_APU__SEQUENCER_TIMEOUT, 32'h1234_5678);
if (s_reg_access[register_index] == AccessRw) begin
expect_read(s_reg_offset[register_index], s_reg_reset[register_index]);
end
end
end
check_rejected_write(`APB4_APU__COMMAND, 32'h0000_0080, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
for (int bit_index = 0; bit_index < 6; bit_index++) begin
if ((bit_index != `APB4_APU__COMMAND_SOFT_RESET) &&
(bit_index != `APB4_APU__COMMAND_CLEAR_COUNTERS)) begin
check_rejected_write(`APB4_APU__COMMAND, 32'd1 << bit_index,
`APB4_APU__ERROR_CODE_UNSUPPORTED);
end
end
check_rejected_write(`APB4_APU__IRQ_STATE, 32'h0000_0800, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__IRQ_ENABLE, 32'h0000_0800,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__IRQ_TEST, 32'h0000_0800, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__ERROR_STATUS, 32'h0000_0002,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__SEQUENCER_TIMEOUT, 32'd0, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__STREAM_ROUTE, 32'h0000_0001, `APB4_APU__ERROR_CODE_UNSUPPORTED);
check_rejected_write(`APB4_APU__STREAM_ROUTE, 32'h0000_0004, `APB4_APU__ERROR_CODE_UNSUPPORTED);
check_rejected_write(`APB4_APU__DMA_TIMEOUT, 32'd0, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__MC_IMAGE_ADDRESS, 32'h3002_0001,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__MC_IMAGE_SIZE, 32'd0, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__JOB_CONTROL, 32'h8000_0000,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__JOB_INPUT_CONFIG, 32'h8000_0000,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__JOB_OUTPUT_CONFIG, 32'h8000_0000,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__JOB_FLAGS, 32'h0000_0002, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_BASE, 32'h3004_0001, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_SIZE, 32'h0000_0003, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_TAIL, 32'h0000_0100, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_CONTROL, 32'h0000_0004,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_COALESCE, 32'd0, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__RING_DOORBELL, 32'h0000_0001,
`APB4_APU__ERROR_CODE_UNSUPPORTED);
check_rejected_write(`APB4_APU__KWS_MODEL_ADDRESS, 32'h3005_0001,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__KWS_MODEL_SIZE, 32'd0, `APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__KWS_CONTROL, 32'h0000_0001, `APB4_APU__ERROR_CODE_UNSUPPORTED);
check_rejected_write(`APB4_APU__KWS_CONTROL, 32'h0000_0002, `APB4_APU__ERROR_CODE_UNSUPPORTED);
check_rejected_write(`APB4_APU__KWS_CONTROL, 32'h0000_0008,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__KWS_CONFIG, 32'h0000_0080,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
check_rejected_write(`APB4_APU__PERF_CONTROL, 32'h0000_0008,
`APB4_APU__ERROR_CODE_INVALID_CONFIG);
hard_reset();
apb_write(`APB4_APU__IRQ_TEST, 32'h0000_0001, 4'hf, 1'b0);
force u_dut.u_apu_reg.s_irq_set = 11'h001;
apb_write(`APB4_APU__IRQ_STATE, 32'h0000_0001, 4'h1, 1'b0);
release u_dut.u_apu_reg.s_irq_set;
expect_read(`APB4_APU__IRQ_STATE, 32'h0000_0001);
apb_write(`APB4_APU__IRQ_STATE, 32'h0000_0001, 4'h1, 1'b0);
expect_read(`APB4_APU__IRQ_STATE, 32'd0);
hard_reset();
program_rw_registers();
apb_write(`APB4_APU__COMMAND, 32'h0000_0004, 4'hf, 1'b0);
check_reset_state(1'b1);
hard_reset();
program_rw_registers();
@(negedge clk_i);
resource_reset_i = 1'b1;
@(posedge clk_i);
@(negedge clk_i);
resource_reset_i = 1'b0;
check_reset_state(1'b1);
hard_reset();
owner_i = 2'd1;
owner_lock_i = 1'b1;
quiesce_i = 1'b1;
expect_read(`APB4_APU__OWNER_STATUS, 32'h0000_0301);
apb_read(12'h060, s_value, 1'b1);
apb_read(12'h001, s_value, 1'b1);
$display("APU-P1 complete APB register matrix passed");
$finish;
end
initial begin
repeat (20000) @(posedge clk_i);
$fatal(1, "APU-P1 APB register matrix timed out");
end
endmodule
+40
View File
@@ -180,6 +180,41 @@ module axi4_interconnect_tb;
end
endtask
task automatic issue_hp_apu_write(input logic [31:0] address, input logic [1:0] expected_response,
input logic expected_access_fault);
begin
@(negedge clk_i);
masters[6].awaddr = address;
masters[6].awlen = 8'd0;
masters[6].awvalid = 1'b1;
do @(posedge clk_i); while (!masters[6].awready);
@(negedge clk_i);
masters[6].awvalid = 1'b0;
masters[6].wdata = 32'h1234_5678;
masters[6].wstrb = 4'hf;
masters[6].wlast = 1'b1;
masters[6].wvalid = 1'b1;
do @(posedge clk_i); while (!masters[6].wready);
@(negedge clk_i);
masters[6].wvalid = 1'b0;
masters[6].bready = 1'b1;
while (!masters[6].bvalid) @(negedge clk_i);
#1;
if ((masters[6].bresp != expected_response) ||
(fault_valid_o != expected_access_fault) ||
(expected_access_fault &&
(!fault_access_o || (fault_addr_o != address) || (fault_master_o != 3'd6) ||
(fault_code_o != `RIB_RESP_PROTERR)))) begin
$fatal(
1,
"HP APU access policy mismatch at %h: resp=%0d fault=%0d access=%0d master=%0d code=%0d",
address, masters[6].bresp, fault_valid_o, fault_access_o, fault_master_o, fault_code_o);
end
@(negedge clk_i);
masters[6].bready = 1'b0;
end
endtask
task automatic issue_management_with_idle_sdio;
integer cycles;
begin
@@ -347,7 +382,12 @@ module axi4_interconnect_tb;
issue_management_with_idle_sdio();
issue_mgmt_error_read(32'hA000_0000, 8'd0, `AXI4_RESP_DECODE_ERROR, `RIB_RESP_DECERR);
issue_mgmt_error_read(32'h3000_0000, 8'd16, `AXI4_RESP_SLAVE_ERROR, `RIB_RESP_BURSTERR);
`ifdef MINI_PRODUCT
issue_hp_apu_write(32'h1001_301C, `AXI4_RESP_OKAY, 1'b0);
issue_hp_apu_write(32'h1001_3040, `AXI4_RESP_SLAVE_ERROR, 1'b1);
`else
issue_denied_user_write(32'h1000_B000);
`endif
issue_contending_sdio_faults();
issue_hp_accesses();
+21 -9
View File
@@ -3,16 +3,17 @@
module resource_controller_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic [ 5:0] idle_i = '0;
logic [ 5:0] block_ack_i = '0;
logic [ 5:0] irq_i = '0;
logic [ 7:0] idle_i = '0;
logic [ 7:0] block_ack_i = '0;
logic [ 7:0] irq_i = '0;
logic cache_request_i = 1'b0;
logic cache_clean_o;
logic [ 5:0][1:0] owner_o;
logic [ 5:0] quiesce_o;
logic [ 5:0] reset_o;
logic [ 5:0] irq_lp_o;
logic [ 5:0] irq_hp_o;
logic [ 7:0][1:0] owner_o;
logic [ 7:0] owner_lock_o;
logic [ 7:0] quiesce_o;
logic [ 7:0] reset_o;
logic [ 7:0] irq_lp_o;
logic [ 7:0] irq_hp_o;
logic fault_irq_o;
logic [31:0] read_data;
@@ -32,6 +33,7 @@ module resource_controller_tb;
.cache_request_i(cache_request_i),
.cache_clean_o (cache_clean_o),
.owner_o (owner_o),
.owner_lock_o (owner_lock_o),
.quiesce_o (quiesce_o),
.reset_o (reset_o),
.irq_lp_o (irq_lp_o),
@@ -90,7 +92,7 @@ module resource_controller_tb;
repeat (3) @(posedge clk_i);
rst_n_i = 1'b1;
idle_i = 6'h3F;
idle_i = 8'hFF;
apb_read(12'h000, read_data);
if (read_data != 32'h5253_4354) $fatal(1, "resource controller ID mismatch");
@@ -135,6 +137,16 @@ module resource_controller_tb;
$fatal(1, "resource lifecycle controls did not update");
end
irq_i[7] = 1'b1;
#1;
if (!irq_lp_o[7] || irq_hp_o[7]) $fatal(1, "APU reset owner routing mismatch");
block_ack_i[7] = 1'b1;
apb_write(12'h1E4, 32'h0000_0001, 1'b0);
apb_write(12'h1E0, 32'h0000_0101, 1'b0);
if ((owner_o[7] != 2'd1) || !owner_lock_o[7] || irq_lp_o[7] || !irq_hp_o[7]) begin
$fatal(1, "APU resource index 7 ownership or IRQ routing mismatch");
end
$display("Resource Controller ownership, IRQ, and cache handshake test passed");
$finish;
end
+2 -1
View File
@@ -43,6 +43,7 @@ module soc_irq_topology_tb;
20: expect_irq(32'd1 << 25);
21: expect_irq(32'd1 << 26);
22: expect_irq(32'd1 << 30);
23: expect_irq(32'd1 << 31);
default: expect_irq(32'd1 << (bit_index + 7));
endcase
end
@@ -70,7 +71,7 @@ module soc_irq_topology_tb;
$fatal(1, "SDIO core IRQ bits are not low when sources are low: IRQ10=%b IRQ21=%b",
s_irq[10], s_irq[21]);
end
if ((s_irq[31] !== 1'b0) || (s_irq[19:18] !== '0)) begin
if (s_irq[19:18] !== '0) begin
$fatal(1, "unallocated core IRQ bits are not low: %h", s_irq);
end