Skip to content

rtl/ucie_link_ctrl.sv — UCIe Die-to-Die Link Training FSM

Models the bring-up sequence of a UCIe link at the state-name level of the spec, without bit-accurate PHY/eye-training.

Where it fits

Two instances in system_top.sv: cpu_link_ctrl_inst and npu_link_ctrl_inst, each with TRAIN_CYCLES=4. Each instance's link_up output gates every ucie_chan on that physical link.

Parameters

Parameter Default Meaning
TRAIN_CYCLES 4 Cycles held in each pre-ACTIVE state before advancing

Ports

Direction Name Width Description
in clk, rst_n 1, 1 Clock / reset
out link_up 1 1 once state == LT_ACTIVE
out train_state 3 Debug/observability only — current FSM state

Functionality

Sequential 7-state FSM, one state transition per TRAIN_CYCLES cycles until ACTIVE:

RESET → SBINIT → PARAM → MBINIT → MBTRAIN → LINKINIT → ACTIVE
State Real-world stand-in
RESET link held down out of chip reset
SBINIT sideband initialization (low-speed always-on lane bring-up)
PARAM parameter exchange (widths, speed, module IDs — stubbed)
MBINIT mainband initialization
MBTRAIN mainband training (SerDes lock, eye training — stubbed)
LINKINIT final link initialization handshake
ACTIVE link up; ucie_chan instances on this link may pass flits — sticky, no dynamic retrain or L1/L2 low-power entry modeled (the state encoding leaves room for it)

Example

With TRAIN_CYCLES=4 (the value used everywhere in this repo), a link takes exactly 6 × 4 = 24 cycles after reset deasserts before link_up goes high — every testbench's reset_dut() holds rst_n low for several cycles and then simply proceeds; the first few instructions dispatched after reset queue up behind tx_ready=0 until both links finish training, which every test in this repo already tolerates because send_instruction() just waits on net_ready.