IRQ controller – openenoc_endpoint_irq_controller

Collects admitted hardware events into ordered interrupt claims for software completion.

Source: openenoc_endpoint_irq_controller.sv.

Parameters

Parameters

Name

Default value

Allowed values

Description

EVENT_PORTS

6

Integer >= 1

Number of independent interrupt-event producer ports.

FIFO_DEPTH

16

Integer >= 1

Shared capacity for queued claims and producer reservations.

PEER_IDX_W

1

1..11

Event peer-index width, bounded by the generated CSR claim field.

SEQUENCE_W

16

1..16

Interrupt claim sequence width, bounded by the generated CSR token field.

SAMPLED_ENABLE_MASK

'0

EVENT_PORTS-bit mask

A set bit means the producer has already sampled the source-enable decision.

Signals

Interface ports contain channels in both directions. The table identifies the selected modport or stream role; member directions follow that interface.

Public signals and interfaces

Name

Type

Direction / role

Description

clk

logic

input

Clock for this component or interface domain.

rst

logic

input

Active-high reset of transaction and control state.

endpoint_if

openenoc_endpoint_if.core

bidirectional (core)

IRQ enables, claim and completion fields, status, and error-clear commands.

irq

logic

output

Level interrupt notification to software.

event_if[EVENT_PORTS]

openenoc_irq_event_if.
controller

bidirectional (controller)

Producer admission and commit channels.

Architecture and operation

Boundary and parameters: event_if[EVENT_PORTS] accepts producers of IRQ event producer – openenoc_irq_event_if; endpoint_if exposes enable, claim, completion, and error controls; irq notifies software. Defaults are EVENT_PORTS = 6, FIFO_DEPTH = 16, PEER_IDX_W = 1, SEQUENCE_W = 16, and SAMPLED_ENABLE_MASK = 0. Peer and sequence widths must fit their generated CSR fields.

Endpoint integration uses seven producer ports and marks port 5 (initiating RMEM error) as having already sampled its source enable. For that port, admit_enable includes the captured enable decision, and the controller does not re-read the live source CSR. For unmarked ports, the controller combines admit_enable with the source-enable CSR when preparing the registered admission offer. Later enable changes do not revise that offer or cancel accepted reservations.

Admission and commit use independent round-robin SELECT/OFFER machines. Selection prepares a registered READY offer; the next edge accepts the producer’s stable VALID and metadata. Each channel accepts at most one enabled operation every two cycles. Disabled admissions can be offered to multiple ports in parallel. Admission reserves credit for a particular producer port; another port cannot consume that reservation, even if both ports report the same event source.

The FIFO capacity is shared by queued claims and reservations. An enabled admission reserves capacity when its READY offer is prepared, before the handshake completes. Withdrawing VALID during that offer releases the provisional reservation. A commit converts one of its port’s reservations into a queued claim without changing the total occupied capacity. A full credit pool blocks new enabled admissions but permits commits backed by existing reservations. A matching completion releases a queued credit, which can fund a new registered admission offer on the same edge.

Claims are ordered by accepted commits, which may differ from admission order. Each accepted commit receives the next sequence number, starting at zero after reset and wrapping modulo 2**SEQUENCE_W. These sequence tokens are independent of oETP Request IDs. The current head remains stable until software completes it. A matching completion and an already offered commit can replace the head on the same edge without dropping claim validity.

Software completes a claim by copying its valid, sequence, source, and peer fields to irq.complete. All token fields must match the head, including zero extension into unused upper CSR bits when parameter widths are smaller. The controller acknowledges a completion command through complete.valid.hwclr whether the token matches or not. A mismatch, or a command with no claim pending, leaves the queue unchanged and sets sticky status.invalid_complete. A commit without a reservation on its producer port, or without queue space, sets status.overflow and creates no claim.

control.clear_errors clears these two controller diagnostics; a new error on the same edge takes precedence. Completion and clear commands are each applied once while their command bit remains asserted. Their registered hwclr outputs stay high until the respective input bit is sampled low. Clearing controller or DMA errors is separate from completing a claim.

The global enable masks only the physical level IRQ. Event capture, credit accounting, and claim visibility continue while it is low. The registered irq and status.irq_asserted reflect the sampled global enable and whether claims remain after the edge’s queue updates. status.claim_pending follows claim validity independently of this mask. status.fifo_level counts queued claims; status.reserved_count counts reservations, including provisional READY offers. Both CSR counters saturate at 255. status.credit_full uses the exact internal counts, so saturation does not affect capacity control. Reset clears claims, reservations, sequence state, handshakes, IRQ, and controller diagnostics.

Functional scenarios

The admission/commit contract is illustrated in IRQ event producer – openenoc_irq_event_if, and firmware IRQ service is illustrated in Full endpoint – openenoc_endpoint_full. The examples here focus on controller credit accounting and claim retirement. They use EVENT_PORTS = 1, PEER_IDX_W = 2, and SEQUENCE_W = 16; each states its FIFO depth.

S0 denotes EVENT_PEER_DMA_COMPLETE (source 0), enabled throughout. The producer uses admit_enable = 1 and admit_source = S0; all commits use commit_source = S0. I0 and I1 denote distinct peer indices. D0 and D1 are complete claim words with sequence numbers 0 and 1, respectively, source S0, and peer indices I0 and I1.

Numbered cycles label intervals between rising edges. Admission and commit transfer at an interval’s ending rising edge when VALID and READY are high. CSR command bits are sampled at the same edge. CSR field paths are relative to endpoint_if.csr_to_core for CSR inputs and endpoint_if.core_to_csr for Core outputs; generated .value and .next wrappers are omitted. The diagrams show the controller boundary, so they do not include CSR bus transaction latency. claim and complete denote packed words while valid; x marks irrelevant values.

IRQ masking, shared credit, and completion-edge reuse

Use FIFO_DEPTH = 1, initially empty after reset. The physical IRQ is masked by control.global_enable = 0. Preparing the first admission offer reserves the only credit: status.reserved_count = 1 and status.credit_full = 1 are already visible in cycle 2, when the admission handshake occurs.

The first commit transfers in cycle 4. In cycle 5, the reservation has become queued claim D0: status.reserved_count falls to zero, status.fifo_level rises to one, and status.credit_full remains asserted. The claim is visible even though irq = 0. A second enabled admission waits from cycle 5 because no credit is free.

Software raises the global enable in cycle 7, so irq rises in cycle 8. The matching completion D0 is sampled at the end of cycle 8. That edge removes the claim and prepares the waiting admission offer. In cycle 9, the FIFO is empty, a new reservation occupies its capacity, and status.credit_full is still asserted. The second admission transfers in that cycle.

Its commit transfers in cycle 11 and becomes claim D1 in cycle 12. Because the global enable remains high, this new claim also raises irq. Masking the IRQ never released either operation’s credit.

A one-entry IRQ FIFO accounts for reservations and claims while masking its physical IRQ.

IRQ masking and reuse of shared FIFO credit

Exact completion tokens and simultaneous head replacement

Use FIFO_DEPTH = 2 and control.global_enable = 1. Initially, claim D0 occupies one entry, and the same producer already holds a reservation for its second operation. No new admission is needed in the shown interval. D2 copies D0 except for an incorrect sequence number.

Software asserts complete.valid with D2 in cycle 1 and holds it through cycle 3. The controller acknowledges the command in cycle 2 and sets status.invalid_complete, while D0, FIFO occupancy, and irq remain unchanged. The acknowledgement therefore confirms command processing, not successful claim retirement.

In cycle 5, software presents the correct D0 token and requests error clearing. On the same edge, the producer commits its second operation with peer I1. Claim D1 replaces D0 in cycle 6: claim.valid and irq remain high, FIFO occupancy stays at one, and the remaining reservation is consumed.

The old completion D0 stays asserted through cycle 7, but it is applied only once. It does not remove D1 or reassert status.invalid_complete after the clear. Software releases the command, then submits D1 in cycle 9. The queue becomes empty and irq falls in cycle 10.

An invalid token preserves the head; a valid completion and commit replace it together.

Exact completion matching and claim replacement without an IRQ gap

Verification

The test suite is in dv/core/openenoc_endpoint_irq_controller/.

Testbench

This cocotb suite verifies the IRQ controller in isolation from the processor, CSR register block, and event producers. The wrapper flattens CSR fields and event interfaces for cocotb. Eight cases run in eight configurations covering 1–7 producer ports, FIFO depths 1, 3, 4, 7, 8, 16, and 260, peer widths up to 11 bits, and sequence widths up to 16 bits.

The tests check independent producer arbitration and credits, FIFO pressure, exact completion tokens, simultaneous completion and commit, held CSR commands, IRQ masking, sequence wrap, status saturation, and output stability between clock edges.

Coverage

The suite covers:

  • reset of claims, reservations, sequence state, and sticky diagnostics;

  • locally disabled admissions and all six source enables, including RMEM_ERROR;

  • per-producer reservations, including independent initiator/responder ports sharing source 0;

  • independent round-robin admission and commit arbitration;

  • FIFO-full backpressure, capacity reuse, and simultaneous claim enqueue/dequeue;

  • ordered, stable claims with preserved peer indices and exact completion-token matching;

  • invalid tokens, nonzero unused token bits, and commits without reservations;

  • global IRQ masking, sequence wraparound, arbitrary FIFO depths, and 8-bit status saturation;

  • registered output stability and one application of held CSR completion/clear commands.