Skip to content

Commit

Permalink
[test] Add DVsim support for the activity-checking part of power viru…
Browse files Browse the repository at this point in the history
…s test

- C code:
   - Add adc_ctrl enablement code.
   - Fix pwm enablement code by adding phase_counter enablement.

- chip_if.sv:
   - Add SignalProbe macros to monitor the states' of the active IPs

- *_vseq.sv:
   - Modify the DV_WAIT macro's message to bring the activity closer the start of max power epoch.
   - Add a utility function to verify that all IPs are active at the beginning of the max-power epoch.

Signed-off-by: Bilgiday Yuce <[email protected]>
  • Loading branch information
bilgiday committed Apr 4, 2023
1 parent 1e139db commit 49b2e4f
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 5 deletions.
93 changes: 93 additions & 0 deletions hw/top_earlgrey/dv/env/chip_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface chip_if;
`endif
`define ADC_CTRL_HIER `TOP_HIER.u_adc_ctrl_aon
`define AES_HIER `TOP_HIER.u_aes
`define AES_CONTROL_HIER `AES_HIER.u_aes_core.u_aes_control
`define ALERT_HANDLER_HIER `TOP_HIER.u_alert_handler
`define AON_TIMER_HIER `TOP_HIER.u_aon_timer_aon
`define AST_HIER u_ast
Expand Down Expand Up @@ -980,9 +981,101 @@ interface chip_if;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_otp_vendor_test_ctrl,
`OTP_CTRL_HIER.lc_otp_vendor_test_i)

/*
* Signal probe functions for sampling the FSM states of the IPs
* during the max power epoch of the power_virus test.
*/

// Signal probe fuction for `fsm_state_q` of ADC_CTRL
wire [4:0] adc_ctrl_state;
assign adc_ctrl_state = `ADC_CTRL_HIER.u_adc_ctrl_core.u_adc_ctrl_fsm.fsm_state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_adc_ctrl_fsm_state,
adc_ctrl_state, 5)

// Signal probe function for `cio_csb_o` of SPI_HOST_0
wire spi_host_0_cio_csb_o;
assign spi_host_0_cio_csb_o = `SPI_HOST_HIER(0).cio_csb_o;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_spi_host_0_cio_csb_o,
spi_host_0_cio_csb_o, 1)

// Signal probe function for `cio_csb_i` of SPI_DEVICE
wire spi_device_cio_csb_i;
assign spi_device_cio_csb_i = `SPI_DEVICE_HIER.cio_csb_i;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_spi_device_cio_csb_i,
spi_device_cio_csb_i, 1)

// Signal probe function for `fsm.state_q` of SPI_HOST_1
wire [2:0] spi_host_1_state;
assign spi_host_1_state = `SPI_HOST_HIER(1).u_spi_core.u_fsm.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_spi_host_1_fsm_state,
spi_host_1_state, 3)

// Signal probe function for `state_q` of CSRNG main FSM
wire [csrng_pkg::MainSmStateWidth-1:0] csrng_main_state;
assign csrng_main_state = `CSRNG_HIER.u_csrng_core.u_csrng_main_sm.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_csrng_main_fsm_state,
csrng_main_state, csrng_pkg::MainSmStateWidth)

// Signal probe function for `aes_ctrl_cs` of AES_CTRL_FSM
wire [5:0] aes_ctrl_fsm_state;
assign aes_ctrl_fsm_state =
`AES_CONTROL_HIER.gen_fsm[0].gen_fsm_p.u_aes_control_fsm_i.u_aes_control_fsm.aes_ctrl_cs;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_aes_ctrl_fsm_state,
aes_ctrl_fsm_state, 6)

// Signal probe function for `st_q` of HMAC
wire [2:0] hmac_fsm_state;
assign hmac_fsm_state = `HMAC_HIER.u_hmac.st_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_hmac_fsm_state,
hmac_fsm_state, 3)

// Signal probe function for `st` of KMAC_CORE
wire [5:0] kmac_fsm_state;
assign kmac_fsm_state = `KMAC_HIER.u_kmac_core.st;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_kmac_fsm_state,
kmac_fsm_state, 6)

// Signal probe function for `state_q` OTBN_START_STOP_CONTROL
wire [6:0] otbn_fsm_state;
assign otbn_fsm_state = `OTBN_HIER.u_otbn_core.u_otbn_start_stop_control.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_otbn_fsm_state,
otbn_fsm_state, 7)

// Signal probe function for `state_q` of EDN_0_MAIN_SM
wire [8:0] edn_0_fsm_state;
assign edn_0_fsm_state = `EDN_HIER(0).u_edn_core.u_edn_main_sm.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_edn_0_fsm_state,
edn_0_fsm_state, 9)

// Signal probe function for `state_q` of EDN_1_MAIN_SM
wire [8:0] edn_1_fsm_state;
assign edn_1_fsm_state = `EDN_HIER(1).u_edn_core.u_edn_main_sm.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_edn_1_fsm_state,
edn_1_fsm_state, 9)

// Signal probe function for `state_q` of ENTROPY_SOURCE_MAIN_SM
wire [8:0] entropy_src_fsm_state;
assign entropy_src_fsm_state = `ENTROPY_SRC_HIER.u_entropy_src_core.u_entropy_src_main_sm.state_q;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_entropy_src_fsm_state,
entropy_src_fsm_state, 9)

// Signal probe function for `chan0.enable` and `chan1.enable`of PATTGEN
wire [1:0] pattgen_chan_1_0_enable;
assign pattgen_chan_1_0_enable = {`PATTGEN_HIER.u_pattgen_core.chan1.enable,
`PATTGEN_HIER.u_pattgen_core.chan0.enable};
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_pattgen_chan_1_0_enable,
pattgen_chan_1_0_enable, 2)

// tb.dut.top_earlgrey.u_pwm_aon.u_pwm_core.cntr_en
wire pwm_core_cntr_en;
assign pwm_core_cntr_en = `PWM_HIER.u_pwm_core.cntr_en;
`DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_pwm_core_cntr_en,
pwm_core_cntr_en, 1)

`undef TOP_HIER
`undef ADC_CTRL_HIER
`undef AES_HIER
`undef AES_CONTROL_HIER
`undef ALERT_HANDLER_HIER
`undef AON_TIMER_HIER
`undef AST_HIER
Expand Down
91 changes: 89 additions & 2 deletions hw/top_earlgrey/dv/env/seq_lib/chip_sw_power_virus_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,88 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq;
end join
endtask

// A utility function to check the FSM states of the IPs.
virtual task check_ip_activity();
logic [4:0] adc_ctrl_state;
logic spi_device_cio_csb_i;
logic spi_host_0_cio_csb_o;
logic [2:0] spi_host_1_state;
logic [csrng_pkg::MainSmStateWidth-1:0] csrng_main_fsm_state;
logic [5:0] aes_ctrl_fsm_state;
logic [2:0] hmac_fsm_state;
logic [5:0] kmac_fsm_state;
logic [6:0] otbn_fsm_state;
logic [8:0] edn_0_fsm_state;
logic [8:0] edn_1_fsm_state;
logic [8:0] entropy_src_fsm_state;
logic [1:0] pattgen_chan_1_0_enable;
logic pwm_core_cntr_en;

// Wait for max-power indicator GPIO pin (IOB8) to go up.
wait (cfg.chip_vif.mios[top_earlgrey_pkg::MioPadIob8]);
// Wait for 16 clock cycles.
cfg.clk_rst_vif.wait_clks(16);

// Sample the FSM states of the IPs.
adc_ctrl_state = cfg.chip_vif.signal_probe_adc_ctrl_fsm_state(SignalProbeSample);
spi_device_cio_csb_i = cfg.chip_vif.signal_probe_spi_device_cio_csb_i(SignalProbeSample);
spi_host_0_cio_csb_o = cfg.chip_vif.signal_probe_spi_host_0_cio_csb_o(SignalProbeSample);
spi_host_1_state = cfg.chip_vif.signal_probe_spi_host_1_fsm_state(SignalProbeSample);
csrng_main_fsm_state = cfg.chip_vif.signal_probe_csrng_main_fsm_state(SignalProbeSample);
aes_ctrl_fsm_state = cfg.chip_vif.signal_probe_aes_ctrl_fsm_state(SignalProbeSample);
hmac_fsm_state = cfg.chip_vif.signal_probe_hmac_fsm_state(SignalProbeSample);
kmac_fsm_state = cfg.chip_vif.signal_probe_kmac_fsm_state(SignalProbeSample);
otbn_fsm_state = cfg.chip_vif.signal_probe_otbn_fsm_state(SignalProbeSample);
edn_0_fsm_state = cfg.chip_vif.signal_probe_edn_0_fsm_state(SignalProbeSample);
edn_1_fsm_state = cfg.chip_vif.signal_probe_edn_1_fsm_state(SignalProbeSample);
entropy_src_fsm_state = cfg.chip_vif.signal_probe_entropy_src_fsm_state(SignalProbeSample);
pattgen_chan_1_0_enable = cfg.chip_vif.signal_probe_pattgen_chan_1_0_enable(SignalProbeSample);
pwm_core_cntr_en = cfg.chip_vif.signal_probe_pwm_core_cntr_en(SignalProbeSample);
`uvm_info(`gfn, $sformatf("adc_ctrl_state = 0x%0x", adc_ctrl_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("spi_device_cio_csb_i = 0x%0x", spi_device_cio_csb_i),
UVM_LOW);
`uvm_info(`gfn, $sformatf("spi_host_0_cio_csb_o = 0x%0x", spi_host_0_cio_csb_o),
UVM_LOW);
`uvm_info(`gfn, $sformatf("spi_host_1_state = 0x%0x", spi_host_1_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("csrng_main_fsm_state = 0x%0x", csrng_main_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("aes_ctrl_fsm_state = 0x%0x", aes_ctrl_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("hmac_fsm_state = 0x%0x", hmac_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("kmac_fsm_state = 0x%0x", kmac_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("otbn_fsm_state = 0x%0x", otbn_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("edn_0_fsm_state = 0x%0x", edn_0_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("edn_1_fsm_state = 0x%0x", edn_1_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("entropy_src_fsm_state = 0x%0x", entropy_src_fsm_state),
UVM_LOW);
`uvm_info(`gfn, $sformatf("pattgen_chan_1_0_enable = 0x%0x", pattgen_chan_1_0_enable),
UVM_LOW);
`uvm_info(`gfn, $sformatf("pwm_core_cntr_en = 0x%0x", pwm_core_cntr_en),
UVM_LOW);

`DV_CHECK_NE(adc_ctrl_state, adc_ctrl_pkg::PWRDN);
`DV_CHECK_NE(spi_device_cio_csb_i, /*Idle*/1'b1);
`DV_CHECK_NE(spi_host_0_cio_csb_o, /*Idle*/1'b1);
`DV_CHECK_NE(spi_host_1_state, /*Idle*/3'b000);
`DV_CHECK_NE(csrng_main_fsm_state, csrng_pkg::MainSmIdle);
`DV_CHECK_NE(aes_ctrl_fsm_state, aes_pkg::CTRL_IDLE);
`DV_CHECK_NE(hmac_fsm_state, /*StIdle*/3'b000);
`DV_CHECK_NE(kmac_fsm_state, /*StKmacIdle*/6'b011000);
`DV_CHECK_NE(otbn_fsm_state, otbn_pkg::OtbnStartStopStateInitial);
`DV_CHECK_NE(edn_0_fsm_state, edn_pkg::Idle);
`DV_CHECK_NE(edn_1_fsm_state, edn_pkg::Idle);
`DV_CHECK_NE(entropy_src_fsm_state, entropy_src_main_sm_pkg::Idle);
`DV_CHECK_NE(pattgen_chan_1_0_enable,/*{chan1_en, chan0_en}*/2'b00);
`DV_CHECK_NE(pwm_core_cntr_en, 1'b0);
endtask

task pre_start();
// i2c_agent configs
configure_i2c_agents();
Expand Down Expand Up @@ -162,8 +244,8 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq;
$assertoff(0, "tb.dut.top_earlgrey.u_spi_device.u_readcmd.u_readsram.u_fifo.DataKnown_A");
super.body();

// Wait for test_main() to start and configurations to be computed.
`DV_WAIT(cfg.sw_logger_vif.printed_log == "All IPs configured.");
// Wait for configurations to be computed and max power epoch to start.
`DV_WAIT(cfg.sw_logger_vif.printed_log == "Entering max power epoch ...");

// Main fork-join block to handle IP-specific threads
fork
Expand All @@ -187,6 +269,11 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq;
// Send the command and check the response.
execute_spi_flash_sequence();
end

begin : ip_activity_check_thread
// Check if the IPs are active at the beginning of max power epoch.
check_ip_activity();
end
join
endtask

Expand Down
23 changes: 20 additions & 3 deletions sw/device/tests/power_virus_systemtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,20 @@ static void max_power_task(void *task_parameters) {
pattgen_ctrl_reg =
bitfield_bit32_write(pattgen_ctrl_reg, PATTGEN_CTRL_ENABLE_CH1_BIT, true);

// Prepare adc_ctrl enablement command
uint32_t adc_ctrl_reg =
mmio_region_read32(adc_ctrl.base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET);
adc_ctrl_reg = bitfield_bit32_write(adc_ctrl_reg,
ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, true);

// Prepare PWM channels for the enablement. The outputs will start toggling
// after the phase counter is enabled (i.e, PWM_CFG_REG.CNTR_EN = 1).
uint32_t pwm_cfg_reg = mmio_region_read32(pwm.base_addr, PWM_CFG_REG_OFFSET);
pwm_cfg_reg = bitfield_bit32_write(pwm_cfg_reg, PWM_CFG_CNTR_EN_BIT, true);
// Enable all the PWM channels.
mmio_region_write32(pwm.base_addr, PWM_PWM_EN_REG_OFFSET,
(1u << PWM_PARAM_N_OUTPUTS) - 1);

// Prepare GPIO register values (for max power indicator).
const uint32_t gpio_on_reg_val = (1u << 16) | 1u;
const uint32_t gpio_off_reg_val = 1u << 16;
Expand All @@ -1152,9 +1166,12 @@ static void max_power_task(void *task_parameters) {

LOG_INFO("Entering max power epoch ...");

// Enable all PWM channels
mmio_region_write32(pwm.base_addr, PWM_PWM_EN_REG_OFFSET,
(1u << PWM_PARAM_N_OUTPUTS) - 1);
// Enable adc_ctrl
mmio_region_write32(adc_ctrl.base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
adc_ctrl_reg);

// Enable toggling at all PWM channels by enabling the phase counter.
mmio_region_write32(pwm.base_addr, PWM_CFG_REG_OFFSET, pwm_cfg_reg);

// Enable all UARTs and I2Cs.
mmio_region_write32(uart_1.base_addr, UART_CTRL_REG_OFFSET, uart_ctrl_reg);
Expand Down

0 comments on commit 49b2e4f

Please sign in to comment.