Skip to content

rtl/noc_router.sv — NoC Instruction Router

The central hardware dispatcher: a 3-port router (CPU + GPU + NPU) that decodes the 7-bit opcode of every incoming network instruction word in a single combinational cycle and drives the appropriate valid/ready handshake to the target engine. Replaces the older server_dispatch_unit.sv, which is kept in the tree only for reference.

Where it fits

Instantiated once by base_die_top.sv as router_inst. Its cpu_valid/cpu_instruction outputs are unused (cpu_accept is what actually drives the CPU-link instr_load channel); its gpu_* port goes straight to the base-die-resident gpu; its npu_* port feeds the NPU-link instr_load... actually npu_disp channel toward npu_chiplet_top.

Ports

Direction Name Width Description
in clk, rst_n 1, 1 Clock / reset
in net_valid 1 Incoming instruction valid
out net_ready 1 Backpressure to the network source
in net_instruction 32 Incoming instruction word
out cpu_valid 1 (unused at the die-boundary level — see cpu_accept below)
out cpu_accept 1 Combinational 1-cycle pulse — fires exactly once when a CPU-bound instruction's handshake completes
in cpu_ready 1 Downstream CPU-link channel credit
out cpu_instruction 32 (unused — net_instruction is forwarded directly by base_die_top on the cpu_accept pulse instead)
out gpu_valid 1 GPU dispatch valid
in gpu_ready 1 GPU accepting (only in its IDLE state)
out gpu_instruction 32 GPU-bound instruction, held until accepted
out npu_valid 1 NPU dispatch valid
in npu_ready 1 NPU-link channel credit
out npu_instruction 32 NPU-bound instruction, held until accepted

Functionality — routing table

Opcode [6:0] Class Target
0x37 LUI, 0x17 AUIPC, 0x6F JAL, 0x67 JALR, 0x63 BRANCH, 0x03 LOAD, 0x23 STORE, 0x13 OP-IMM, 0x33 OP (incl. RV32M MUL/DIV) Standard RV32I/M CPU
0x57 custom-0 (vector ALU) GPU
0x6B custom-1 (neural/matrix) NPU
anything else dropped (net_ready=1 to prevent deadlock, no dispatch)

net_ready = (target_cpu & cpu_ready) | (target_gpu & gpu_ready) | (target_npu & npu_ready) | (!route_valid & net_valid) — the last term accepts-and-drops unknown opcodes so the network source never wedges on an instruction no engine will claim.

cpu_accept = target_cpu & route_valid & net_ready — combinational, fires the exact cycle the handshake completes, guaranteeing each accepted CPU instruction is written into imem exactly once regardless of how long net_valid is held.

Each target's dispatch register (cpu_valid/gpu_valid/npu_valid + its instruction) is held until that engine's own _ready signal clears it — i.e. until the engine actually consumes it.

Example

Dispatching one NPU instruction while the GPU is mid-OUTPUT_ST (busy, gpu_ready=0) has zero effect on NPU dispatch — each of the three ports arbitrates independently:

net_instruction = 0x6B_... (custom-1, opcode 0x6B)
-> target_npu=1, route_valid=1
-> net_ready = npu_ready   (gpu_ready's value is irrelevant here)
-> if npu_ready: cpu_accept=0, npu dispatch register latches next cycle