Skip to content

Commit

Permalink
[dv, aon_timer] Enabling mid-TL_UL access reset injection
Browse files Browse the repository at this point in the history
Plus also making the Vseqs reset aware

Signed-off-by: Antonio Martinez Zambrana <[email protected]>
  • Loading branch information
antmarzam committed Feb 7, 2025
1 parent faab544 commit 78048c8
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 56 deletions.
2 changes: 2 additions & 0 deletions hw/ip/aon_timer/dv/env/aon_timer_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ function void aon_timer_env_cfg::initialize(bit [31:0] csr_base_addr = '1);
// set num_interrupts & num_alerts
num_interrupts = ral.intr_state.get_n_used_bits();
set_intr_state_has_prediction();
// Allow mid-TL-US accesses
can_reset_with_csr_accesses = 1;
endfunction : initialize

function bit aon_timer_env_cfg::hdl_read_bit(string path);
Expand Down
83 changes: 59 additions & 24 deletions hw/ip/aon_timer/dv/env/seq_lib/aon_timer_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,35 @@ endclass : aon_timer_base_vseq
constraint aon_timer_base_vseq::thold_count_c {
solve wkup_count_gap, wkup_thold before wkup_count;
solve aim_bite, wdog_count_gap, wdog_bark_thold, wdog_bite_thold before wdog_count;
wkup_count_gap inside {[1:500]};
wdog_count_gap inside {[1:500]};

wkup_thold inside {[1:10]};
wdog_bark_thold inside {[1:10]};
wdog_bite_thold inside {[1:10]};

wkup_thold <= (2**64-1);
wdog_bark_thold <= (2**32-1);
wdog_bite_thold <= (2**32-1);

wkup_count inside {[wkup_thold-wkup_count_gap:wkup_thold]};
!aim_bite -> wdog_count inside {[wdog_bark_thold-wdog_count_gap:wdog_bark_thold]};
aim_bite -> wdog_count inside {[wdog_bite_thold-wdog_count_gap:wdog_bite_thold]};

wkup_count_gap inside {[1:10]};
wdog_count_gap inside {[1:10]};
wkup_thold <= (2**WKUP_WIDTH-1);
wdog_bark_thold <= (2**WDOG_WIDTH-1);
wdog_bite_thold <= (2**WDOG_WIDTH-1);

wkup_thold dist {0 :/ 20,
[1:(2**WKUP_WIDTH-2)] :/ 60,
(2**WKUP_WIDTH-1) :/ 20};

wdog_bark_thold dist {0 :/ 20,
[1:(2**WDOG_WIDTH-2)] :/ 60,
(2**WDOG_WIDTH-1) :/ 20};

wdog_bite_thold dist {0 :/ 20,
[1:(2**WDOG_WIDTH-2)] :/ 60,
(2**WDOG_WIDTH-1) :/ 20};


wkup_thold != 0 -> wkup_count inside {[wkup_thold-wkup_count_gap:wkup_thold]};
wkup_thold == 0 -> wkup_count == 0;
if (!aim_bite) {
wdog_bark_thold != 0 -> wdog_count inside {[wdog_bark_thold-wdog_count_gap:wdog_bark_thold]};
wdog_bark_thold == 0 -> wdog_count == 0;
}
else {
wdog_bite_thold != 0 -> wdog_count inside {[wdog_bite_thold-wdog_count_gap:wdog_bite_thold]};
wdog_bite_thold == 0 -> wdog_count == 0;
}
}

function aon_timer_base_vseq::new (string name="");
Expand All @@ -97,62 +111,78 @@ endtask : dut_init

task aon_timer_base_vseq::aon_timer_shutdown();
`uvm_info(`gfn, "Shutting down AON Timer...", UVM_LOW)

if (cfg.under_reset) return;
`uvm_info(`gfn, "Writing 0 to WKUP_CTRL and WDOG_CTRL to disable AON timer", UVM_HIGH)
write_wkup_reg(ral.wkup_ctrl.enable, 1'b0);
if (cfg.under_reset) return;
`uvm_info(`gfn, "write_reg wdog_ctr.enable", UVM_DEBUG);
csr_utils_pkg::csr_wr(ral.wdog_ctrl.enable, 1'b0);

if (cfg.under_reset) return;
`uvm_info(`gfn, "Clearing interrupts, count registers and wakeup request.", UVM_HIGH)
// Clear wake-up request if we have any
csr_utils_pkg::csr_wr(ral.wkup_cause, 1'b0);
if (cfg.under_reset) return;

// We need to ensure the prediction has kicked in before we read the intr_state
wait (ral.intr_state.is_busy() == 0);
wait (ral.intr_state.m_is_busy == 0);

// Clear the interrupts
csr_utils_pkg::csr_wr(ral.intr_state, 2'b11);
if (cfg.under_reset) return;

`uvm_info(`gfn, $sformatf({"Initializating AON Timer. Writing ",
"0x%0x to WKUP_COUNT and 0x%0x ",
"to WDOG_COUNT."},
wkup_count, wdog_count), UVM_LOW)
// Register Write
write_wkup_reg(ral.wkup_count_lo, wkup_count[31:0]);
if (cfg.under_reset) return;
write_wkup_reg(ral.wkup_count_hi, wkup_count[63:32]);
if (cfg.under_reset) return;
write_wkup_reg(ral.wdog_count, wdog_count);
if (cfg.under_reset) return;

// Wait to settle registers on AON timer domain
cfg.aon_clk_rst_vif.wait_clks(5);
cfg.aon_clk_rst_vif.wait_clks_or_rst(5);
endtask : aon_timer_shutdown

// setup basic aon_timer features
task aon_timer_base_vseq::aon_timer_init();
bit wkup_thold_lo_we, wkup_thold_hi_we;
// Clear the interrupts
csr_utils_pkg::csr_wr(ral.intr_state, 2'b11);
if (cfg.under_reset) return;

`uvm_info(`gfn, "Initializating AON Timer. Writing 0 to WKUP_COUNT and WDOG_COUNT", UVM_LOW)
// Register Write
write_wkup_reg(ral.wkup_count_lo, 32'h0000_0000);
write_wkup_reg(ral.wkup_count_hi, 32'h0000_0000);
csr_utils_pkg::csr_wr(ral.wdog_count, 32'h0000_0000);
write_wkup_reg(ral.wkup_count_lo, wkup_count[31:0]);
if (cfg.under_reset) return;
write_wkup_reg(ral.wkup_count_hi, wkup_count[63:32]);
if (cfg.under_reset) return;
csr_utils_pkg::csr_wr(ral.wdog_count, wdog_count);
if (cfg.under_reset) return;

`uvm_info(`gfn, "Randomizing AON Timer thresholds", UVM_HIGH)

`uvm_info(`gfn, $sformatf("Writing 0x%0h to wkup_thold", wkup_thold), UVM_HIGH)
write_wkup_reg(ral.wkup_thold_lo, wkup_thold[31:0]);
if (cfg.under_reset) return;
write_wkup_reg(ral.wkup_thold_hi, wkup_thold[63:32]);
if (cfg.under_reset) return;

`uvm_info(`gfn, $sformatf("Writing 0x%0h to wdog_bark_thold", wdog_bark_thold), UVM_HIGH)
write_wkup_reg(ral.wdog_bark_thold, wdog_bark_thold);
if (cfg.under_reset) return;

`uvm_info(`gfn, $sformatf("Writing 0x%0h to wdog_bite_thold", wdog_bite_thold), UVM_HIGH)
write_wkup_reg(ral.wdog_bite_thold, wdog_bite_thold);
if (cfg.under_reset) return;

cfg.lc_escalate_en_vif.drive(0);

`uvm_info(`gfn, $sformatf("Writing 0x%0h to WDOG_REGWEN", wdog_regwen), UVM_HIGH)
csr_utils_pkg::csr_wr(ral.wdog_regwen, wdog_regwen);
if (cfg.under_reset) return;

endtask : aon_timer_init

Expand Down Expand Up @@ -188,13 +218,17 @@ task aon_timer_base_vseq::wait_for_interrupt(bit intr_state_read = 1);
uvm_reg_data_t intr_state_value;

@(negedge cfg.aon_clk_rst_vif.rst_n or cfg.aon_intr_vif.pins);
if (cfg.under_reset) return;
`uvm_info(`gfn, $sformatf("Interrupt detected: 0x%0x ",cfg.aon_intr_vif.pins), UVM_DEBUG)

if (intr_state_read) begin
// Wait 2 clocks to ensure interrupt is visible on intr_state read
cfg.aon_clk_rst_vif.wait_clks(2);
cfg.aon_clk_rst_vif.wait_clks_or_rst(2);

if (cfg.under_reset) return;
// We need to ensure the prediction has kicked in before we read the intr_state
wait (ral.intr_state.is_busy()==0);
wait (ral.intr_state.m_is_busy == 0);
if (cfg.under_reset) return;
csr_utils_pkg::csr_rd(ral.intr_state, intr_state_value);
end

Expand All @@ -212,6 +246,7 @@ task aon_timer_base_vseq::write_wkup_reg(input uvm_object ptr, input uvm_reg_dat
string path_to_we;
csr_field_t csr_or_fld = decode_csr_or_field(ptr);

if (cfg.under_reset) return;
if (csr_or_fld.csr == null)
`uvm_fatal(`gfn, "Couldn't decode argument into CSR reg")
path_to_we = {".u_reg.aon_", csr_or_fld.csr.get_name(), "_we"};
Expand Down
33 changes: 3 additions & 30 deletions hw/ip/aon_timer/dv/env/seq_lib/aon_timer_custom_intr_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,7 @@ task aon_timer_custom_intr_vseq::intr_stimulus();
bit [1:0] read_intr_state;
for (int i = 1; i <= num_trans; i++) begin
// Write random value to the COUNT registers
// cfg.aon_clk_rst_vif.wait_clks(1);
fork
begin : iso_fork_1
fork
begin : execute_code
cfg.aon_clk_rst_vif.wait_clks(1);
end : execute_code
begin : detect_reset
wait (cfg.under_reset);
end : detect_reset
join_any
disable fork;
end : iso_fork_1
join
cfg.aon_clk_rst_vif.wait_clks_or_rst(1);

if (!this.randomize())
`uvm_fatal(`gfn, "Randomization Failure")
Expand All @@ -70,21 +57,7 @@ task aon_timer_custom_intr_vseq::intr_stimulus();
csr_utils_pkg::csr_rd(ral.intr_state, read_intr_state);
if (cfg.under_reset) return;

`uvm_info(`gfn, "\n\t Waiting for AON Timer to finish (interrupt)", UVM_HIGH)
// cfg.aon_clk_rst_vif.wait_clks(5);
fork
begin : iso_fork_2
fork
begin : execute_code
cfg.aon_clk_rst_vif.wait_clks(5);
end : execute_code
begin : detect_reset
wait (cfg.under_reset);
end : detect_reset
join_any
disable fork;
end : iso_fork_2
join

`uvm_info(`gfn, "\n\t Waiting for AON Timer to finish (interrupt)", UVM_HIGH)
cfg.aon_clk_rst_vif.wait_clks_or_rst(5);
end
endtask : intr_stimulus
7 changes: 6 additions & 1 deletion hw/ip/aon_timer/dv/env/seq_lib/aon_timer_jump_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,26 @@ task aon_timer_jump_vseq::jump_configure();

// Write random value to the COUNT registers
write_wkup_reg(ral.wkup_count_lo, wkup_count[31:0]);
if (cfg.under_reset) return;
write_wkup_reg(ral.wkup_count_hi, wkup_count[63:32]);
`uvm_info(`gfn,
$sformatf("\n\t Writing random COUNT value of %d to WKUP", wkup_count),
UVM_HIGH)
if (cfg.under_reset) return;

csr_utils_pkg::csr_wr(ral.wdog_count, wdog_count);
`uvm_info(`gfn,
$sformatf("\n\t Writing random COUNT value of %d to WDOG", wdog_count),
UVM_HIGH)

cfg.aon_clk_rst_vif.wait_clks(1);
cfg.aon_clk_rst_vif.wait_clks_or_rst(1);
if (cfg.under_reset) return;

`uvm_info(`gfn, "Enabling AON Timer. Writing 1 to WKUP_CTRL and WDOG_CTRL", UVM_HIGH)
csr_utils_pkg::csr_wr(ral.wdog_ctrl.enable, 1'b1);
if (cfg.under_reset) return;
csr_utils_pkg::csr_wr(ral.wkup_ctrl.enable, 1'b1);
if (cfg.under_reset) return;

`uvm_info(`gfn, "\n\t Waiting for AON Timer to finish (interrupt)", UVM_HIGH)
endtask : jump_configure
16 changes: 15 additions & 1 deletion hw/ip/aon_timer/dv/env/seq_lib/aon_timer_prescaler_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ class aon_timer_prescaler_vseq extends aon_timer_base_vseq;
`uvm_object_utils(aon_timer_prescaler_vseq)

// Randomize prescaler configuration of the wake up timer.
randc bit [11:0] prescaler;
rand bit [11:0] prescaler;

//Overrides constraint in parent vseq:
extern constraint thold_count_c;
extern constraint prescaler_c;

extern function new (string name="");
extern task body();
Expand All @@ -27,14 +28,23 @@ constraint aon_timer_prescaler_vseq::thold_count_c {
wdog_count == 0;
}

constraint aon_timer_prescaler_vseq::prescaler_c {
prescaler dist {0 :/ 15,
[1:(2**PRESCALER_WIDTH-2)] :/ 70,
(2**PRESCALER_WIDTH-1) :/ 15};
}

function aon_timer_prescaler_vseq::new (string name="");
super.new(name);
endfunction : new

task aon_timer_prescaler_vseq::body();
aon_timer_init();
if (cfg.under_reset) return;
prescaler_configure();
if (cfg.under_reset) return;
wait_for_interrupt();
if (cfg.under_reset) return;
aon_timer_shutdown();
endtask : body

Expand All @@ -46,13 +56,17 @@ task aon_timer_prescaler_vseq::prescaler_configure();
$sformatf("\n\t Writing random prescaler value of %d to WKUP CTRL", prescaler),
UVM_HIGH)

if (cfg.under_reset) return;
csr_utils_pkg::csr_spinwait(.ptr(ral.wkup_ctrl.prescaler), .exp_data(prescaler), .backdoor(1));
`uvm_info(`gfn, "Written values (wkup_prescaler) has propagated through the CDC", UVM_DEBUG)


if (cfg.under_reset) return;
`uvm_info(`gfn, "Enabling AON Timer (WKUP ONLY). Writing 1 to WKUP_CTRL", UVM_HIGH)
csr_utils_pkg::csr_wr(ral.wkup_ctrl.enable, 1'b1);
if (cfg.under_reset) return;
csr_utils_pkg::csr_wr(ral.wdog_ctrl.enable, 1'b0);
if (cfg.under_reset) return;

`uvm_info(`gfn, "\n\t Waiting for AON Timer to finish (interrupt)", UVM_HIGH)
endtask : prescaler_configure
5 changes: 5 additions & 0 deletions hw/ip/aon_timer/dv/env/seq_lib/aon_timer_smoke_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,23 @@ endfunction : new

task aon_timer_smoke_vseq::body();
aon_timer_init();
if (cfg.under_reset) return;
smoke_configure();
if (cfg.under_reset) return;
wait_for_interrupt();
if (cfg.under_reset) return;
aon_timer_shutdown();
endtask : body

task aon_timer_smoke_vseq::smoke_configure();

`uvm_info(`gfn, "Enabling AON Timer. Writing 1 to WKUP_CTRL and WDOG_CTRL", UVM_HIGH)
csr_utils_pkg::csr_wr(ral.wkup_ctrl.enable, 1'b1);
if (cfg.under_reset) return;
wdog_ctrl_pause_in_sleep = $urandom_range(0, 1);
ral.wdog_ctrl.enable.set(1);
ral.wdog_ctrl.pause_in_sleep.set(wdog_ctrl_pause_in_sleep);
csr_update(ral.wdog_ctrl);
if (cfg.under_reset) return;
`uvm_info(`gfn, "\n\t Waiting for AON Timer to finish (interrupt)", UVM_HIGH)
endtask : smoke_configure
2 changes: 2 additions & 0 deletions hw/ip/aon_timer/dv/env/seq_lib/aon_timer_stress_all_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class aon_timer_stress_all_vseq extends aon_timer_base_vseq;
endclass : aon_timer_stress_all_vseq

constraint aon_timer_stress_all_vseq::num_trans_c {
// TODO: tweak the constraint to see if we see same coverage with less iterations
num_trans inside {[15:20]};
}

Expand Down Expand Up @@ -48,5 +49,6 @@ task aon_timer_stress_all_vseq::body();
end

aon_timer_vseq.start(p_sequencer);
if (cfg.under_reset) break;
end
endtask : body

0 comments on commit 78048c8

Please sign in to comment.