片上网络 NoC:把「路由网络」缩小到一颗芯片里
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」**进阶层(intermediate)**数字逻辑第八十九篇。前面用总线/AXI、仲裁连接少数几个主从设备。可当芯片里有上百个 CPU、GPU、NPU、DMA、缓存分片时,共享总线和全交叉开关在面积、功耗、长线延迟上都不可扩展。于是工程师把计算机网络的思想搬上硅片,这就是 NoC(Network-on-Chip)。
本文要回答的问题
- 为什么核一多,总线/交叉开关就不够用?NoC 怎么做到可扩展?
- 报文为什么要切成定长微片(flit)?头微片里装什么?
- 一个路由器内部有哪几级流水(RC/VA/SA/ST)?报文每跳怎么走?
- 虚通道(VC)是什么,它怎么解队头阻塞、怎么防死锁?
- XY 路由为什么天然无死锁?credit 流控和 valid-ready 什么关系?
一、拓扑与报文:mesh、flit 与节点编址
NoC 用大量短而规整的点到点链路把路由器连成二维 mesh(也有 ring、torus、树形),每个路由器挂一个本地节点(一个核或一个缓存分片/IP)并与东、南、西、北四个邻居相连。把数据拆成定长的微片 flit(flow control digit),一个包 packet 由 head(携带目的坐标/源/长度/类型)、若干 body、tail(标记包结束)组成。这种 **wormhole(虫洞)**交换像虫子钻洞:头 flit 一边走一边建立路径,body/tail 紧跟其后占住沿途通道,整个包不需要在一个路由器里完整缓存——片上缓冲极小、延迟低。
(0,0)—R—R—R
| | |
R——R——R R=路由器,每个 R 下挂一个核/缓存分片
| | |
R——R——R二、路由器数据通路与五级流水
一个典型输入缓冲路由器的每个输入端口有若干 VC FIFO,报文在每跳经历经典流水段:
- BW(buffer write):到来 flit 写入对应输入 VC 的 FIFO;
- RC(route compute):头 flit 根据目的地址和路由算法(如 XY:先沿 X 走到同列、再沿 Y)算出输出端口;
- VA(VC allocation):为该包在下一路由器的输出端口申请一个空闲输出虚通道(仅头 flit 需要,body/tail 继承);
- SA(switch allocation):已获 VC 的输入端口竞争本周期的交叉开关时刻,由仲裁器在多个请求中选一个;
- ST(switch traversal)+ LT(link traversal):选中的 flit 经内部交叉开关和输出链路发往下一跳。
成熟实现常把 SA+ST、RC+VA 合并压缩到 2~3 级流水以降低每跳延迟(zero-load latency ≈ 路由/分配 + 物理跳数 × 每跳周期)。
三、虚通道:多组 FIFO 如何解决队头阻塞与死锁
每个输入端口不是一个大 FIFO,而分成多个虚通道(VC,virtual channel)——各自独立的 flit 队列、共享同一条物理链路,由一个 VC id 字段区分。两个关键作用:
- 解队头阻塞(HOL blocking):若 VC0 队头的包因下一跳端口忙而走不了,VC1 里去别的方向的包仍可被 SA 选中发出,不被堵在后面;
- 破除通道依赖环(防死锁):wormhole 网络中包会同时占住多跳通道,若四个包各占一个通道又等下一个,可能形成循环等待全部卡死(死锁)。把 VC 分成两类并规定「转弯只能从 VC0 进入 VC1、不能反向」,就切断了依赖环。XY 维序路由(先 X 后 Y、不许回头)本身在 mesh 上也可证明无环、无死锁。
此外用有向的转弯限制(odd-even、west-first 等)可在不死锁的前提下放宽 XY 的路径限制、做负载均衡和容错。
四、流控:credit 与 valid-ready
链路每周期可发一个 flit,接收方缓冲有限,必须反压:
- credit 流控(on/off 计数):下游每有一个空 VC 槽就发一个 credit,上游发一个 flit 减一个 credit,credit 用完即停;控制准确、可隐藏一个 RTT 延迟,NoC 最常用;
- valid/ready 握手:下游当拍用 ready 表示能收(与 valid-ready 同源),简单但反压延迟要小心;
- 丢包(像计算机网络那样)在片上不可接受——NoC 保证可靠投递,靠反压而非重传(链路可用 ECC/CRC 检错后再重传/中断)。
跨时钟域(核与 NoC、NoC 与 IO 不同频)在网络接口 NI 处用异步 FIFO/CDC解耦,报文先在 NI 打包成 flit、到达再还原回 AXI 事务。
五、为什么用 NoC,以及设计权衡
- 可扩展性:总线带宽被所有设备分时共享、仲裁随设备数变差;全交叉开关面积/功耗随 N² 涨;mesh 上每节点只连 4 个邻居、链路短而流水化,加核只加路由单元,频率可保持;
- 代价:每跳引入路由+分配延迟(多跳访问远端缓存比总线慢)、路由器本身有面积/功耗,数据要打包/拆包、可能乱序(需协议支持或在同一 VC 保序);
- 设计要联合优化:拓扑(mesh/ring/聚簇)、每跳流水级数、VC 数与深度、flit 宽度(常 128/256bit 匹配缓存行)、路由算法(负载均衡 vs 无死锁)、QoS(为实时/DMA 流量预留 VC 或优先级)、多播(缓存一致性目录广播)。NoC 是把「仲裁+FIFO+交叉开关+CDC」组合成的分布式互连系统。
与现有篇目的衔接
总结
一句话总结:当主控数量达到几十上百时,共享总线带宽被分时且仲裁变差、全交叉开关面积功耗按平方增长都不可扩展,NoC 把计算机网络搬上硅片,用短而规整的点到点链路把挂着本地核或缓存分片的路由器连成 mesh/ring,数据被切成带目的坐标的 head、body、tail 定长微片,以虫洞方式由头 flit 逐跳建立路径、后续微片紧跟占用通道从而只需很小的片上缓冲;每个路由器对每个输入端口维护若干虚通道 FIFO,微片依次经过缓冲写入、路由计算(XY 维序先 X 后 Y)、虚通道分配、交叉开关分配(仲裁器选通)和交叉开关/链路传输五级流水(常合并到 2~3 级);虚通道用多组共享物理链路的独立队列既解了队头阻塞,又能通过「只许从 VC0 转到 VC1」的通道依赖规则配合 XY 路由切断循环等待以数学上避免死锁,必要时用受限转弯算法换取负载均衡;流控不允许丢包而靠下游空槽信用或 valid-ready 反压保证可靠投递,跨频率域在打包/拆包的网络接口用异步 FIFO 做 CDC;其代价是多跳延迟、路由器面积功耗和打包开销,设计需联合权衡拓扑、流水级数、VC 数量深度、微片宽度、路由算法与 QoS,本质上是仲裁器、FIFO、交叉开关和 CDC 构成的分布式互连系统。