WIOWIZ Verification · Article 06

What Vajra-LP checks that simulation cannot see

Low-Power Verification

What Vajra-LP checks that simulation cannot see

A block that is powered off does not misbehave. It goes dark, and its outputs drift to an undefined level that the neighbours downstream will happily latch. Simulation with everything powered rarely shows it. The structure that prevents it lives in the power intent, and that is a document you check statically, before a single cycle runs.

The static half of low-power verification, read from UPF.

WIOWIZ Verification Series · Article 06 of 6

Low-power design splits a chip into regions that can be switched off independently to save energy. That single idea creates a family of failure modes that ordinary functional simulation is poorly placed to catch, because the bugs live at the boundary between a region that is off and a region that is on, and a default simulation keeps everything on. The intent for all of this is written in a UPF file, and Vajra-LP reads that intent and checks it as a structure.

Five things the power intent must get right

A UPF description names the parts of the low-power contract, and each one is a place a design can be wrong:

Vajra-LP is a static check of these five. It does not run the design, it reads the intent and asks whether the structure is complete and consistent. That is the half of low-power verification that happens before dynamic power-aware simulation, and it catches the class of bug that simulation with everything powered will simply never present.

Scope discipline. Vajra-LP is static, not dynamic. It verifies that the power intent is structurally sound. It is the complement to power-aware simulation, not a substitute for it: one checks that the intent is well-formed, the other checks that the design behaves under it.

A production SoC intent, read in one pass

Point it at the UPF for a production SoC top and it inventories the intent before it judges anything:

$ vajra-lp check wzax1_top.upf
  power domains : 36
  declared strategies: iso=29  ls=16  ret=19  switch=23
  power states  : 104
  switchable    : 27 / 36 domains
  supply nets   : 31 declared, 12 switched rails, 17 roots

  ⚠ 130 input construct(s) NOT modelled: their intent is not checked
      (a finding-free report does NOT cover the above)

Thirty-six domains, twenty-seven of them able to power off, a hundred and four legal power states. That is the surface a human cannot hold in their head, which is the reason a static tool exists: to hold the whole contract at once and find the corner of it that is inconsistent. The line that matters most is the warning: 130 input constructs fell outside what this build models, so their intent is not checked, and the tool says so up front rather than letting a short finding list read as a clean bill.

The finding: a domain that goes dark with nothing to clamp it

Here is the report the tool renders for this design.

Vajra-LP report showing five PL-ISO-01 isolation errors and the domain inventory

Vajra-LP report for wzax1_top. Five PL-ISO-01 errors, each a switchable domain whose outputs cross into an on domain with no isolation strategy.

Five domains failed the same check:

findings: 5  (5 error, 0 warning, 0 info)  | memory: 18 prior, 5 recurring
  PL-ISO-01  x5   Off-to-on crossing without isolation
    [ERROR/recurring] PL-ISO-01: domain 'PD_HSM' can power OFF but has no
        output isolation strategy (off-to-on crossing unprotected)
    [ERROR/recurring] PL-ISO-01: domain 'PD_MEM_BANK0' ...
    [ERROR/recurring] PL-ISO-01: domain 'PD_MEM_BANK1' ...
    [ERROR/recurring] PL-ISO-01: domain 'PD_MEM_BANK2' ...
    [ERROR/recurring] PL-ISO-01: domain 'PD_MEM_BANK3' ...

The rule PL-ISO-01 is the isolation gap in one line: a domain that can power off, feeding a domain that stays on, with no isolation clamp between them. When the source domain goes dark its outputs are undefined, and the live domain downstream latches that undefined level as if it were data. It is precisely the bug a fully-powered simulation cannot show you, because in that simulation the source domain is never off.

PD_MEM_BANK0 powered OFF -> output X on domain latches whatever arrives no ISO

PL-ISO-01: the missing clamp on the off-to-on crossing. With isolation, the live domain sees a defined value while the source is dark.

The verdict is a diagnosis, not just a count

What lifts this above a linter is that the tool does not stop at five errors. A second command resolves them to a single dominant cause and proposes what to do:

$ vajra-lp close wzax1_top.upf
  declared strategies: iso=29 ls=16 ret=19 switch=23
  run          : 5 errors, 0 warnings (score 500)
  closure state: UNVERIFIED
  verdict      : KEEP
  input coverage: UNVERIFIED (130 constructs not modelled)
  dominant RC  : LC1_MISSING_ISO_CTRL (5)
  action plan (ranked by learned effectiveness):
    - WAIVE_IF_REDUNDANT   waive if crossing is provably safe
    - ADD_ISO_CONTROL      add set_isolation_control signal for the domain

Read the closure block carefully, because the state is the whole point. It is UNVERIFIED, not FAIL and not PASS and not a clean close. The tool found 5 isolation errors, but it also could not model 130 of the design's UPF constructs, so it refuses to claim the design is verified either way: the errors it did find stand, and the part it could not check stays explicitly unverified. The five findings collapse to one root cause, LC1_MISSING_ISO_CTRL, so you fix a category rather than five lines, and the verdict is KEEP: these are worth keeping rather than waiving.

The machine-readable report from check -out-dir adds one more number the terminal does not print: coverage 129 / 144 (90%). That is not simulation coverage and not a toggle percentage. It is static structural completeness, four checklist items across the 36 domains, measuring how much of the intent the tool could evaluate. Paired with the 130 unmodelled constructs, it is the tool stating the boundary of its own check rather than letting a short finding list read as a clean bill.

The model it hands to formal

The static check is also the front of a longer pipeline. The power intent Vajra-LP validates becomes a model that a formal engine can reason about, so a question like is this isolation ever needed given the legal power states can be answered by proof rather than inspection. The static tool establishes that the intent is well-formed; the formal low-power app then reasons about whether the intent is sufficient. The first has to hold before the second means anything, which is why the structural check comes first and refuses to sign off while errors are open.

The most expensive low-power bugs are invisible to a simulation that keeps everything on. They live in the intent, in a domain that can go dark with nothing to clamp its outputs. Reading that intent as a structure, before a cycle runs, is how you find them while they are still cheap to fix.