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
Related
- server_dispatch_unit.md — the earlier CPU/GPU/NPU-only router this one is functionally descended from
- base_die_top.md — instantiates this and bridges
cpu_accept/npu_validonto UCIe channels - reference.md — full opcode table