Skip to content

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).

  • ucie_chan.md — the module every one of these fields describes
  • chiplets.md — the channel table this file documents, in context