Skip to guide

Reactive stimulus

IRQ Subsystem Verification

Verify nested, prioritized, level, edge, and coalesced interrupts with reactive sequences, pulse-aware monitoring, event prediction, and hardware-software service flows.

Watercolor of a verification workstation with waveform traces and a development board.
Trace the mechanism from failure signature through independent evidence, component ownership, stress, and recovery.

Mechanism and evidence

Guided verification lab

A request is only the beginning.

Compare coalescing and timeout triggers, then follow the request through status capture, source clearing, and resumed traffic.

STEP THROUGH
STATE & OBSERVATIONEvent 10 / 1 of 6

Checkpoint 1 · Nine events are still waiting.

EVENT COUNT
9
IRQ LEVEL
0
SERVICE
wait
EXPECTED
0
Compare all 6 checkpoints
  1. 1 · Nine events are still waiting.

    EVENT COUNT
    9
    IRQ LEVEL
    0
    SERVICE
    wait
    EXPECTED
    0
  2. 2 · The tenth event sets the request.

    EVENT COUNT
    10
    IRQ LEVEL
    1
    SERVICE
    request
    EXPECTED
    1
  3. 3 · Reactive traffic waits at a legal boundary.

    EVENT COUNT
    10
    IRQ LEVEL
    1
    SERVICE
    grab
    EXPECTED
    1
  4. 4 · Read the cause before changing it.

    EVENT COUNT
    10
    IRQ LEVEL
    1
    SERVICE
    read
    EXPECTED
    1
  5. 5 · Clear the handled source.

    EVENT COUNT
    0
    IRQ LEVEL
    0
    SERVICE
    clear
    EXPECTED
    1
  6. 6 · Return access to normal traffic.

    EVENT COUNT
    0
    IRQ LEVEL
    0
    SERVICE
    ungrab
    EXPECTED
    0
123456EVENT COUNT910101000IRQ LEVELSERVICEwaitrequestgrabreadclearungrabEXPECTED
Inspect the contract

Nine events are still waiting.

Events
9 / 10
IRQ
0
Expired
No

The coalescer has recorded nine qualifying events. The example threshold is ten, and its safety timer has not expired.

Evidence to inspect

Compare the event ledger to the source status before expecting an interrupt.

Checkpoint 1 / 6
Inspect the checker Selected checkpoint pseudocode
Conceptual checker / selected checkpoint
expected_irq = (events >= 10) || expired;
assert(!expected_irq);
Example contract & limitations

Example contract. A level IRQ is latched when events ≥ 10 OR the safety timer expires at a defined sampling boundary. No new arrivals occur during this short service fixture. Source clear consumes the snapshot and restarts the timer; real register semantics must be checked. Checkpoints show selected state changes, not equally spaced simulation cycles.

Read the complete walkthrough

Event 10

  1. Nine events are still waiting.. The coalescer has recorded nine qualifying events. The example threshold is ten, and its safety timer has not expired. Evidence: Compare the event ledger to the source status before expecting an interrupt.
  2. The tenth event sets the request.. Event ten reaches the threshold at the sampled boundary. The source latches one level interrupt. Evidence: Observe a single rising IRQ and preserve all qualifying cause information.
  3. Reactive traffic waits at a legal boundary.. The service sequence gains access after any already granted driver item reaches its permitted boundary. grab() is not an abort mechanism. Evidence: Keep the in-progress handshake trace and the sequencer ownership transition.
  4. Read the cause before changing it.. Read the latched event status once. Observation must capture the cause before the service operation clears it. Evidence: Correlate the status snapshot with the event ledger.
  5. Clear the handled source.. This fixture consumes the recorded events, clears the latch, and restarts the timeout. Clearing unrelated controller state would leave the level request asserted. Evidence: Observe source deassertion and verify that no new event was erased.
  6. Return access to normal traffic.. Release the sequencer and continue useful traffic. The checker retires exactly one service obligation. Evidence: Confirm ordinary traffic resumes and the expected-IRQ count returns to zero.

Timeout first

  1. Nine events are still waiting.. The coalescer has recorded nine qualifying events. The example threshold is ten, and its safety timer has not expired. Evidence: Compare the event ledger to the source status before expecting an interrupt.
  2. The timer supplies the missing trigger.. The safety timer expires with only nine events. The OR condition still requires one interrupt. Evidence: Observe a single rising IRQ and preserve all qualifying cause information.
  3. Reactive traffic waits at a legal boundary.. The service sequence gains access after any already granted driver item reaches its permitted boundary. grab() is not an abort mechanism. Evidence: Keep the in-progress handshake trace and the sequencer ownership transition.
  4. Read the cause before changing it.. Read the latched event status once. Observation must capture the cause before the service operation clears it. Evidence: Correlate the status snapshot with the event ledger.
  5. Clear the handled source.. This fixture consumes the recorded events, clears the latch, and restarts the timeout. Clearing unrelated controller state would leave the level request asserted. Evidence: Observe source deassertion and verify that no new event was erased.
  6. Return access to normal traffic.. Release the sequencer and continue useful traffic. The checker retires exactly one service obligation. Evidence: Confirm ordinary traffic resumes and the expected-IRQ count returns to zero.

Threshold + timeout

  1. Nine events are still waiting.. The coalescer has recorded nine qualifying events. The example threshold is ten, and its safety timer has not expired. Evidence: Compare the event ledger to the source status before expecting an interrupt.
  2. Two causes create one service obligation.. Threshold and timeout become true together. They are two causes of the same latched request, not two independent IRQ completions. Evidence: Observe a single rising IRQ and preserve all qualifying cause information.
  3. Reactive traffic waits at a legal boundary.. The service sequence gains access after any already granted driver item reaches its permitted boundary. grab() is not an abort mechanism. Evidence: Keep the in-progress handshake trace and the sequencer ownership transition.
  4. Read the cause before changing it.. Read the latched event status once. Observation must capture the cause before the service operation clears it. Evidence: Correlate the status snapshot with the event ledger.
  5. Clear the handled source.. This fixture consumes the recorded events, clears the latch, and restarts the timeout. Clearing unrelated controller state would leave the level request asserted. Evidence: Observe source deassertion and verify that no new event was erased.
  6. Return access to normal traffic.. Release the sequencer and continue useful traffic. The checker retires exactly one service obligation. Evidence: Confirm ordinary traffic resumes and the expected-IRQ count returns to zero.
Related implementation: Reactive traffic and ISR threads
task body();
  fork
    // Thread 1: Normal Traffic
    forever begin
      `uvm_do_with(req, {type == DATA_PACKET;})
    end

    // Thread 2: Interrupt Handler (The ISR)
    forever begin
      @(posedge vif.irq[0]); // High Priority IRQ
      `uvm_info("IRQ", "High-Prio IRQ Detected! Pre-empting...", UVM_LOW)

      // Stop current bus traffic to simulate SW reading the status reg
      m_sequencer.grab(this);
      `uvm_do(read_status_reg_seq);
      `uvm_do(clear_irq_seq);
      m_sequencer.ungrab(this);
    end
  join_any
endtask

The source slide runs normal traffic and an IRQ listener concurrently. The listener takes sequencer ownership, performs the status-read and clear-register flow, and then releases arbitration.

Event 10, checkpoint 1: Nine events are still waiting.. Inspect the contract.
Understand the failure
Reactive event flowFrom event to service—and back to a cleared source.

The tracker predicts coalescing and priority while the reactive sequence models the software-visible service path.

1DMA done2Timer3ECC4Mailbox
Priority · mask · coalescingEvent trackerthreshold = 10 or safety timeout
IRQ
01grab()02read status03clear source04ungrab()

Event-to-service path

The checker follows each source event through priority and coalescing state, onto an IRQ line, and through the software-visible ISR handshake.

Event sources
Asynchronous IP events, including simultaneous and coalesced sources.
IRQ controller
Maps Event_ID to IRQ_Line, applies priority, and counts to the threshold or timeout.
Pulse monitor
Captures edge, level, width, and timestamp at the output pin.
Reactive ISR sequence
Takes sequencer ownership, reads status, and writes the clear control.
IRQ scoreboard
Correlates the source, programmed mapping, predicted pulse, and completed service.
  1. Event source -> priority and coalescing state
  2. Threshold or safety timeout -> IRQ line
  3. IRQ edge or level -> reactive ISR sequence
  4. Status read and clear write -> source retirement
  5. Source event + pin observation + RAL state -> scoreboard verdict

Why it matters

  • Interrupts are the hardware doorbell. A complex SoC interrupt controller may coordinate thousands of events.
  • A dropped interrupt can hang the operating system. Incorrect prioritization can make latency-sensitive work, such as audio processing, stutter.
  • The verification target includes the pin-level IRQ, the source/status mapping, priority behavior, and the software-visible read-and-clear service flow.

What is difficult

  • Interrupts are asynchronous to normal bus traffic, so a linear UVM sequence does not naturally model a high-priority IRQ interrupting a low-priority ISR.
  • A coalescing controller may wait for 10 packets before firing one IRQ. The checker must accept an interrupt on the 10th packet or when the safety timeout expires, whichever happens first.
  • Level-triggered interrupts persist until software clears them, while a one-clock edge interrupt can disappear before a polling sequence observes it.
  • An interrupt storm requires simultaneous source activity plus exact checking against the programmed priority registers.

Failure signatures

  • An event is dropped and the expected IRQ never arrives.
  • The arbiter services simultaneous sources in an order that disagrees with the priority registers.
  • A coalesced IRQ fires before event 10, after event 10, or after the timeout boundary.
  • A level IRQ deasserts before its clear write, or a one-cycle edge IRQ is never captured.
  • The IRQ pin toggles while the IP status register reports no active source, creating a spurious interrupt.
  • The testbench services an IRQ but never reads status or clears the source, hiding an incorrect hardware-software handshake.
Compare approaches

Two viable approaches—and their cost

Reactive virtual sequences

Use wait-for-interrupt tasks to launch the ISR sequence when the DUT asserts an interrupt.

Strengths
  • Naturally models hardware-software interaction.
  • Makes nested-interrupt and pre-emption scenarios direct to express.
Costs
  • Introduces threading and arbitration complexity in the virtual sequencer.
  • Can become difficult to manage when IRQs fire faster than service sequences complete.

IRQ scoreboard and event tracker

Count source events, predict output IRQ pulses, and check event-to-line mapping, coalescing, pulse width, and timing.

Strengths
  • Provides accurate event-to-pulse and threshold checking.
  • Separates asynchronous prediction from bus stimulus.
Costs
  • Does not by itself verify the ISR read-status and clear-register flow.
  • Needs state for every source, line, threshold, timer, and pending event.
Explain it in an interview

Interview answer, built from the mechanism

  1. I verify interrupt subsystems around pre-emption and coalescing. A reactive virtual sequence listens to the interrupt pins instead of assuming interrupts occur at a convenient point in a linear test.
  2. When a high-priority IRQ fires, the ISR sequence takes sequencer ownership, reads the status register, clears the interrupt, and then releases normal traffic. This models the software-visible service path as well as the pin.
  3. A dedicated scoreboard tracks source events, the programmed Event_ID-to-IRQ_Line mapping, pulse width, and the event-to-pulse ratio. It permits a coalesced IRQ only when the threshold is met or the safety timer expires.
  4. I add assertions for level persistence, a capture queue for one-cycle edges, simultaneous-source storm tests for priority, and a spurious-interrupt check that correlates every IRQ with an active status bit.
Assign responsibilities

Component responsibility contract

Component responsibilities and required verification changes for IRQ Subsystem Verification
ComponentResponsibilityRequired change
MonitorPulse detectionCapture IRQ edge, level, and pulse width, and timestamp the trigger.
SequencerPre-emptionUse is_relevant() or an equivalent arbitration policy to pause normal traffic while an IRQ is pending.
ScoreboardEvent mappingMap Event_ID from the IP to the output IRQ_Line and predict coalescing thresholds and timers.
Build the checker

Implementation patterns

Reactive traffic and ISR threadssystemverilog
task body();
  fork
    // Thread 1: Normal Traffic
    forever begin
      `uvm_do_with(req, {type == DATA_PACKET;})
    end

    // Thread 2: Interrupt Handler (The ISR)
    forever begin
      @(posedge vif.irq[0]); // High Priority IRQ
      `uvm_info("IRQ", "High-Prio IRQ Detected! Pre-empting...", UVM_LOW)

      // Stop current bus traffic to simulate SW reading the status reg
      m_sequencer.grab(this);
      `uvm_do(read_status_reg_seq);
      `uvm_do(clear_irq_seq);
      m_sequencer.ungrab(this);
    end
  join_any
endtask

The source slide runs normal traffic and an IRQ listener concurrently. The listener takes sequencer ownership, performs the status-read and clear-register flow, and then releases arbitration.

Stress the design

Stress recipe

  1. Program a coalescing threshold of 10 plus a known safety timeout.
  2. Send nine qualifying packets and prove that no IRQ is emitted.
  3. Send packet 10 and require the IRQ at the specified threshold boundary.
  4. Repeat with fewer than 10 packets, stop event arrival, and require the timeout-driven IRQ.
  5. Begin a low-priority ISR, assert a high-priority IRQ during service, and check pre-emption, status read, clear, and traffic resumption.
  6. Drive every event source simultaneously and compare service order with the priority-register image.
  7. Exercise a held level, a one-cycle edge, and an IRQ with no status source.

Follow-up questions

How do you verify level-triggered versus edge-triggered interrupts?

Use SVA to require a level IRQ to remain asserted until its Clear bit is written through RAL. Capture an edge IRQ in a local event queue even when it is only one clock wide.

How do you verify an interrupt storm?

Saturate all event inputs simultaneously and verify that the arbiter services them in the exact order defined by the priority registers.

What is a spurious interrupt, and how do you find it?

It is an IRQ with no active source. Flag an error if an IRQ pin toggles while the IP status register reports no active event.

Engineering qualifications