From 49b2e4f8f0fbdbf53fa3a3f901d813fe4e3f826d Mon Sep 17 00:00:00 2001 From: Bilgiday Yuce Date: Fri, 31 Mar 2023 01:33:40 +0000 Subject: [PATCH] [test] Add DVsim support for the activity-checking part of power virus 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 --- hw/top_earlgrey/dv/env/chip_if.sv | 93 +++++++++++++++++++ .../env/seq_lib/chip_sw_power_virus_vseq.sv | 91 +++++++++++++++++- sw/device/tests/power_virus_systemtest.c | 23 ++++- 3 files changed, 202 insertions(+), 5 deletions(-) diff --git a/hw/top_earlgrey/dv/env/chip_if.sv b/hw/top_earlgrey/dv/env/chip_if.sv index 729141a4575c5..73b9f7374200e 100644 --- a/hw/top_earlgrey/dv/env/chip_if.sv +++ b/hw/top_earlgrey/dv/env/chip_if.sv @@ -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 @@ -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 diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_power_virus_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_power_virus_vseq.sv index 91f0eda5effd3..fe2a9ae115fe8 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_power_virus_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_power_virus_vseq.sv @@ -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(); @@ -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 @@ -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 diff --git a/sw/device/tests/power_virus_systemtest.c b/sw/device/tests/power_virus_systemtest.c index 07b8540b683d0..15d15065adc21 100644 --- a/sw/device/tests/power_virus_systemtest.c +++ b/sw/device/tests/power_virus_systemtest.c @@ -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; @@ -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);