Ethernet clock/width adapter – openenoc_eth_adapter
Bridges bidirectional Ethernet-like streams across clock domains and stream widths.
Source: openenoc_eth_adapter.sv.
Parameters
The table describes the Ethernet profile, with byte-granular KEEP, frame termination enabled, and no active stream ID, destination, or user metadata.
Name |
Default value |
Allowed values |
Description |
|---|---|---|---|
|
|
At least two beats at the wider link width |
Capacity passed to TAXI; counts bytes with enabled KEEP and eight-bit lanes, otherwise whole stream words. Account for the wider side. |
|
|
Integer >= 0 |
RAM pipeline register count in each asynchronous FIFO adapter. |
|
|
0 or 1 |
Enables the FIFO adapter output FIFO. |
|
|
0 or 1 |
Holds complete frames before making them available at the output. |
|
|
0 or 1; requires FRAME_FIFO |
Drops frames that exceed the frame FIFO capacity. |
|
|
0 or 1; requires frame buffering and oversize dropping |
Discards arriving frames instead of backpressuring when full. |
|
|
0 or 1 |
Frame-boundary pause policy; inactive because this wrapper has no pause requests and leaves TAXI PAUSE_EN disabled. |
The generic TAXI marker options remain in the source declaration:
USER_BAD_FRAME_VALUE = 1'b1, USER_BAD_FRAME_MASK = 1'b1,
DROP_BAD_FRAME = 1'b0, and MARK_WHEN_FULL = 1'b0.
Marker-based dropping or overflow marking requires an enabled USER field;
keep both policies disabled for Ethernet links.
Signals
Interface ports contain channels in both directions. The table identifies the selected modport or stream role; member directions follow that interface.
Name |
Type |
Direction / role |
Description |
|---|---|---|---|
|
|
bidirectional; A clock domain |
Receives A-to-B frames and transmits B-to-A frames using this link’s clock/reset. |
|
|
bidirectional; B clock domain |
Transmits A-to-B frames and receives B-to-A frames using this link’s clock/reset. |
Embedded stream |
Adapter role |
Clock/reset |
|---|---|---|
|
Sink |
|
|
Source |
|
|
Sink |
|
|
Source |
|
Each stream uses tdata, tkeep, tlast, tvalid, and
tready as described in Bidirectional Ethernet link – openenoc_eth_if. Widths follow the containing
link; READY travels in the opposite direction to frame data.
Architecture and operation
The adapter connects eth_a and eth_b using one TAXI asynchronous FIFO
adapter per direction. The links provide their own clk/rst and AXIS widths.
The A-to-B path preserves a2b_axis_if orientation; the B-to-A path preserves
b2a_axis_if orientation. Local TAXI interfaces bridge nested link interfaces
for tool compatibility.
DEPTH, RAM_PIPELINE, and OUTPUT_FIFO_EN configure buffering.
FRAME_FIFO and the drop options select frame policy. Defaults allow
streaming rather than requiring a whole frame before forwarding.
Each direction has its own storage and flow control; backpressure does not
propagate into the opposite-direction FIFO.
For enabled KEEP with eight-bit lanes, DEPTH counts bytes. Internally the
FIFO stores the wider side’s beats and rounds the cycle count up to a power
of two. The depth must therefore leave usable storage at that width. Link
widths must have an integer ratio for width adaptation. FRAME_FIFO = 0
with all drop/mark policies clear permits a frame larger than the FIFO to
progress through backpressure as its receiver consumes bytes. This generic
adapter does not impose the endpoint oETP engine’s frame-size ceiling.
Width conversion keeps byte order and frame boundaries. Widening gathers successive narrow beats into the low, then high lanes of a wide beat. Narrowing emits the low lanes first. A partial final beat is released on TLAST without waiting for more bytes; KEEP identifies its valid lanes.
With FRAME_FIFO = 1, a frame that fits in the FIFO is made visible to
the receiving clock domain only after its final input beat is accepted.
The default DROP_OVERSIZE_FRAME = 1 discards an oversized frame.
If oversize dropping is disabled, TAXI can release an oversized frame in
pieces to make progress; size the FIFO for the largest frame when whole-frame
buffering is required. Pause requests are not exposed by this wrapper, so
FRAME_PAUSE has no active pause request to control.
Reset flushes queued data and interrupts in-flight frames. For a clean restart, coordinate reset with the attached sources and sinks in both link domains. The opposite-domain reset is synchronized through four release stages in each local domain. Keep both clocks running during release and restart frame transmission through the ordinary READY handshake. There is no replay of frames interrupted by reset.
Functional scenarios
The examples use a 66-byte Ethernet frame, counted from Destination MAC
through the final payload byte and excluding preamble, SFD, and FCS.
DA0, DA1, … identify successive four-byte portions of an A-to-B
frame; DB0, DB1, … identify the reverse frame. Word 16 contains
only the last two bytes. A packed label such as DA0/1 means DA0
in bits 31:0 and DA1 in bits 63:32. Labels retain the same meaning
throughout a scenario and its continuation.
KEEP width follows each link’s DATA width:
DATA width |
KEEP width |
Full-beat mask |
Final two-byte mask |
|---|---|---|---|
32 bits |
4 bits |
|
|
64 bits |
8 bits |
|
|
Both links use KEEP_EN = 1 and LAST_EN = 1. All scenarios use
RAM_PIPELINE = 1, OUTPUT_FIFO_EN = 0, and disabled bad-frame,
overflow-marking, and drop-when-full policies. Resets have already been
released, and the links are otherwise idle.
A transfer occurs at the ending rising edge of its own link-clock interval
when VALID and READY are both high. x denotes irrelevant values while
VALID is low. Tick labels count 10 ns intervals; a 20 ns B-clock cycle
spans two of these intervals.
Concurrent widening and narrowing
Use eth_a.DATA_W = 32, eth_b.DATA_W = 64, DEPTH = 128,
and FRAME_FIFO = 0. The A clock period is 10 ns and the B clock
period is 20 ns. Both sources send their 66-byte frames concurrently,
and both receivers remain ready.
The A-to-B path accepts 16 full four-byte beats followed by DA16
with KEEP 0x3 and TLAST. It packs each successive pair into a full
64-bit word with KEEP 0xFF. The final word carries only DA16;
KEEP 0x03 invalidates its six unused byte lanes. TLAST releases this
partial word without waiting for another narrow beat.
Forwarding begins while the source is still sending the frame: streaming
mode exposes available FIFO words after they cross the clock domain.
A 66-byte frame widens from 32 to 64 bits across clock domains
The reverse path accepts eight full 64-bit beats and one final beat with
KEEP 0x03. It emits the low 32-bit portion of each full beat first,
then its high portion. Thus DB0/1 becomes DB0, then DB1.
The final partial wide word produces only DB16 with KEEP 0x3
and TLAST; it produces no empty upper-half beat. The two directions
preserve their own byte ordering and frame boundaries independently.
The concurrent reverse frame narrows from 64 to 32 bits
Whole-frame buffering waits for commit
Use 32-bit A and 64-bit B links, with clock periods of 10 ns and
20 ns, DEPTH = 128, and FRAME_FIFO = 1. Keep
DROP_OVERSIZE_FRAME = 1 and the other drop/mark policies disabled.
The frame occupies nine 64-bit FIFO locations, including its partial
last word, and fits within the 16 locations provided by this configuration.
The destination remains invalid while all 66 input bytes are accepted.
The final DA16 with KEEP 0x3 and TLAST flushes the partial
packed word and commits the frame. The committed boundary then crosses
to the B domain before FIFO reads make the frame available.
Frame buffering accepts the complete frame before release
Nine consecutive B-clock transfers deliver the complete frame, ending
with KEEP 0x03 and TLAST. With the receiver ready and the complete
frame buffered, output VALID stays asserted through its final beat.
The adapter changes packing and delivery timing while preserving the
66 frame bytes.
The committed frame crosses to the receiving clock domain
Verification
The test suite is in dv/core/openenoc_eth_adapter/.
Testbench
This cocotb suite verifies bidirectional Ethernet adaptation using independently clocked stream fixtures. Pytest sweeps asymmetric pairs from widths 8, 16, 32, 64, 128, 256, and 512 bits. The default waveform configuration uses 8/512-bit streams. The fixture uses two widest-side storage beats and streaming FIFO policy.
Coverage
The suite covers:
A-to-B and B-to-A frame preservation with width conversion and clock-domain crossing;
source idle insertion, sink backpressure, and TID/TDEST/TUSER preservation;
simultaneous traffic without cross-direction corruption;
initial sink pauses in each direction;
directed frame lengths 20, 21, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511, and 512 bytes;
bidirectional stress with 30 random 20–256-byte frames and two 9000-byte jumbo frames.