Add generic IMU fusion and PMOD IRQ verification

This commit is contained in:
2026-07-14 11:03:13 +03:00
parent e77651dac3
commit dd6569c025
35 changed files with 2680 additions and 70 deletions
+75 -2
View File
@@ -9,6 +9,7 @@ module asic_rocket_tb;
reg board_reset = 1'b1;
reg gps_rf_clk = 1'b0;
reg [3:0] gps_rf_data = 4'h0;
reg pmod_irq = 1'b0;
wire core_clk = board_clock;
wire core_reset;
@@ -34,11 +35,16 @@ module asic_rocket_tb;
wire uart_valid;
wire [7:0] uart_data;
reg simjtag_enable = 1'b0;
reg pmod_irq_rtl_only = 1'b0;
reg [7:0] last_uart_byte = 8'h00;
integer app_match_count = 0;
integer gps_match_count = 0;
integer uart_toggle_count = 0;
integer pmod_irq_rise_count = 0;
reg main_return_seen = 1'b0;
reg [15:0] main_return_code_q = 16'hffff;
reg pmod_irq_pulse_done = 1'b0;
reg pmod_irq_pending_seen = 1'b0;
reg uart_txd_q = 1'b1;
wire core_wfi;
wire [63:0] main_return_status;
@@ -46,6 +52,7 @@ module asic_rocket_tb;
initial begin
simjtag_enable = $test$plusargs("jtag_rbb_enable");
pmod_irq_rtl_only = $test$plusargs("pmod_irq_rtl_only");
end
always #(CLOCK_HALF_PERIOD_NS) board_clock = ~board_clock;
@@ -69,6 +76,25 @@ module asic_rocket_tb;
board_reset = 1'b0;
end
// Model an asynchronous, active-high sensor interrupt. Four square-wave
// periods deliberately straddle core clock edges and exercise the Rocket
// interrupt synchronizer before reaching PLIC device 11.
initial begin
wait (core_reset === 1'b0);
repeat (32) @(posedge core_clk);
repeat (4) begin
#(3.0) pmod_irq = 1'b1;
repeat (8) @(posedge core_clk);
#(2.0) pmod_irq = 1'b0;
repeat (8) @(posedge core_clk);
end
pmod_irq_pulse_done = 1'b1;
end
always @(posedge pmod_irq) begin
pmod_irq_rise_count = pmod_irq_rise_count + 1;
end
always @(posedge core_clk) begin
uart_txd_q <= uart_txd;
if (!core_reset && uart_txd_q !== uart_txd) begin
@@ -81,6 +107,7 @@ module asic_rocket_tb;
.board_reset(board_reset),
.gps_rf_clk(gps_rf_clk),
.gps_rf_data(gps_rf_data),
.pmod_irq(pmod_irq),
.uart_rxd(1'b1),
.uart_txd(uart_txd),
.spi_sck(spi_sck),
@@ -104,6 +131,19 @@ module asic_rocket_tb;
assign main_return_status = dut.u_rocket.tile_prci_domain.element_reset_domain.rockettile.core.csr.reg_mscratch;
assign main_return_code = main_return_status[15:0];
// pmod_irq is source 10 in the zero-based TLPLIC arrays, corresponding to
// architectural PLIC device ID 11.
always @(posedge core_clk) begin
if (core_reset) begin
pmod_irq_pending_seen <= 1'b0;
end else if (dut.u_rocket.plic_domain.plic.pending_10 === 1'b1) begin
if (!pmod_irq_pending_seen) begin
$display("ASIC PMOD IRQ: PLIC device 11 pending observed");
end
pmod_irq_pending_seen <= 1'b1;
end
end
SimJTAG #(.TICK_DELAY(3)) sim_jtag (
.clock(core_clk),
.reset(core_reset),
@@ -179,21 +219,54 @@ module asic_rocket_tb;
end
always @(posedge core_clk) begin
if (!core_reset && gps_match_count == 10) begin
if (!core_reset && gps_match_count == 10 && pmod_irq_pulse_done &&
pmod_irq_pending_seen && pmod_irq_rise_count == 4) begin
$display("ASIC PMOD IRQ PASS: rises=%0d pending_seen=%0d",
pmod_irq_rise_count, pmod_irq_pending_seen);
$display("ASIC sanity PASS");
$finish;
end
end
// The RTL-only mode bypasses the intentionally slow SPI-flash boot path.
// It proves the complete hardware route from the asynchronous ASIC input to
// architectural PLIC device 11; sim-pmod-irq retains the CPU/ISR check.
always @(posedge core_clk) begin
if (!core_reset && pmod_irq_rtl_only && pmod_irq_pulse_done) begin
if (pmod_irq_pending_seen && pmod_irq_rise_count == 4) begin
$display("ASIC PMOD IRQ RTL PASS: rises=%0d plic_device=11 pending_seen=%0d",
pmod_irq_rise_count, pmod_irq_pending_seen);
$display("ASIC sanity PASS");
end else begin
$display("ASIC PMOD IRQ RTL FAIL: rises=%0d plic_device=11 pending_seen=%0d",
pmod_irq_rise_count, pmod_irq_pending_seen);
$display("ASIC sanity FAIL");
end
$finish;
end
end
always @(posedge core_clk) begin
if (core_reset) begin
main_return_seen <= 1'b0;
main_return_code_q <= 16'hffff;
end else if (!main_return_seen && main_return_status[31:16] == 16'h5a5a) begin
main_return_seen <= 1'b1;
main_return_code_q <= main_return_code;
$display("C main returned %0d", main_return_code);
if (main_return_code == 16'h0000) begin
end
end
always @(posedge core_clk) begin
if (!core_reset && main_return_seen && pmod_irq_pulse_done) begin
if (main_return_code_q == 16'h0000 && pmod_irq_pending_seen &&
pmod_irq_rise_count == 4) begin
$display("ASIC PMOD IRQ PASS: rises=%0d pending_seen=%0d",
pmod_irq_rise_count, pmod_irq_pending_seen);
$display("ASIC sanity PASS");
end else begin
$display("ASIC PMOD IRQ FAIL: rises=%0d pending_seen=%0d",
pmod_irq_rise_count, pmod_irq_pending_seen);
$display("ASIC sanity FAIL");
end
$finish;
+5
View File
@@ -17,6 +17,11 @@ add wave -noupdate -expand -group Core /asic_rocket_tb/dut/jtag_tdo_data
add wave -noupdate -expand -group Core /asic_rocket_tb/dut/jtag_tdo_driven
add wave -noupdate -expand -group Core /asic_rocket_tb/dut/debug_ndreset
add wave -noupdate -expand -group Core /asic_rocket_tb/dut/debug_dmactive
add wave -noupdate -expand -group PMOD_IRQ /asic_rocket_tb/pmod_irq
add wave -noupdate -expand -group PMOD_IRQ /asic_rocket_tb/pmod_irq_pulse_done
add wave -noupdate -expand -group PMOD_IRQ /asic_rocket_tb/pmod_irq_pending_seen
add wave -noupdate -expand -group PMOD_IRQ /asic_rocket_tb/dut/rocket_pmod_irq
add wave -noupdate -expand -group PMOD_IRQ /asic_rocket_tb/dut/u_rocket/plic_domain/plic/pending_10
add wave -noupdate -expand -group Flash /asic_rocket_tb/u_flash/sck
add wave -noupdate -expand -group Flash /asic_rocket_tb/u_flash/csn
add wave -noupdate -expand -group Flash /asic_rocket_tb/u_flash/dq_o