Motivation¶
Why ml-hpi Exists¶
Modern SoC verification demands that the same test intent execute across a chain of increasingly complex environments: block-level RTL simulation, subsystem integration, full-chip simulation, emulation, and silicon bring-up. Today, teams handle this by duplicating effort — rewriting the same test logic in each environment, maintaining diverging copies, and rebuilding interface glue every time a new language or methodology enters the flow.
The root cause is the absence of a shared interface contract. A UVM sequence
that drives a DMA engine at block level typically reaches into the UVM
component hierarchy directly — env.dma_agent.reg_driver,
env.dma_agent.irq_monitor — so it cannot compile in any other environment.
The typical response is copy-paste: clone the sequence, patch every
environment reference, and maintain a second fork forever.
The fix is well-known in software engineering: program to an interface, not
an implementation. If the sequence interacts with the environment through a
DmaIf handle — an object that exposes do_transfer as a method — then
any environment capable of providing a DmaIf implementation can run the
sequence unchanged. Block-level, subsystem, SoC, virtual platform, and
emulation environments each supply a different implementation of the same
interface; the test logic is never touched.
The Multi-Language Challenge¶
The interface abstraction described above already delivers portability across
abstraction levels in a single-language environment: any SystemVerilog testbench
that provides a DmaIf implementation can run the same sequence unchanged.
The additional challenge appears when verification spans multiple languages.
Defining DmaIf in SystemVerilog does not make it available in C++, Python,
or PSS. Without a language-neutral specification, each new language context
requires a hand-written interface definition and a hand-written binding layer —
and the two must be kept in sync forever.
ml-hpi automates this integration infrastructure with a semantic model: a
language-neutral description of interfaces, methods, types, hierarchy, and
per-method attributes. The model can be recorded in YAML/JSON, but it can
equally be expressed in a host language. A SystemVerilog interface class
hierarchy is a complete, valid representation of the same model; an ml-hpi
extraction tool derives the YAML/JSON form automatically. From that derived
representation the toolchain generates idiomatic bindings for all target
languages in one step — the user maintains one source artifact and gets
everything else for free.
The consistent interface contracts that result also provide a stable semantic
anchor for AI-assisted cross-language translation: when DmaIf carries
identical semantics in every language, translating test logic between them
becomes a syntax mapping rather than a semantic inference problem — an indirect
benefit that falls outside ml-hpi’s direct scope but follows naturally from the
consistency it enforces.
Verification-Specific Requirements¶
Two requirements specific to verification environments go beyond what a generic IDL can provide:
Hierarchical context.
Real designs contain many instances of the same IP block — four DMA channels,
eight PCIe ports. ml-hpi models interfaces as class hierarchies with named
field members (a single sub-interface) and array members (an indexed
collection). A test navigates naturally: chip.uarts_at(1).send(ch).
Each instance is a typed object; no handle bookkeeping is required. The
generated binding layer handles the mechanics of crossing flat DPI/FFI
boundaries while preserving the object model transparently.
Blocking vs. non-blocking calls.
Whether a method must consume simulated time before returning is a property of
the operation, not the language. ml-hpi captures a blocking attribute
per method. Generators emit the correct construct for each language: a
pure virtual task in SystemVerilog, an async def coroutine in Python,
a callback-based completion import in C. In PSS, the same attribute drives the
target-time / solve-time distinction. The interface author states what each
method does; the generator handles how each language expresses it.
Extending to PSS¶
The same interface spec that enables UVM sequence reuse across integration
levels also serves as the bridge to PSS (Accellera Portable Test and Stimulus
Standard). PSS actions call platform functionality through function import
declarations that must be kept in sync with DPI stubs and platform dispatch
logic — hand work spread across three languages. Because ml-hpi already
captures all attributes PSS needs (blocking, target, solve), the
toolchain generates the complete PSS component and function import
declarations in the same step that produces C++ and Python bindings.
The practical workflow is:
SV interface class --> (ml-hpi derives IDL) --> PSS component + function imports
+--> C++ / Python / C bindings
The IDL is a hidden intermediary — the SV interface class remains the
single maintained artifact, and the PSS infrastructure is never hand-written.