AON Timer DV Document
- Verify the always-on timer (AON Timer) by running dynamic simulations with a SV/UVM based testbench
- Develop and run all tests based on the DV plan below towards closing code and functional coverage on the IP and all of its sub-modules
- Verify TileLink device protocol compliance with an SVA based testbench
The AON timer is documented in the AON Timer HWIP technical specification.
The testbench is based on the CIP testbench architecture.
The block’s testbench is located at
It instantiates the
aon_timer DUT module, defined at
In addition, it instantiates the following interfaces, connects them to the DUT and registers their handles in
- A clock and reset interface for the fast clock
- A clock and reset interface for the AON clock
- A TileLink host interface The AON timer exposes a TL device. Here, the testbench is acting as the host CPU; in the OpenTitan SoC, this will be the Ibex core.
- Two interrupts (wakeup timer; watchdog bark) in the fast clock domain
- Two interrupts (wakeup timer; watchdog bite) in the AON clock domain
- The sleep mode input
- The core interface (see below).
The interrupts and sleep mode input are modelled with the basic
The AON timer uses three clock domains (
clk_aon_i), with synchronisation logic between them.
The following diagram shows the different inputs and outputs for the module and in which clock domain each resides.
To model this accurately without having to precisely model the timing of the synchronisation logic, the testbench is split into two pieces.
The first piece has a precise model of the AON timer core and checks that the DUT respects it.
The second piece has an approximate timing model and checks forwarding between the async, fast and slow clock domains.
These pieces are connected through a bound-in interface, which observes signals on the
This core interface is bound into the design as
u_core_if and is used to passively monitor the signals coming in and out of the AON Timer Core block in this diagram.
In order to communicate through the register interface, the testbench uses the tl_agent that is instantiated in the CIP base environment. This is also used by generic test sequences to exercise the register interface.
UVM RAL Model
aon_timer RAL model is created with the
ralgen FuseSoC generator script automatically when the simulation is at the build stage.
It can be created manually by invoking
util/regtool.py -s -t . hw/ip/aon_timer/data/aon_timer.hjson
aon_timer_ral_pkg.sv in the current directory.
We want to see timers expire without waiting too long, but we also want to check the counter for large values. To get this right, we normally set up tests as follows:
- Pick a threshold value
- Pick a start count slightly below the threshold value
Occasionally, we’ll pick a start count above the threshold value, to make sure nothing triggers when it shouldn’t. To ensure that we check wrap-around behaviour and see toggles on counter bits, we are careful to pick threshold values more often if they are near zero, the maximum value, or powers of two.
Since the two timers are essentially independent, we use two test sequences, driving them separately.
The test sequences can be found in
The basic test virtual sequence configures the block in a valid initial state, but doesn’t enable either timer.
This is used as a base class for automated tests like the CSR tests.
TODO: Describe other test sequences here.
TODO: Functional coverage points are not yet defined.
As described earlier in this document, the self-checking strategy is in two parts. The first part of the strategy is to track the domain crossing logic and check that values propagate across unmodified and reasonably quickly. This does not include precise modelling for the CDC timing.
The second part of the self-checking logic looks at only the core interface.
This is an interface of type
aon_timer_core_if, that is bound into the
Here, there is a single clock domain (the AON clock) and easily predictable behaviour.
The scoreboard contains an exact model of how the signals exposed by this interface will behave.
Putting the two parts of the scoreboard together gives a full checker for the block. An incoming configuration write will be tracked (with slightly flexible timing) through the CDC logic by the first part of the scoreboard. Once it takes effect in the core, the second part of the scoreboard will check that things behave correctly. Finally, outputs (in the form of configuration register updates or interrupts) will be tracked by the first part of the scoreboard as they go back through the CDC logic and, eventually, make it out to the top-level.
TLUL protocol assertions are checked by binding the TL-UL protocol checker into the design.
Outputs are also checked for
'X values by assertions in the design RTL.
Building and running tests
Tests can be run with
The link gives details of the tool’s features and command line arguments.
To run a basic smoke test, go to the top of the repository and run:
$ util/dvsim/dvsim.py hw/ip/aon_timer/dv/aon_timer_sim_cfg.hjson -i aon_timer_smoke
Smoke test accessing a major datapath within the aon_timer.
Add more test entries here like above.
Verify the reset values as indicated in the RAL specification.
Verify accessibility of CSRs as indicated in the RAL specification.
Verify no aliasing within individual bits of a CSR.
Verify no aliasing within the CSR address space.
Verify random reset during CSR/memory access.
Verify accessibility of all memories in the design.
Verify partial-accessibility of all memories in the design.
Verify common intr_test CSRs that allows SW to mock-inject interrupts.
Access out of bounds address and verify correctness of response / behavior
Drive unsupported requests via TL interface and verify correctness of response / behavior. Below error cases are tested
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.
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