Skip to content

AMBA AXI · Module 16

Negative & Error-Injection Testing

Deliberately drive error and illegal scenarios to verify an AXI DUT's error handling — provoking SLVERR/DECERR with bad addresses and read-only writes, injecting errors from an error-capable slave model, and (carefully) probing illegal traffic — then checking the DUT responds and recovers correctly rather than hanging or corrupting state.

Constrained-random testing (16.6) deliberately stays inside the legal space. Negative and error-injection testing does the opposite: it intentionally drives the error scenarios — accesses that should return SLVERR/DECERR, slaves that fault, and (carefully) malformed traffic — to verify the DUT handles them correctly rather than hanging, corrupting state, or silently swallowing the fault. Error paths are the least-exercised and most-fragile part of any design (normal stimulus almost never triggers them), so they need deliberate provocation. This chapter shows how to provoke error responses, inject faults from an error-capable slave model, probe illegal traffic safely, and — crucially — check the recovery: that the DUT returns the right error code, stays consistent, and continues serving subsequent legal traffic.

1. Why Negative Testing Is Separate and Essential

Positive testing (random or directed) confirms the DUT does the right thing on good input. Negative testing confirms it does the right thing on bad input — a distinct, equally important question that positive testing structurally cannot answer, because legal traffic rarely produces errors. The error-handling logic (decode-error paths, SLVERR generation, recovery) is real RTL that must be exercised, and it's where bugs hide precisely because it's rarely hit.

Positive testing exercises main datapath on good input; negative testing exercises error paths on bad input; both required.Positive testinggood input → main pathNegative testingbad input → error pathError paths rarely hitby normal trafficBoth requiredor errors go untested12
Figure 1 — positive vs. negative testing as complementary halves. Positive testing (legal traffic) verifies correct behavior on good input and exercises the main datapath. Negative/error testing (error-provoking and illegal scenarios) verifies correct behavior on bad input and exercises the error-handling paths. Both are needed: a DUT can pass all positive tests and still hang or corrupt on the first error, because positive traffic never reaches the error logic.

2. Provoking Error Responses

The first class of negative test provokes the error responses the protocol defines — these are legal transactions that the slave is supposed to error on. Drive them deliberately and confirm the correct code comes back:

  • DECERR — access an unmapped address (no slave at that decode). The interconnect's default slave should return DECERR.
  • SLVERR — write to a read-only register, access a reserved offset, or hit a slave-defined error condition. The slave should return SLVERR and not change state.
  • EXOKAY / exclusive failures — attempt an exclusive access that fails its monitor; confirm OKAY (not EXOKAY) is returned to signal failure.
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Directed negative sequence: provoke each error response
task provoke_errors();
  axi_txn t = axi_txn::type_id::create("t");
 
  // DECERR: write to an address with no slave mapped
  start_item(t); assert(t.randomize() with { addr == UNMAPPED_ADDR; });
  finish_item(t);                       // expect BRESP == DECERR
 
  // SLVERR: write to a read-only register
  start_item(t); assert(t.randomize() with { addr == RO_REG_ADDR; });
  finish_item(t);                       // expect BRESP == SLVERR, reg unchanged
 
  // Reserved offset read
  start_item(t); assert(t.randomize() with { addr == RESERVED_ADDR; });
  finish_item(t);                       // expect RRESP == SLVERR
endtask

The scoreboard's reference model (16.4) must predict these error responses — it knows the address map, so it expects DECERR for unmapped and SLVERR for read-only — and verify the DUT both returns the right code and leaves state unchanged (a read-only write must not modify the register).

3. Error Injection from a Faulting Slave Model

The second class injects faults that don't originate from the manager's request but from the slave side — an error-capable slave model (or VIP) configured to return errors on demand, drop responses, stall indefinitely, or corrupt data, so you can verify how the manager and interconnect react. This tests the error-propagation and recovery paths the slave's own legal behavior wouldn't trigger.

Configurable error-injection slave returns errors, drops/delays responses, or corrupts data to drive manager/interconnect error handling.Manager (DUT)error handling testedError-inject slaveconfigurable faultsInject SLVERR/DECERRon selected txnsDrop / delay resptest timeoutCorrupt datatest detectionVerify recoverypropagate + continue12
Figure 2 — error injection from a configurable slave model. A normal slave returns OKAY; an error-injection slave model is configured to return SLVERR/DECERR, delay or drop responses, or corrupt data on selected transactions. This drives the manager's and interconnect's error-handling and recovery logic — how they propagate an error response, time out a missing one, or flag corruption — which the slave's normal behavior never exercises.

The injected error then propagates, and the test verifies the response and the subsequent recovery on the bus:

Injected SLVERR then recovery

10 cycles
Write returns OKAY; next write to error region returns SLVERR; following write returns OKAY, showing recovery.good → OKAYerror region → SLVERRrecover → OKAYSLVERR injectedSLVERR injectedrecoveredrecoveredACLKAWVALIDAWREADYBVALIDBRESP..OK OK ERBREADYt0t1t2t3t4t5t6t7t8t9
Figure 3 — an injected SLVERR and recovery on the write channel. A normal write to a good address returns BRESP=OKAY. The next write targets an error region; the error-injection slave returns BRESP=SLVERR. The test confirms the manager receives and reports the error, then issues a following legal write that completes normally (OKAY) — proving the DUT propagated the error without hanging and recovered to serve subsequent traffic.

4. Probing Illegal Traffic — Carefully

The third, most delicate class drives protocol-illegal traffic to test a checker, an interconnect's robustness, or a slave's defensive behavior. This is the deliberate inverse of 16.6's legality constraints: temporarily relax a constraint to emit, say, a 4 KB-crossing burst or a reserved encoding. It must be done carefully and in isolation, because the result is often undefined by the spec — the goal is usually to confirm a protocol checker fires (an illegal_bins hit or assertion) or that the DUT degrades gracefully, not to assert a particular functional outcome.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Illegal-traffic sequence: relax a legality constraint deliberately.
// Used to confirm a CHECKER fires, not to assert functional behavior.
class axi_illegal_seq extends axi_rand_seq;
  task body();
    axi_txn t = axi_txn::type_id::create("t");
    start_item(t);
    // Disable the 4 KB constraint for this item, force a crossing burst
    t.c_no_4k_cross.constraint_mode(0);
    assert(t.randomize() with { burst == 1;           // INCR
                                (addr % 4096) > 4000;  // near page end
                                len > 8; });           // span crosses 4 KB
    finish_item(t);   // EXPECT: protocol checker/assertion fires
  endtask
endclass

The key discipline: illegal-traffic tests verify the checker, not the DUT's functional response — since the spec doesn't define behavior for illegal input, asserting a specific functional result would be wrong. Keep them isolated so they can't pollute the legal-traffic scoreboard.

Relax one constraint in an isolated sequence, emit malformed transaction, expect a checker to fire, keep out of functional scoreboard.yesnoRelax onelegalityconstraintEmit malformed txn(isolated seq)Checkerfires?Pass — checkercaught itChecker gap —fix assertion
Figure 4 — the illegal-traffic testing discipline. Relax one legality constraint to emit a specific malformed transaction, in an isolated sequence. The success criterion is that a protocol checker (assertion or illegal_bins) fires — not a particular functional outcome, since the spec doesn't define one. Isolation keeps the illegal traffic out of the functional scoreboard and coverage. The finding is about the checker's completeness, not the DUT's data behavior.

5. Common Misconceptions

6. Debugging Insight

7. Verification Insight

8. Interview Questions

9. Summary

Negative and error-injection testing deliberately exercises what positive testing structurally cannot: the DUT's behavior on bad input. It has three classes. Provoking error responses drives the protocol's defined errors — DECERR (unmapped addresses), SLVERR (read-only writes, reserved offsets, slave faults), exclusive-access failures — with the scoreboard's reference model predicting each and confirming both the right code and no wrongful state change. Slave-side error injection uses a configurable faulting slave model to return errors, drop/delay responses, or corrupt data, exercising the manager's and interconnect's error-propagation, timeout, and recovery logic. Illegal-traffic probing (relaxing a legality constraint) drives undefined scenarios in isolated sequences solely to confirm a checker fires — never to assert a functional outcome the spec doesn't define.

The decisive discipline is to check recovery, not just the response: the right error code is necessary but insufficient — the DUT must also suppress error side effects (a read-only write changes nothing), free resources (outstanding counters/FIFOs cleared), and keep serving subsequent legal traffic without hanging. The highest-severity, easiest-to-miss failures are hang-after-error (broken recovery/liveness) and state-change-despite-error (side effect not suppressed) — both pass a naive error-code check. Recovery is verified rigorously by following every error with legal traffic, checking resource accounting, using timeout watchdogs, and stressing errors under concurrency. With negative testing alongside assertions, monitors, scoreboards, coverage, and constrained-random, verification establishes not just "works when right" but "fails safely when wrong." Next, we package the whole environment into the reusable UVM AXI agent.

10. What Comes Next

You've completed the stimulus/checking toolkit; next we package it for reuse:

  • 16.8 — UVM AXI Agent Overview (coming next) — assembling the driver, sequencer, and monitor into a reusable UVM agent, the standard packaging that bundles an interface's verification into one drop-in unit.

Previous: 16.6 — Constrained-Random AXI Traffic. Related: 6.8 — RRESP, BRESP & RLAST for the response codes provoked here, 12.3 — Decode & Address Map for the unmapped-address DECERR path, and 16.4 — AXI Scoreboards for the reference model that predicts errors.