Peer-table lookup – openenoc_endpoint_peer_lookup

Resolves peer-table queries and returns a coherent configuration snapshot to each client.

Source: openenoc_endpoint_peer_lookup.sv.

Parameters

Parameters

Name

Default value

Allowed values

Description

LOOKUP_PORTS

2

Integer >= 1

Number of peer-lookup clients sharing the response queue.

NUM_OF_PEERS

4

Integer >= 1; match generated CSR array

Number of peer-table entries.

PEER_IDX_W

NUM_OF_PEERS > 1 ? $clog2(NUM_OF_PEERS) : 1

Integer >= 1; enough bits for the peer count

Width of local peer indices; all connected interfaces must agree.

ADDR_W

32

32

Peer address width required by the current CSR entry format.

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)

CSR peer-table configuration sampled when accepting a lookup request.

lookup_if[LOOKUP_PORTS]

openenoc_peer_lookup_if.slv

bidirectional (slv)

Per-client peer query and coherent peer-entry response snapshot.

Architecture and operation

Boundary and parameters: endpoint_if supplies the CSR peer table; lookup_if[LOOKUP_PORTS] serves clients of Endpoint peer lookup – openenoc_peer_lookup_if. Defaults are LOOKUP_PORTS = 2, NUM_OF_PEERS = 4, and ADDR_W = 32; PEER_IDX_W is derived with a minimum of one bit.

A single clocked process arbitrates requests round-robin, samples peer entries, and updates registered READY and response outputs. A request first receives a registered grant and is accepted on the following rising edge if VALID remains asserted. The coherent entry snapshot becomes visible after that acceptance edge once it reaches the response-queue head. Arbitration starts at client 0 after reset and advances to the client following each accepted request, skipping clients without an active request.

All clients share a two-entry response queue. Responses leave in request acceptance order, and only the owner of the head response sees rsp_valid. If that client stalls, a response for another client must wait behind it even when the other client is ready. The second entry can hold a response for a request already granted before the stall. A full queue stops new grants; freeing an entry permits another registered grant, so a waiting request is accepted on the following edge. With ready clients, the module accepts one request and returns one response per cycle after the initial grant latency. Configuration writes do not alter a buffered response, which remains stable until its owner accepts it.

Disabled entries never match. Index lookups select peer DMA modes 2/3; RMEM lookups select mode 1 and require the requested address to belong to its half-open RMEM region. MAC lookups select any enabled matching entry. req_mode_mask further restricts permitted modes for every lookup type. When several eligible entries match, the lowest peer-table index wins. Zero-sized RMEM regions never match. The region end is calculated with an extra carry bit, so a range extending beyond the 32-bit address space does not wrap around to low addresses. A miss returns deterministic zero entry fields. Reset clears the response queue, outward handshakes, and round-robin state.

Functional scenarios

Query types, mode masks, and single-client snapshot timing are covered by Endpoint peer lookup – openenoc_peer_lookup_if. The example below uses the default two clients and four peer entries to show contention for the shared response queue. All requests use req_type = LOOKUP_BY_INDEX and req_mode_mask = 0xC. I0, I1, and I2 identify distinct enabled entries in DMA mode 2 or 3, so every query returns the selected peer.

Numbered cycles label intervals between rising edges; a transfer occurs at the ending rising edge when VALID and READY are both high. x marks irrelevant values. The queue is initially empty, and arbitration starts from its reset position.

Concurrent clients and shared response queue

Both clients assert req_valid in cycle 1. Client 0 receives the first registered grant and its request for I0 transfers in cycle 2. The next grant goes to client 1, whose request for I1 transfers in cycle 3. Client 0 presents its next request, for I2, immediately after the first acceptance and holds it while waiting for another grant.

Client 0 keeps rsp_ready = 0 through cycle 5. Its response for I0 remains at the queue head, and the response for I1 occupies the second entry. Client 1 keeps rsp_ready = 1, but its rsp_valid stays low until the preceding response is consumed. The full queue also prevents a grant for the waiting I2 request.

Client 0 accepts its first response in cycle 6. The newly available space allows a registered grant for I2 in cycle 7, while the response for client 1 also transfers in that cycle. The response for I2 then transfers in cycle 8. Each response includes the full snapshot associated with its accepted request.

Two clients contend for the lookup queue; a stalled head response delays the other client.

Shared peer-lookup response queue with a stalled client

Verification

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

Testbench

This cocotb suite verifies peer lookup with the generated CSR block and bridge. All peer configuration uses AXI4-Lite transactions. Five cases run with two clients, four peers, two-bit peer indices, and 32-bit addresses.

The tests check continuous traffic, buffered response ownership, backpressure, configuration snapshots, overlapping-entry priority, RMEM range boundaries, and output stability between clock edges.

Coverage

The suite covers:

  • generated CSR configuration, readback, and complete coherent peer snapshots;

  • index, RMEM-address, and MAC-address lookup with DMA-mode filtering;

  • disabled entries, mode masks, deterministic misses, and lowest-index match priority;

  • half-open and zero-sized regions, overlaps, and address-wrap protection;

  • registered grants, round-robin arbitration, and sustained one-response-per- cycle traffic;

  • two buffered responses, stable backpressured data, and same-cycle replacement;

  • configuration changes after acceptance and output stability between clock edges.