Testplan

Testpoints

Stage V1 Testpoints

smoke

Test: clkmgr_smoke

Smoke test disabling peripheral and transactional clocks.

  • Disables all peripheral clocks from their enabled reset state.
  • Transactional clocks gating depends on whether they are idle.
  • Initializes all units as busy (not idle).
  • Clears each unit’s clk_hints bit, which has no effect until the unit becomes idle.
  • Sets the unit’s idle_i bit, which should disable the clock.
  • Writes both values of the jitter_enable CSR.

Stimulus:

  • CSR writes to clk_enables and clk_hints.
  • Setting idle_i clkmgr input.

Checks:

  • SVA assertions for peripheral clocks enable and disable properties.
  • Transactional clocks check SVA properties as follows:
    • If the hint enables it, the clock becomes active.
    • If the hint disables it but the unit is busy, the clock remains active.
    • If the hint disables it and the unit is idle, the clock stops.
  • For transactional units the CSR clk_hints_status is checked to correspond to clk_hints once the units are idle.
  • Check in scoreboard the jitter_en_o output tracks updates of the jitter_enable CSR.

csr_hw_reset

Test: clkmgr_csr_hw_reset

Verify the reset values as indicated in the RAL specification.

  • Write all CSRs with a random value.
  • Apply reset to the DUT as well as the RAL model.
  • Read each CSR and compare it against the reset value. it is mandatory to replicate this test for each reset that affects all or a subset of the CSRs.
  • It is mandatory to run this test for all available interfaces the CSRs are accessible from.
  • Shuffle the list of CSRs first to remove the effect of ordering.

csr_rw

Test: clkmgr_csr_rw

Verify accessibility of CSRs as indicated in the RAL specification.

  • Loop through each CSR to write it with a random value.
  • Read the CSR back and check for correctness while adhering to its access policies.
  • It is mandatory to run this test for all available interfaces the CSRs are accessible from.
  • Shuffle the list of CSRs first to remove the effect of ordering.

csr_bit_bash

Test: clkmgr_csr_bit_bash

Verify no aliasing within individual bits of a CSR.

  • Walk a 1 through each CSR by flipping 1 bit at a time.
  • Read the CSR back and check for correctness while adhering to its access policies.
  • This verify that writing a specific bit within the CSR did not affect any of the other bits.
  • It is mandatory to run this test for all available interfaces the CSRs are accessible from.
  • Shuffle the list of CSRs first to remove the effect of ordering.

csr_aliasing

Test: clkmgr_csr_aliasing

Verify no aliasing within the CSR address space.

  • Loop through each CSR to write it with a random value
  • Shuffle and read ALL CSRs back.
  • All CSRs except for the one that was written in this iteration should read back the previous value.
  • The CSR that was written in this iteration is checked for correctness while adhering to its access policies.
  • It is mandatory to run this test for all available interfaces the CSRs are accessible from.
  • Shuffle the list of CSRs first to remove the effect of ordering.

csr_mem_rw_with_rand_reset

Test: clkmgr_csr_mem_rw_with_rand_reset

Verify random reset during CSR/memory access.

  • Run csr_rw sequence to randomly access CSRs
  • If memory exists, run mem_partial_access in parallel with csr_rw
  • Randomly issue reset and then use hw_reset sequence to check all CSRs are reset to default value
  • It is mandatory to run this test for all available interfaces the CSRs are accessible from.

regwen_csr_and_corresponding_lockable_csr

Tests:

  • clkmgr_csr_rw
  • clkmgr_csr_aliasing

Verify regwen CSR and its corresponding lockable CSRs.

  • Randomly access all CSRs
  • Test when regwen CSR is set, its corresponding lockable CSRs become read-only registers

Note:

  • If regwen CSR is HW read-only, this feature can be fully tested by common CSR tests - csr_rw and csr_aliasing.
  • If regwen CSR is HW updated, a separate test should be created to test it.

This is only applicable if the block contains regwen and locakable CSRs.

Stage V2 Testpoints

peri_enables

Test: clkmgr_peri

Peripheral clocks are disabled if its clk_enables bit is off, or the corresponding pwr_i.*_ip_clk_en is off, and scanmode_i is not lc_ctrl_pkg::On.

This test runs multiple rounds which do the following:

  • Randomize pwr_i.usb_ip_clk_en and scanmode_i, and the initial setting of clk_enables.
  • Send a CSR write to clk_enables with its initial value.
  • Send a CSR write to clk_enables that flips all bits.

It makes no sense to have pwr_i.io_ip_clk_en set to zero since that would prevent the CPU from running and sending CSR updates.

Checks:

  • SVA assertions for peripheral clocks enable and disable properties.

trans_enables

Test: clkmgr_trans

Transactional unit clocks are disabled if they are idle and their CSR clk_hints bit is off, or pwr_i.main_ip_clk_en is off, and scanmode_i is not lc_ctrl_pkg::On. This test randomizes the initial setting of idle_i and the desired value of clk_hints. Each round performs this sequence:

  • Writes the desired value to CSR clk_hints and checks that the CSR clk_hints_status reflects CSR clk_hints except for the units not-idle.
  • Marks all units as idle, and checks that csr_hints_status matches clk_hints.
  • Writes clk_hints to all ones and checks that csr_hints_status is all ones.
  • Writes clk_hints with its reset value.

Checks:

  • SVA assertions for transactional unit clocks described in clkmgr_smoke.

extclk

Test: clkmgr_extclk

Tests the functionality of enabling external clocks.

  • External clock is enabled if the lc_clk_byp_req_i input from lc_ctrl is lc_ctrl_pkg::On.
  • External clock is also be enabled when CSR extclk_ctrl.sel is set to lc_ctrl_pkg::On and the lc_dtl_en_i input from lc_ctrl is lc_ctrl_pkg::On.
  • Notice writes to the extclk_ctrl.sel register are ignored unless the CSR extclk_ctrl_regwen is 1.
  • A successful switch to external clocks due to lc_clk_byl_req_i will cause the clkmgr to undo a divide by 2 for io_div4 and io_div2 clocks except when (scanmode_i == prim_mubi_pkg::MuBi4True).
  • A software triggered switch to external clock will undo divides by 2 if extclk_ctrl.hi_speed_sel is set to prim_mubi_pkg::MuBi4True.

Stimulus:

  • CSR writes to extclk_ctrl and extclk_ctrl_regwen.
  • Setting lc_hw_debug_en_i, lc_clk_byp_req_i, and the handshake to ast via ast_clk_byp_req_o and ast_clk_byp_ack_i.
  • Setting scanmode_i.

Checks: Clock divider checks are done with SVA assertions.

  • When the external clock is selected (and not defeated by scanmode_i for scoreboard checks):
    • The clk_io_div2_powerup output matches the clk_io_powerup output.
    • The clk_io_div4_powerup output matches the clk_io_powerup output at half its frequency.
  • When the external clock is not selected or division is defeated:
    • The clk_io_div2_powerup output matches the clk_io_powerup output at half its frequency.
    • The clk_io_div4_powerup output matches the clk_io_powerup output at a quarter of its frequency. LC / AST handshake:
  • When the external clock functionality is triggered the ast_clk_byp_req_o output pin is set to lc_ctrl_pkg::On.
  • When ast_clk_byp_ack_i is set to lc_ctrl_pkg::On in response to a corresponding request:
    • The clock dividers are stepped down, unless defeated by scanmode_i being lc_ctrl_pkg::On.
  • If the initial request was due to the assertion of the lc_clk_byp_req_i, the lc_clk_byp_ack_o output is set to lc_ctrl_pkg::On.

clk_status

Test: clkmgr_clk_status

This tests the three pwr_o.*_status output ports, for the io, main, and usb clocks.

The pwr_o.*_status output must track the correspponding pwr_i.*_ip_clk_en input.

Stimulus:

  • Randomize the pwr_i.*_ip_clk_en setting for each clock.

Check:

  • The checks are done in SVA at clkmgr_pwrmgr_sva_if.sv.

jitter

Test: clkmgr_smoke

This tests the jitter functionality.

The jitter functionality is implemented by the AST block, but controlled by the jitter_enable CSR in this block. This CSR directly drives the jitter_en_o output pin.

Stimulus:

  • CSR write to jitter_enable.

Check:

  • The jitter_en_o output pin reflects the jitter_enable CSR. Test is implemented in the scoreboard, and is always running.

frequency

Test: clkmgr_frequency

This tests the frequency counters measured count functionality.

These counters compute the number of cycles of each clock relative to the aon timer, and compares it to the corresponding thresholds written into the *_meas_ctrl_shadowed CSR. Measurements beyond these thresholds trigger a recoverable alert and set a bit in the recov_err_code CSR. Also, if the counters reach their maximum value they don’t wrap around.

If clock calibration is lost, indicated by the calib_rdy_i input being prim_mubi_pkg::MuBi4False, the measurements stop, no error is triggered, and measure_ctrl_regwen is set to 1.

Stimulus:

  • Randomly set slow, correct, and fast interval for each counter and test.
  • Randomly set the calib_rdy_i input.
  • Randomly trigger a clock saturation by forcing its cycle count to be near its maximum value while counting.

Check:

  • Slow and fast intervals should cause a recoverable alert.
  • Coverage collected per clock.

frequency_timeout

Test: clkmgr_frequency_timeout

This tests the frequency counters timeout functionality.

These counters compute the number of cycles of some clock relative to the aon timer. It should trigger a recoverable alert when there is no valid measurement when enabled, leading to a timeout. This is separate from the frequenty testpoint to simplify the test checks.

Stimulus:

  • Randomly stop measured clocks to trigger a timeout.

Check:

  • Timeout should cause a recoverable alert.
  • Coverage collected per clock.

frequency_overflow

Test: clkmgr_frequency

This tests the overflow feature in prim_clock_meas.

This needs to modify the state of the counter to trigger the feature.

Stimulus:

  • Program the counter. Whenever it hits the value of 1, set it to the range - 2.

Check:

  • The internal cnt_ovfl flop is set.
  • The fast_o output should be set.

stress_all

Test: clkmgr_stress_all

This runs random sequences in succession.

Randomly chooses from the following sequences:

  • clkmgr_extclk_vseq,
  • clkmgr_frequency_timeout_vseq,
  • clkmgr_frequency_vseq,
  • clkmgr_peri_vseq,
  • clkmgr_smoke_vseq,
  • clkmgr_trans_vseq

intr_test

Test: clkmgr_intr_test

Verify common intr_test CSRs that allows SW to mock-inject interrupts.

  • Enable a random set of interrupts by writing random value(s) to intr_enable CSR(s).
  • Randomly “turn on” interrupts by writing random value(s) to intr_test CSR(s).
  • Read all intr_state CSR(s) back to verify that it reflects the same value as what was written to the corresponding intr_test CSR.
  • Check the cfg.intr_vif pins to verify that only the interrupts that were enabled and turned on are set.
  • Clear a random set of interrupts by writing a randomly value to intr_state CSR(s).
  • Repeat the above steps a bunch of times.

alert_test

Test: clkmgr_alert_test

Verify common alert_test CSR that allows SW to mock-inject alert requests.

  • Enable a random set of alert requests by writing random value to alert_test CSR.
  • Check each alert_tx.alert_p pin to verify that only the requested alerts are triggered.
  • During alert_handshakes, write alert_test CSR again to verify that: If alert_test writes to current ongoing alert handshake, the alert_test request will be ignored. If alert_test writes to current idle alert handshake, a new alert_handshake should be triggered.
  • Wait for the alert handshakes to finish and verify alert_tx.alert_p pins all sets back to 0.
  • Repeat the above steps a bunch of times.

tl_d_oob_addr_access

Test: clkmgr_tl_errors

Access out of bounds address and verify correctness of response / behavior

tl_d_illegal_access

Test: clkmgr_tl_errors

Drive unsupported requests via TL interface and verify correctness of response / behavior. Below error cases are tested bases on the TLUL spec

  • TL-UL protocol error cases
    • invalid opcode
    • some mask bits not set when opcode is PutFullData
    • mask does not match the transfer size, e.g. a_address = 0x00, a_size = 0, a_mask = 'b0010
    • mask and address misaligned, e.g. a_address = 0x01, a_mask = 'b0001
    • address and size aren’t aligned, e.g. a_address = 0x01, a_size != 0
    • size is greater than 2
  • OpenTitan defined error cases
    • access unmapped address, expect d_error = 1
    • write a CSR with unaligned address, e.g. a_address[1:0] != 0
    • write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte
    • write a memory with a_mask != '1 when it doesn’t support partial accesses
    • read a WO (write-only) memory
    • write a RO (read-only) memory
    • write with instr_type = True

tl_d_outstanding_access

Tests:

  • clkmgr_csr_hw_reset
  • clkmgr_csr_rw
  • clkmgr_csr_aliasing
  • clkmgr_same_csr_outstanding

Drive back-to-back requests without waiting for response to ensure there is one transaction outstanding within the TL device. Also, verify one outstanding when back- to-back accesses are made to the same address.

tl_d_partial_access

Tests:

  • clkmgr_csr_hw_reset
  • clkmgr_csr_rw
  • clkmgr_csr_aliasing
  • clkmgr_same_csr_outstanding

Access CSR with one or more bytes of data. For read, expect to return all word value of the CSR. For write, enabling bytes should cover all CSR valid fields.

Stage V2S Testpoints

tl_intg_err

Tests:

  • clkmgr_tl_intg_err
  • clkmgr_sec_cm

Verify that the data integrity check violation generates an alert.

  • Randomly inject errors on the control, data, or the ECC bits during CSR accesses. Verify that triggers the correct fatal alert.
  • Inject a fault at the onehot check in u_reg.u_prim_reg_we_check and verify the corresponding fatal alert occurs

shadow_reg_update_error

Test: clkmgr_shadow_reg_errors

Verify shadowed registers’ update error.

  • Randomly pick a shadowed register in the DUT.
  • Write it twice with different values.
  • Verify that the update error alert is triggered and the register value remains unchanged.
  • Verify the update_error status register field is set to 1.
  • Repeat the above steps a bunch of times.

shadow_reg_read_clear_staged_value

Test: clkmgr_shadow_reg_errors

Verify reading a shadowed register will clear its staged value.

  • Randomly pick a shadowed register in the DUT.
  • Write it once and read it back to clear the staged value.
  • Then write it twice with the same new value (but different from the previous step).
  • Read it back to verify the new value and ensure that the update error alert did not trigger.
  • Verify the update_error status register field remains the same value.
  • Repeat the above steps a bunch of times.

shadow_reg_storage_error

Test: clkmgr_shadow_reg_errors

Verify shadowed registers’ storage error.

  • Randomly pick a shadowed register in the DUT.
  • Backdoor write to shadowed or committed flops to create a storage fatal alert.
  • Check if fatal alert continuously fires until reset.
  • Verify that all other frontdoor write attempts are blocked during the storage error.
  • Verify that storage_error status register field is set to 1.
  • Reset the DUT.
  • Read all CSRs to ensure the DUT is properly reset.
  • Repeat the above steps a bunch of times.

shadowed_reset_glitch

Test: clkmgr_shadow_reg_errors

Verify toggle shadowed_rst_n pin can trigger storage error.

  • Randomly drive shadowed_rst_n pin to low or rst_n pin to low.
  • check if any registers have been written before the reset. If so check if storage error fatal alert is triggered.
  • Check status register.
  • Drive shadowed_rst_n pin or rst_n pin back to high.
  • If fatal alert is triggered, reset the DUT.
  • Read all CSRs to ensure the DUT is properly reset.
  • Repeat the above steps a bunch of times.

shadow_reg_update_error_with_csr_rw

Test: clkmgr_shadow_reg_errors_with_csr_rw

Run shadow_reg_update_error sequence in parallel with csr_rw sequence.

  • Randomly select one of the above sequences.
  • Apply csr_rw sequence in parallel but disable the csr_access_abort to ensure all shadowed registers’ write/read to be executed without aborting.
  • Repeat the above steps a bunch of times.

sec_cm_bus_integrity

Test: clkmgr_tl_intg_err

Verify the countermeasure(s) BUS.INTEGRITY. This entry is covered by tl_access_test.

sec_cm_meas_clk_bkgn_chk

Test: clkmgr_frequency

Verify the countermeasure(s) MEAS.CLK.BKGN_CHK.

  • Test measurement feature of clkmgr_meas_chk modules. For all test clocks (clk_main, clk_usb, clk_io, clk_io_div2 and clk_io_div4), do measurement with normal configuration. Then change either min or max threshold value to see whether the module can detect measurement error for each test clock.
  • Measurement error should trigger a recoverable alert

sec_cm_timeout_clk_bkgn_chk

Test: clkmgr_frequency_timeout

Verify the countermeasure(s) TIMEOUT.CLK.BKGN_CHK.

  • Test timeout feature of clkmgr_meas_chk modules. While frequency measurement, one of clk_main, clk_usb, clk_io, clk_io_div2 and clk_io_div4 are choose and stopped. This will leads to timeout event.
  • Timeout should cause a recoverable alert

sec_cm_meas_config_shadow

Test: clkmgr_shadow_reg_errors

Verify the countermeasure(s) MEAS.CONFIG.SHADOW.

This is covered by shadow_reg_errors_tests (https://github.com/lowRISC/opentitan/blob/master/ hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson)

sec_cm_idle_intersig_mubi

Test: clkmgr_idle_intersig_mubi

Verify the countermeasure(s) IDLE.INTERSIG.MUBI. It uses true_strict and false_loose. Stimulus: Use same sequence as trans_enables test. Randomize dut.idle_i ports with illegal values. Check:

  • hins_status check: When clk_hints update from ‘1’ to ‘0’, clk_hints_status has to wait idle becomes ‘true’. So check clk_hints_status with random idle value, then check again after set all idle values to ‘true’.

  • clock output check: When clk_hints_status go to ‘0’, check clocks_o to see if clock is really off

sec_cm_lc_ctrl_intersig_mubi

Test: clkmgr_lc_ctrl_intersig_mubi

Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI. It compares to lc_ctrl_pkg::On only. Use clkmgr_extclk test as in testplan.extclk but randomize dut.lc_hw_debug_en_i s.t. all 16 values can be generated with equal priority.

Checks: When dut sees invalid values of lc_hw_debug_en_i, all_clk_byp_req should not be asserted. Covered by assertion checker.

sec_cm_lc_ctrl_clk_handshake_intersig_mubi

Test: clkmgr_lc_clk_byp_req_intersig_mubi

Verify the countermeasure(s) LC_CTRL_CLK_HANDSHAKE.INTERSIG.MUBI. It compared to lc_ctrl_pkg::On only. Use clkmgr_extclk test but randomize lc_clk_byp_req s.t. all 16 values can be generated with equal priority. lc_clk_byp_req drives dut.lc_clk_byp_req_i in the test. Checks: When dut sees invalid values of lc_clk_byp_req_i, io_clk_byp_req_o should not be asserted. Covered by assertion checker.

sec_cm_clk_handshake_intersig_mubi

Test: clkmgr_clk_handshake_intersig_mubi

Verify the countermeasure(s) CLK_HANDSHAKE.INTERSIG.MUBI. It uses true_strict. Use clkmgr_extclk test. Upon receiving [io|all]_clk_byp_req_o from dut, assert invalid [io|all]_clk_byp_ack values to dut.

Check: all_clk_byp_ack is copied to CLKGMR.EXTCLK_STATUS as is. So read extclk status and compare. io_clk_byp_ack is evaluated with step_down_acks_syn. When both are true, lc_clk_byp_req is assigned to lc_clk_byp_ack. Covered by assertion checker.

sec_cm_div_intersig_mubi

Test: clkmgr_div_intersig_mubi

Verify the countermeasure(s) DIV.INTERSIG.MUBI. use true_strict. Use clkmgr_extclk test. Before, test drive dut.div_step_down_req_i with ‘true’, sends invalid values. Check: dut should ignore invalid req values. Covered by assertion checker.

sec_cm_jitter_config_mubi

Test: clkmgr_csr_rw

Verify the countermeasure(s) JITTER.CONFIG.MUBI. use false_strict. This doesn’t do any function in the dut but indicating jittery clock is enabled. So it can be covered by default csr test.

sec_cm_idle_ctr_redun

Test: clkmgr_sec_cm

Verify the countermeasure(s) IDLE.CTR.REDUN. This is triggered by common cm primitives (SecCmPrimCount). Check: read check CLKMGR.FATAL_ERR_CODE.IDLE_CNT == 1

sec_cm_meas_config_regwen

Test: clkmgr_csr_rw

Verify the countermeasure(s) MEAS.CONFIG.REGWEN.

This is covered by auto csr test.

sec_cm_clk_ctrl_config_regwen

Test: clkmgr_csr_rw

Verify the countermeasure(s) CLK_CTRL.CONFIG.REGWEN.

This is covered by auto csr test.

prim_count_check

Test: clkmgr_sec_cm

Verify that violating prim_count counter properties generate a fatal alert.

Stimulus:

  • At the falling edge (non-active edge), force the counter to a different value than expected.
  • Randomly force the counter back to a normal value to ensure the error is latched and won’t go away until reset.
  • Within the next few cycles, the violation of hardened counter property should generate a fatal alert.
  • Repeat for ALL prim_count instances in the DUT.

Checks:

  • Check that fatal alert is triggered.
  • Check that err_code/fault_status is updated correctly and preserved until reset.
  • Verify any operations that follow fail (as applicable).

Stage V3 Testpoints

regwen

Test: clkmgr_regwen

This tests the behavior of the regwen CSRs.

When a regwen is clear, any write to CSRs it locks are ignored. Once a regwen is cleared, it will only be set again after a full reset.

Stimulus:

  • Clear each regwen.
  • Write to the corresponding locked CSRs.

Check:

  • The locked CSR value is not updated.

stress_all_with_rand_reset

Test: clkmgr_stress_all_with_rand_reset

This test runs 3 parallel threads - stress_all, tl_errors and random reset. After reset is asserted, the test will read and check all valid CSR registers.

Covergroups

extclk_cg

Collects coverage for the external clock selection.

The external clock selection depends on the extclk_ctrl CSR fields sel and hi_speed_sel, and the lc_hw_debug_en_i, lc_clk_byp_req_i, and scanmode_i input pins. This covergroup collects their cross.

freq_measure_cg

Collects coverage for the frequency measurement counters.

The relevant information is whether it got an okay, slow, or fast measurement, or a timeout.

peri_cg

Collects coverage for each peripheral clock.

The peripheral clocks depend on a bit in the clk_enables CSR, the ip_clk_en input from pwrmgr, and the scanmode input. This collects the cross of them for each peripheral.

FIXME This is collected in an array, one instance for each clock, but the dvsim coverage flow doesn’t yet support arrays.

regwen_val_when_new_value_written_cg

Cover each lockable reg field with these 2 cases:

  • When regwen = 1, a different value is written to the lockable CSR field, and a read occurs after that.
  • When regwen = 0, a different value is written to the lockable CSR field, and a read occurs after that.

This is only applicable if the block contains regwen and locakable CSRs.

shadow_field_errs_cg

Cover all shadow register errors for each register field.

For all register fields within the shadowed register, this coverpoint covers the following errors:

  • Update error
  • Storage error

tl_errors_cg

Cover the following error cases on TL-UL bus:

  • TL-UL protocol error cases.
  • OpenTitan defined error cases, refer to testpoint tl_d_illegal_access.

tl_intg_err_cg

Cover all kinds of integrity errors (command, data or both) and cover number of error bits on each integrity check.

Cover the kinds of integrity errors with byte enabled write on memory if applicable: Some memories store the integrity values. When there is a subword write, design re-calculate the integrity with full word data and update integrity in the memory. This coverage ensures that memory byte write has been issued and the related design logic has been verfied.

trans_cg

Collects coverage for each transactional unit clock.

The transactional unit clocks depend on a bit in the clk_hints CSR, the ip_clk_en input from pwrmgr, the respective idle input bit from the unit, and the scanmode input. This collects the cross of them for each transactional unit.

FIXME This is collected in an array, one instance for each clock, but the dvsim coverage flow doesn’t yet support arrays.