rtl/duck_ucie_pkg.sv — UCIe Flit Field Reference (docs-only)
Documents the flat-signal "flit" fields shared by every ucie_chan instance in the design, and the flit_type encoding used by each chiplet boundary. Not imported by any RTL module (same convention as duck_cache_pkg.sv) — Icarus Verilog 11 / cocotb 2.0 need flat signals rather than packages/structs on module ports, so every ucie_chan instantiation site ties off unused fields to 0 directly instead of importing this package. It exists purely as documentation.
Where it fits
Not instantiated or imported anywhere — read this file (or this page) to understand what tx_type/tx_addr/tx_data/tx_byte_en/tx_tag mean at each ucie_chan call site in system_top.sv.
Flit fields
| Field | Width | Meaning |
|---|---|---|
tx_type |
4 | Flit opcode, see table below |
tx_addr |
32 | Byte address (MEM_RD_REQ/MEM_WR_REQ only) |
tx_data |
32 | Payload word (instruction, wdata, rdata, or result) |
tx_byte_en |
4 | Store byte enables (MEM_WR_REQ only) |
tx_tag |
4 | Correlation id (NPU_RESULT: accumulator row index) |
Every ucie_chan instance in system_top.sv carries exactly one flit type in practice (each virtual channel is single-purpose), so tx_type is largely documentation — unused fields are tied to 0 at the instantiation site.
Flit opcodes and channel sizing
| Constant | Value | Direction | Carries |
|---|---|---|---|
FLIT_INSTR_LOAD |
0 | base → cpu | Accepted network instruction word |
FLIT_MEM_RD_REQ |
1 | cpu → base | Load request (addr valid) |
FLIT_MEM_WR_REQ |
2 | cpu → base | Store request (addr, data, byte_en valid) |
FLIT_MEM_RSP |
3 | base → cpu | Load/store completion (data = rdata) |
FLIT_NPU_DISP |
4 | base → npu | Dispatch instruction (custom-1 word) |
FLIT_NPU_RESULT |
5 | npu → base | One accumulator result (tag = row idx) |
| Constant | Value | Meaning |
|---|---|---|
CH_DEPTH_INSTR_LOAD |
256 | Matches cpu_chiplet_top's imem capacity |
CH_DEPTH_MEM_REQ |
2 | Single outstanding CPU load/store |
CH_DEPTH_MEM_RSP |
2 | — |
CH_DEPTH_NPU_DISP |
1 | Mirrors original npu_ready (1 in flight) |
CH_DEPTH_NPU_RESULT |
4 | Absorbs bursts of the 16-word output stream |
CH_CROSSING_LATENCY |
2 | Cycles, stand-in for SerDes + interposer hop |
LINK_TRAIN_CYCLES |
4 | Cycles per link-training sub-state |
Why raw/streaming mode, not PCIe/CXL mode?
Duck Server's inter-die traffic is a custom instruction/result stream, not memory-mapped PCIe TLPs or CXL.mem/cache semantics — UCIe's raw (streaming) mode is the correct fit: the protocol layer is fully custom, carried over the standard UCIe die-to-die adapter + physical-layer bring-up sequence.
Why one flit type per channel instead of a shared multiplexed stream?
Real UCIe supports multiple virtual channels per link precisely to avoid head-of-line blocking between unrelated traffic classes. Duck Server's dedicated single-purpose ucie_chan per direction is the same idea, sized down to this SoC's traffic (5 channels total instead of a generic N-VC crossbar).
Related
- ucie_chan.md — the module every one of these fields describes
- chiplets.md — the channel table this file documents, in context