What is SoC verification, and how is it different from block-level verification?

Block-level verification checks one IP in isolation, with a testbench that drives its interfaces directly and checks it against its specification in depth. SoC verification assumes the blocks are already verified and focuses on how they work together: the interconnect and address map, connectivity between blocks, interrupts, clocks and resets, power modes, shared memory and the interaction with software running on the processors.

Because the full chip is large and slow to simulate, SoC tests are more scenario-based and less exhaustive. Bugs found at SoC level are usually integration bugs, such as wrong connections, wrong address decoding or wrong reset sequencing, rather than bugs inside a block.

Read more on Introduction to SoC Verification.

How is an SoC-level testbench usually structured?

  • The DUT is the full chip or a subsystem, often with the real processor model running test software.
  • External interfaces are driven by verification IPs (UVCs) and memory models, for example DDR, PCIe, USB and serial ports.
  • Block-level monitors and scoreboards are reused in passive mode on internal interfaces.
  • A register model mirrors the SoC address map, and a top-level environment and virtual sequencer coordinate everything.
  • A test layer combines C code running on the processor with SystemVerilog sequences driving the external VIPs.

Read more on SoC Testbench Structure.

Why are C tests used in SoC verification?

In a real chip the processor configures and controls the other blocks through software. Running C tests on the processor model inside the simulation exercises the real paths: instruction fetch through the interconnect, register accesses with real bus timing, interrupt handling and software sequences similar to the drivers that will run on silicon.

C tests can also be reused later on emulation, FPGA prototypes and silicon, which a UVM sequence cannot. Their weaknesses are less randomization and harder debug, so most SoC environments combine C tests with SystemVerilog stimulus.

Read more on Directed vs Self-Checking C Tests.

How do you get a C test running on the processor inside the DUT?

  1. Cross-compile the C code with the processor's toolchain, together with startup code that sets up the stack and jumps to main.
  2. Link it with a linker script that places code and data at the addresses of the SoC's boot memory and RAM.
  3. Convert the resulting ELF file into a memory image (for example a hex file).
  4. Load the image into the memory model at time zero, usually with $readmemh or a backdoor write.
  5. Release reset, so the processor fetches from its reset vector and runs the test.

Read more on Getting a C Test Running in the DUT and Linker Scripts and Memory Maps.

How do C tests and SystemVerilog sequences coordinate?

They communicate through shared memory or dedicated registers that both sides can access. The C test writes a value to a mailbox address, for example "configuration done" or a test ID, and the testbench watches that address with a monitor or backdoor peek and starts the matching sequence on an external VIP. The testbench can answer the same way, by writing a flag that the C code polls.


// Testbench side: wait for the C code to signal it is ready
wait (mem.read_word(MAILBOX_ADDR) == 32'h0000_0001);
uart_seq.start(env.uart_agent.sequencer);

The same mechanism reports the final pass or fail status, so the simulation ends with a clear result.

Read more on Co-ordinating C Tests with SystemVerilog Sequences.

How do you reuse block-level verification components at SoC level?

Interfaces that are internal at SoC level are no longer driven by the testbench, so the block-level agents on them are switched to passive mode. Their monitors still observe the traffic, and the block-level scoreboards and assertions keep checking the block in its real surroundings.

Agents on interfaces that are still external to the chip stay active. This reuse only works if the block environments were built to be configurable, for example with active and passive settings, configurable addresses and no hard-coded hierarchy paths.

Read more on Importing VIPs in SoC Testbench and Testbench Configurability.

How is a register model used at SoC level?

The SoC register model is built by instantiating each block's register model at its base address in a top-level address map. The same register can then be accessed by name, while the model works out the full address.

Accesses can go front door through the real bus, either from a bus VIP or from the processor, or back door directly into the RTL for fast setup and checking. The model also mirrors expected values, which allows checking register state at the end of a test.

Read more on Register Model at SoC Scale.

How do you verify the address map and address decoding?

  • Access the first and last address of every region from every master that is allowed to reach it, and check the right target responds.
  • Access holes in the map and check the interconnect returns a decode error instead of hanging or aliasing.
  • Check that masters without permission to a region are blocked, for secure or protected regions.
  • Check aliasing and remapping, for example a boot ROM mapped at address zero before remap.

Most of this is generated from the address map specification, so that a change in the map automatically updates the tests.

Read more on Address Map and Decode Verification.

What is connectivity verification?

Connectivity verification checks that signals are wired correctly between blocks: interrupt lines to the interrupt controller, DMA request lines, pin multiplexing, clock and reset connections and debug signals. A wrong connection inside a correct block passes every block-level test.

It is often done with formal connectivity checks generated from a spreadsheet or specification of expected connections, which prove each connection exhaustively, combined with simulation tests for the important paths.

Read more on Connectivity Verification.

How do you verify interrupts at SoC level?

For each interrupt source, a test makes the block raise its interrupt, checks that it reaches the interrupt controller on the correct line, that the processor takes the right handler, and that clearing the source clears the interrupt. Masking, priority, edge versus level behaviour and interrupts during low-power states are checked as well.

Interrupts are a cross-block concern because they involve the source block, the wiring, the interrupt controller, the processor and the software handler, so a bug can be in any of them.

Read more on Interrupt Verification as a Cross-Block Concern.

How is cache coherency verified?

Coherency tests make several cores, and other masters such as DMA, read and write the same addresses so that cache lines move between states and between caches. Tests use small address ranges to create many conflicts, and include false sharing, where different data shares one cache line.

Checking uses a memory scoreboard that tracks the expected latest value of each address, protocol assertions on the coherent interconnect, and self-checking software patterns such as locks and producer-consumer queues. Coverage of cache line state transitions shows which scenarios were reached.

Read more on Cache Coherency Verification.

What clock and reset problems are typically found at SoC level?

  • Clock domain crossings without proper synchronizers between blocks in different domains.
  • Reset domain crossings, where one block leaves reset while a connected block is still in reset or reset at a different time.
  • Wrong reset sequencing or missing resets after a power or clock change.
  • Glitches when clocks are switched or gated at the SoC level.

Static CDC and RDC tools find most structural problems, and simulation with realistic clock ratios and reset sequences checks the behaviour.

Read more on Clock and Reset Domains in SoC.

What is power-aware verification?

Power-aware simulation reads the power intent, usually described in UPF, and models what happens when power domains are switched off and on. Signals from a powered-off domain become unknown, isolation cells must clamp them, retention registers must save and restore state, and level shifters must be present between voltage domains.

Tests run the real power-down and power-up sequences, check that isolation is enabled before power is removed and released only after it is restored, and that the system works after wake-up.

Read more on Power-Aware Verification.

What is end-to-end scoreboarding?

An end-to-end scoreboard checks data across a whole path through the SoC, for example from a packet entering on an external interface, through a DMA into memory, and out on another interface. It compares what leaves with what entered, after the expected transformation, without checking every block in between.

It catches integration bugs that block-level scoreboards cannot see, such as wrong addresses, lost or duplicated data in the interconnect, and ordering problems between blocks.

Read more on End-to-End Scoreboarding.

When would you use emulation or FPGA prototyping instead of simulation?

When tests need far more cycles than simulation can run: booting an operating system, running real software and drivers, long performance tests, or large regressions. Emulation runs the design orders of magnitude faster while keeping good debug visibility. FPGA prototypes are faster still and suit software development, but have limited visibility and need design changes to fit.

Simulation remains the main tool for detailed debug, randomized block and subsystem tests, and anything that needs full signal visibility.

Read more on Emulation and FPGA Prototyping.

Did you find what you were looking for?

Quiz

No quiz questions available for this article.