Skip to content
STIMSMITH

Boot code execution

Concept WIKI v1 · 6/9/2026

Boot code execution refers to the initial software that runs on a hardware circuit immediately after reset, typically responsible for initializing and clearing microarchitectural state. In the context of formal hardware verification, modeling many cycles of boot code execution is essential for proving security properties such as deterministic start and output determinism, but the large number of cycles involved poses significant challenges for traditional bounded model checking tools, which scale exponentially with the number of execution cycles.

Boot code execution

Definition and purpose

Boot code execution refers to the cycle-accurate execution of the initial software that a hardware circuit runs after reset. In a typical system-on-chip (SoC), this boot code is responsible for clearing uninitialized microarchitectural state and bringing the hardware into a known, deterministic configuration before any application software is loaded. For example, in the MicroTitan RISC-V SoC (a subset of OpenTitan), boot code takes 24,516 cycles to clear the chip's uninitialized state, compared to only 104 cycles for the simpler PicoRV32 CPU [chunk: 91532559-482e-4d7c-96dd-390c79237ffc, 8f0d2e8d-6757-4786-b035-ece765fac6f1].

Role in hardware security properties

Boot code execution is central to several hardware security properties:

  • Deterministic start: A circuit satisfies this property if its internal state, including microarchitectural state, is fully cleared to deterministic values by boot code that runs on reset [chunk: e01eb2bc-af07-4f83-a991-8c44179dcede].
  • Output determinism: A circuit satisfies this property if its outputs do not depend on data present in the circuit state prior to reset. Unlike deterministic start, output determinism does not require that all circuit state is reset to deterministic values — it allows state to depend on input data. This makes checking the property more complex, since it involves tracking a set of "allowed dependencies" (i.e. all inputs received over the course of execution) and verifying that the circuit's state post-boot code execution only relies on these allowed dependencies [chunk: 100a4c6b-a946-4379-a410-c1a6a76b0c78].

Some systems, such as MicroTitan, cannot satisfy output determinism or SEQX without boot code execution [chunk: 91532559-482e-4d7c-96dd-390c79237ffc].

Verification challenges

Verifying properties about boot code execution requires modeling the complete execution of the boot code from an initially unconstrained (symbolic) circuit state and performing a solver query on the final state. This poses difficulties for traditional hardware verification tools:

  • Bounded model checking (BMC): Tools like SymbiYosys use BMC to unroll a bounded number of circuit steps into one large SMT query. Empirically, SMT solvers exhibit poor performance when reasoning about long chains of transition relations [chunk: da13564e-2b08-4a7e-b7f8-9409cf1c1d13]. SymbiYosys's runtime increases exponentially with the number of boot code cycles [chunk: e01eb2bc-af07-4f83-a991-8c44179dcede].
  • Two-copy encoding: A common workaround in SymbiYosys is to instantiate two copies of the CPU that are initially unrelated, and add assertions that their state must be equal after the boot code runs. However, this encoding has poor scalability [chunk: e01eb2bc-af07-4f83-a991-8c44179dcede].
  • Memory state complexity: In complex SoCs like MicroTitan, symbolic terms representing state (e.g., SPI state machine registers) can grow rapidly each cycle during boot code execution if left unchecked, because the new state on each cycle depends on the previous state [chunk: 100a4c6b-a946-4379-a410-c1a6a76b0c78].

rtlv's approach to verifying boot code execution

The rtlv verification approach is specifically designed to handle many cycles of boot code execution efficiently. Its key techniques include:

  • Hybrid symbolic execution: rtlv compiles Verilog circuits into a Rosette model and uses Rosette's hybrid symbolic execution, which performs type-driven state merging to merge values at control-flow joins, avoiding path explosion [chunk: da13564e-2b08-4a7e-b7f8-9409cf1c1d13].
  • Rewrite rules: Rosette's rewrite rules act as heuristics to simplify symbolic expressions on the fly before they reach the solver, resulting in smaller SMT queries [chunk: 8f0d2e8d-6757-4786-b035-ece765fac6f1].
  • Imperative step function: Instead of using a transition relation directly in the SMT encoding, rtlv transforms the transition relation into an imperative step function that allows for symbolic execution, which scales linearly with the number of cycles [chunk: da13564e-2b08-4a7e-b7f8-9409cf1c1d13].
  • Performance hints: For complex SoCs, rtlv/shiva provides a performance hint interface (e.g., abstract, overapproximate, abstract-or-overapproximate-vector) that allows developers to suggest state transformations to reduce the size of symbolic expressions while maintaining soundness [chunk: 100a4c6b-a946-4379-a410-c1a6a76b0c78, 8f0d2e8d-6757-4786-b035-ece765fac6f1].

Case study results

Circuit Flip-flops Boot code cycles rtlv runtime SymbiYosys result
PicoRV32 ~1,300 104 1.3 seconds Times out (>12 hours)
MicroTitan ~4,300 24,516 Feasible with performance hints Not attempted / not feasible

Table: rtlv can verify boot code execution for a small RISC-V SoC in 1.3 seconds, while SymbiYosys is unable to finish within 12 hours for the same 104 cycles [chunk: e01eb2bc-af07-4f83-a991-8c44179dcede, ab47b904-296b-461d-8987-9bce0df2787b]. For the more complex MicroTitan, rtlv scales to over 20,000 cycles of boot code execution, and the verification effort helped find and fix violations of the state-clearing property in the baseline hardware [chunk: ab47b904-296b-461d-8987-9bce0df2787b].

Limitations

The rtlv approach to verifying boot code execution has several limitations:

  • Simple embedded applications only: rtlv is currently expected to verify properties that require executing several hundred lines of C on microcontroller-level hardware, and is not designed for larger applications [chunk: 91532559-482e-4d7c-96dd-390c79237ffc].
  • End-to-end proof gap: rtlv does not bridge results proven with Rosette to verification tools like Coq for end-to-end proofs requiring metatheory. The case study proves properties about individual clock domains in MicroTitan, but there is no machine-checked proof that these imply a top-level output determinism property [chunk: 91532559-482e-4d7c-96dd-390c79237ffc].
  • Boot code must have known control flow: The approach works best when the boot code is known and its control flow is not dependent on unconstrained values, so that the program counter is concrete on each cycle. The final circuit state should also contain mostly or solely concrete terms, because this means the verification runtime is dominated by symbolic execution time rather than the final solver query [chunk: da13564e-2b08-4a7e-b7f8-9409cf1c1d13].

Related verification approaches

Several prior works have addressed end-to-end verification of systems, including:

  • The CLI Stack (beginning in 1989) [chunk: 91532559-482e-4d7c-96dd-390c79237ffc]
  • Verisoft [chunk: 91532559-482e-4d7c-96dd-390c79237ffc]
  • The CakeML project's end-to-end verified system [chunk: 91532559-482e-4d7c-96dd-390c79237ffc]

These works prove deep end-to-end correctness theorems about software running on hardware, but rely on heavyweight techniques using interactive theorem provers. The rtlv framework shares a limitation with prior systems like AVR and Averroes: neither supports the modeling of code execution [chunk: 91532559-482e-4d7c-96dd-390c79237ffc].

CITATIONS

15 sources
15 citations
[1] Boot code takes 104 cycles for the PicoRV32 CPU to clear uninitialized state. rtlv: push-button verification of software on hardware
[2] Boot code takes 24,516 cycles for MicroTitan to clear uninitialized state, compared to 104 for PicoRV32. rtlv: push-button verification of software on hardware
[3] Deterministic start requires that a circuit's internal state, including microarchitectural state, is fully cleared to deterministic values by boot code that runs on reset. rtlv: push-button verification of software on hardware
[4] Output determinism allows state to depend on input data, and verification requires tracking a set of 'allowed dependencies' to verify that the circuit's state post-boot code execution only relies on these allowed dependencies. rtlv: push-button verification of software on hardware
[5] Some systems such as MicroTitan cannot satisfy output determinism or SEQX without boot code. rtlv: push-button verification of software on hardware
[6] rtlv can model 104 cycles of PicoRV32 boot code execution and verify the deterministic start property in 1.3 seconds. rtlv: push-button verification of software on hardware
[7] SymbiYosys is unable to finish within 12 hours when verifying 104 cycles of boot code execution for PicoRV32, scaling exponentially with the number of cycles. rtlv: push-button verification of software on hardware
[8] rtlv scales linearly with the number of boot code execution cycles by using symbolic execution and an imperative step function instead of a transition relation in the SMT encoding. rtlv: push-button verification of software on hardware
[9] Rosette's hybrid symbolic execution performs type-driven state merging to avoid path explosion, and its rewrite rules simplify symbolic expressions on the fly. rtlv: push-button verification of software on hardware
[10] rtlv/shiva provides performance hints (abstract, overapproximate, abstract-or-overapproximate-vector) for transforming circuit state during boot code execution verification without affecting proof soundness. rtlv: push-button verification of software on hardware
[11] MicroTitan is a RISC-V SoC based on a subset of the OpenTitan project containing an Ibex CPU, 8KB ROM, 8KB RAM, UART, SPI, and USB peripherals. rtlv: push-button verification of software on hardware
[12] rtlv is expected to verify properties requiring executing several hundred lines of C on microcontroller-level hardware, but is not designed for larger applications. rtlv: push-button verification of software on hardware
[13] Prior frameworks AVR and Averroes do not support the modeling of code execution, similar to limitations discussed for rtlv in certain contexts. rtlv: push-button verification of software on hardware
[14] End-to-end software/hardware verification has a long history beginning with the CLI Stack in 1989, and includes Verisoft and the CakeML project's end-to-end verified system, which prove deep end-to-end correctness theorems using heavyweight interactive theorem provers. rtlv: push-button verification of software on hardware
[15] rtlv does not have a machine-checked, end-to-end proof that the individually verified properties of MicroTitan's clock domains imply a top-level output determinism property. rtlv: push-button verification of software on hardware