DCRouter's hardware is fully verified at block level. Its driver is written by a software team from the register specification. The driver clears error counters by writing ERR_CNT0 through ERR_CNT3 in a loop after reading them, enables low power during initialisation, and treats any counter value of 255 as "counter broken". Each of those choices interacts with a hardware rule (writes clear only one counter, sleep after 8 idle cycles, saturation at 255). If any reading of the specification differs between the two teams, both sides pass their own tests and the product fails.
How do you verify a driver and its hardware together before silicon exists?
The obvious plan is to wait for silicon, or at least for an FPGA prototype, and bring the driver up there. Bugs found then are expensive: a hardware bug needs a workaround or a respin, a contract misunderstanding needs both teams. Earlier options exist, each running the real driver against a different model of the hardware, and they trade speed against accuracy.
Platform | Speed | Accuracy | Good for |
|---|---|---|---|
Virtual platform (transaction-level models) | Close to real time | Registers and functions, not timing | Driver development before RTL; register sequences; error paths |
RTL simulation | Very slow | Cycle-exact | Short driver sequences against the real RTL: initialisation, interrupt handling |
Emulation, FPGA prototype | Fast | Cycle-exact RTL | Full driver and OS bring-up, long scenarios (Part 10) |
Hybrid (virtual processor plus RTL block) | Fast where it can be | Exact for the block under test | A real driver against one RTL block early |
Driver behaviour | Hardware rule it depends on | Risk if the readings differ |
|---|---|---|
Clears each ERR_CNT by writing it | R9: a write clears only that counter | A loop that writes only ERR_CNT0 expecting all four cleared |
Enables low power at initialisation | R13: sleep after 8 idle cycles; any valid wakes it | Driver waits for a status the router cannot show while asleep |
Treats 255 as a broken counter | R9: saturates at 255 by design | Error storms reported as hardware faults |
Reads PKT_CNT for statistics | R10: wraps at 65,535 | Statistics jump backwards |
Handles the unmapped-address error | R12: pslverr on unmapped addresses | Bus fault handler never exercised |
Each row is a contract between two teams. Co-verification runs the driver's real code against the real register behaviour, so the contract is tested rather than assumed.
One register specification, generated for both sides: RTL, verification model and driver headers from the same source (lesson 2.4).
Driver tests in the verification plan: initialisation, error recovery, low power, as chip-level scenarios.
Hardware checkers stay on under the driver: the driver may do things no testbench did (lesson 8.3).
Software engineers review the hardware specification early: their questions are specification review (lesson 2.5).
Practice | Purpose |
|---|---|
Virtual platforms available before RTL | Driver development and register-sequence checks months earlier |
Driver boot on emulation before tape-out | The full software stack exercised on the real RTL |
Shared bug tracking between hardware and software | Contract misunderstandings resolved once, in the specification |
A team (illustrative) shipped a network controller whose driver enabled interrupts before clearing a sticky status bit the hardware set at reset. In every hardware test, the status had been cleared first by the testbench's own initialisation; in every driver test on the virtual platform, the model did not set the bit at reset. The first boot on silicon raised a spurious interrupt and the driver locked up. Running the driver's initialisation once against the RTL would have shown it.
If the driver team read "a write clears the counters" as clearing all four, its tests against its own model pass; the hardware clears only the one written, as its tests check.
Fast, early driver development and register-sequence and error-path checks; it misses cycle timing and any behaviour its model does not implement.
Many failures live in the contract between drivers or firmware and the hardware.
Run the real software against virtual platforms, RTL simulation and emulation, trading speed for accuracy.
Generate the register interface for both sides from one source and put driver sequences in the plan.