2. Virtual validation landscape
Physical test coverage planning rarely starts from a blank sheet. By the time a coverage plan is drafted, the system under test already exists in several representations: a control model in a simulation tool, generated production code, a compiled binary on a target ECU, or a bench with real actuators and sensors. Each representation defines a different execution context, and the choice of context determines what can be stimulated, what can be observed, and therefore which coverage items are even measurable. This chapter maps the virtual validation landscape — MiL, SiL, PiL, and HiL — and shows how each context constrains and enables coverage planning.
Four contexts, one system under test
The standard taxonomy is defined by what executes the control logic and what surrounds it. In Model-in-the-Loop (MiL), the controller is an executable model (for example, a Simulink model) and the plant is a model; both run on a host PC. In Software-in-the-Loop (SiL), the controller is production C code compiled for the host, while the plant remains simulated. Processor-in-the-Loop (PiL) moves the controller code onto the target processor (or an instruction-set simulator) while the plant stays simulated. Hardware-in-the-Loop (HiL) places the real ECU — with its I/O drivers, operating system, and communication stacks — against a real-time simulated plant with emulated electrical interfaces.
The critical insight for coverage planning is that these are not four interchangeable ways to "run the same tests." They differ in three dimensions that directly affect coverage: stimulus fidelity (what signals can be injected and at what rate), observability (which internal states and branches can be instrumented), and timing determinism (whether execution is simulated time, host time, or real time). A coverage goal that is trivially achievable in MiL may be unmeasurable in HiL, and vice versa.
What each context lets you measure
In MiL, the model is fully instrumented. Coverage tools can report statement, branch, and condition coverage on the model itself, plus state and transition coverage for Stateflow or similar state machines. Because time is simulated, you can run thousands of scenarios in minutes and inject any signal without electrical constraints. This makes MiL the natural home for algorithmic coverage: have all operating modes been entered? Have all transition guards been evaluated both true and false? Have all saturation and anti-windup branches been exercised?
SiL shifts the target to production code. Coverage is now measured on the compiled C (or C++) implementation, typically with gcov/llvm-cov or a commercial tool. This is where you discover that the model and the code are not the same object: compiler optimizations may merge branches, hand-written integration code adds paths the model never had, and fixed-point quantization introduces new decision outcomes. A branch that was reachable in MiL may become unreachable in SiL, or a new defensive branch may appear that no functional stimulus can reach. Coverage planning must therefore treat SiL as the authoritative context for code-level structural coverage.
PiL keeps code coverage but moves execution to the target processor. On-chip trace (ETM, NEXUS, or similar) or instrumented builds provide the measurement. The value here is timing: you can observe whether worst-case execution paths are actually taken, and whether interrupt-driven branches behave as designed. The constraint is trace bandwidth and buffer depth — long scenarios may overflow the trace and silently lose coverage data, so runs must be segmented.
HiL is where internal code coverage usually becomes inaccessible. The ECU runs unmodified production software, often without instrumentation, and the test system sees only the electrical interface. Coverage planning in HiL therefore shifts to interface and scenario coverage: every sensor range, every bus message and signal value, every fault-injection state, every operating-mode transition observable at the I/O boundary. This is not a lesser form of coverage — it is the coverage that matters for integration and safety validation, and it must be planned with the same rigor.
Planning coverage across the V-model
The practical consequence is a layered coverage strategy rather than a single number. A defensible plan assigns each coverage objective to the context where it is both measurable and meaningful:
| Coverage objective | Primary context | Why |
|---|---|---|
| State / transition coverage of control logic | MiL | Full model instrumentation, fast simulated time |
| Statement, branch, MC/DC on production code | SiL | Code is the object under test; host coverage tools |
| Timing-path and interrupt branch coverage | PiL | Target clock and on-chip trace |
| I/O range, bus signal, fault-injection coverage | HiL | Only the electrical boundary is observable |
| End-to-end scenario coverage | HiL | Real-time closed loop with real interfaces |
Two failure modes recur when this layering is ignored. The first is context mismatch: a team reports 95% branch coverage from MiL and treats the code-level requirement as satisfied, when the production code has never been measured. The second is unreachable-target chasing: a team tries to hit 100% MC/DC in HiL, where internal branches are invisible, and burns bench time on an objective the context cannot support. Both are planning errors, not testing errors.
A worked planning example
Consider a battery-management slave ECU with a state machine (Init → Standby → Charging → Balancing → Fault) and a CAN interface. A coverage plan might specify:
- MiL: all 5 states entered, all 11 transitions taken, all guard conditions evaluated true and false — target 100% state/transition coverage, achieved with a scenario sweep over voltage, temperature, and current setpoints.
- SiL: 100% statement and branch, ≥90% MC/DC on the balancing and fault-detection modules, measured with gcov; any unreachable branch documented with a justification (defensive code, hardware interlock).
- PiL: verify that the fault-detection ISR path is exercised under target timing; confirm no trace overflow by segmenting the run into 30-second windows.
- HiL: every CAN signal exercised across its valid range plus out-of-range and timeout faults; every state transition observed at the bus; fault-injection coverage for open-load, short-to-ground, and over-temperature.
Each row has a concrete measurement method, a target, and a context in which that target is achievable. That is what a coverage plan looks like when it is grounded in the virtual validation landscape rather than in a single tool's report.
The next planning decision — how to translate these context-specific objectives into concrete test cases and stimulus — depends on understanding what each context can inject and observe at its boundary, which is the subject of the following chapter.