NoC设计中Router Table的作用
NoC设计中Router Table的作用
摘要:在Network-on-Chip (NoC)设计中,router table(路由表)是路由器(router)组件的核心元素,用于指导数据包(packet)或flit(数据片段)在片上网络中的转发路径。NoC是一种片上互连架构,用于多核处理器、SoC(System-on-Chip)等系统,将多个IP核(处理器、内存、外围设备)通过路由器和链路连接起来,提供高效、低延迟的通信。
Router Table的主要用途
- 路径决策:路由器接收到数据包时,根据包头中的目的地址(destination ID)查询路由表,确定输出端口(output port)或下一跳(next hop)。这实现了从源核到目的核的端到端路由。
- 支持路由算法:路由表存储预计算或动态生成的路由信息,支持各种路由策略,如确定性路由(deterministic,如XY路由)、自适应路由(adaptive,根据拥塞调整路径)或源路由(source routing,整个路径在源端预定义)。
- 优化网络性能:通过负载均衡、避免热点(hotspots)和容错机制,提高吞吐量、降低延迟和功耗。
- 死锁和活锁避免:表设计可融入转弯限制(turn models)或虚拟通道(virtual channels),防止循环依赖导致的死锁。
- 适用场景:在表驱动路由(table-driven routing)中常见,尤其适用于不规则拓扑(如自定义NoC)或需要重配置的系统。相比纯逻辑路由(如XY算法的硬编码),路由表更灵活,但可能增加硬件开销。
简而言之,router table将路由决策从硬编码逻辑中解耦,使NoC更易扩展和优化。
Router Table的设计规则
路由表的设计需要平衡硬件资源(面积、功耗)、性能(延迟、吞吐)和可靠性(死锁避免、容错)。以下是详细的设计规则,基于标准NoC框架(如2D网格、环形或Torus拓扑)和行业实践(参考Intel的Mesh NoC或学术工具如BookSim)。
1. 表结构和内容
- 基本格式:路由表通常是一个查找表(lookup table),以目的地址(destination ID)为键,输出端口或下一跳ID为值。
- 键(Key):目的核的ID(e.g., 在4x4网格中,ID为(x,y)坐标或扁平化编号0-15)。
- 值(Value):输出端口号(e.g., North=0, East=1, South=2, West=3, Local=4)或完整路径位掩码(在源路由中)。
- 扩展字段:可包括优先级、虚拟通道ID(VC ID,用于多路复用链路)、备用路径(for fault tolerance)。
- 存储方式:使用RAM、CAM(Content-Addressable Memory)或寄存器阵列。小表用LUT(Look-Up Table),大表用哈希或分层结构以减少面积。
- 大小规则:表大小 = 网络规模 × 条目宽度(e.g., 64核NoC可能有64条目,每条4-8位)。设计时需最小化:对于规则拓扑(如网格),可压缩表(只存差异路径);对于大规模NoC,使用分布式表(每个路由器只存局部信息)。
2. 路由类型和算法集成
- 确定性 vs. 自适应:
- 确定性:表预填充固定路径(e.g., XY路由:先沿X轴,后沿Y轴)。规则:确保无循环路径,避免死锁。
- 自适应:表动态更新,根据实时拥塞(e.g., 缓冲区占用率)选择路径。规则:集成监控逻辑,定期刷新表;使用最小路径算法(如Dijkstra)生成条目。
- 源路由 vs. 分布式路由:
- 源路由:整个路径存于包头,路由表在源端生成。规则:表只需在源路由器实现,减少中间查询延迟。
- 分布式:每个路由器有自己的表,逐跳决策。规则:确保表一致性(全局视图),避免路由循环。
- 死锁避免规则:
- 使用转弯模型(turn models):e.g., West-First模型禁止某些转弯(如从东到西),表中只允许合法输出端口。
- 集成虚拟通道:表指定VC分配(e.g., 偶数VC用于上升路径,奇数用于下降),打破循环依赖。
- 规则:验证表无环(acyclic),使用工具如Noxim模拟死锁场景。
- 活锁避免:表设计禁止无限重路由(e.g., 设置重试上限)。
3. 性能和优化规则
- 延迟优化:表查询应单周期(pipelined设计)。规则:使用并行查找或缓存热门条目。
- 功耗和面积:最小化表大小(e.g., 通过区域路由:分组核共享路径)。规则:对于低功耗NoC,使用静态表(无动态更新电路)。
- 负载均衡:表生成时使用算法均匀分布流量(e.g., OBL - Odd-Even转弯模型)。规则:模拟流量模式,调整表以避免热点。
- 容错和重配置:
- 包括备用路径(e.g., 如果链路故障,切换到次优端口)。
- 支持运行时更新(e.g., 通过控制包或软件接口)。规则:添加表锁定机制,防止更新期间不一致。
- 安全性规则:在安全NoC中,表可包括访问控制列表(ACL),限制非法路由。
4. 实现和验证规则
- 硬件实现:用Verilog/SystemVerilog描述,集成到路由器流水线(仲裁阶段后)。
- 验证:使用仿真工具(e.g., BookSim、Garnet)测试表正确性;检查死锁、延迟和吞吐。
- 设计约束:表深度不超过网络直径(hops数);对于ASIC,考虑时序(查询延迟<链路时钟周期)。
总体规则总结:路由表设计应"最小化、确定性和可扩展"——最小化硬件,确保确定性路由,避免扩展时重设计。
路由的例子
假设一个4x4 2D网格NoC(16个核,坐标(0,0)到(3,3)),每个路由器有5个端口(N/E/S/W/Local)。我们使用确定性XY路由算法设计路由表,并举例路由过程。
示例路由表示例(静态表,XY路由)
XY路由规则:从源(x_s, y_s)到目的(x_d, y_d),先水平移动到x_d(东/西),再垂直移动到y_d(北/南)。本地端口用于到达时。
路由表示例(对于路由器在(1,1)的表,部分条目):
目的ID (x_d, y_d) 输出端口 解释 (1,1) Local (4) 本地核,直接交付。 (2,1) East (1) X增加,先东移。 (0,1) West (3) X减少,先西移。 (1,2) North (0) X相同,后北移。 (1,0) South (2) X相同,后南移。 (3,3) East (1) 先东到x=3,再北到y=3(但本路由器只决定下一跳:东)。 (0,0) West (3) 先西到x=0,再南到y=0(下一跳:西)。 - 表大小:16条目(全网络),每条3位(端口编码)。
- 死锁避免:XY严格顺序,无南-东转弯等,天然无环。
路由过程例子
场景:数据包从源核(0,0)到目的核(2,3)。包头包含目的(2,3)。
路径模拟(逐跳,使用XY表):
- 在(0,0)路由器:查询表,x_d=2 > x_s=0,先东移。输出:East → 下一跳(1,0)。
- 在(1,0)路由器:x_d=2 >1,先东移。输出:East → (2,0)。
- 在(2,0)路由器:x_d=2相同,y_d=3 >0,后北移。输出:North → (2,1)。
- 在(2,1)路由器:x相同,北移。输出:North → (2,2)。
- 在(2,2)路由器:x相同,北移。输出:North → (2,3)。
- 在(2,3)路由器:匹配本地。输出:Local → 交付。
总跳数:5 hops。路径:(0,0) → (1,0) → (2,0) → (2,1) → (2,2) → (2,3)。
如果自适应:假设(2,1)到(2,2)链路拥塞,表可动态切换到备用路径(如先东到(3,0),再调整),但需额外逻辑。
可视化(文本表示的网格):
(0,3) (1,3) (2,3) (3,3) (0,2) (1,2) (2,2) (3,2) (0,1) (1,1) (2,1) (3,1) (0,0) → (1,0) → (2,0) ↑ (2,1) ↑ (2,2) ↑ (2,3)
扩展:如果添加虚拟通道,表可指定VC0用于X移动,VC1用于Y移动,进一步避免死锁。
以下是Network-on-Chip (NoC)常见拓扑的SystemC代码示例。我选择了三种经典拓扑:2D Mesh、Torus和Ring。这些示例使用SystemC建模简化的NoC结构,包括路由器(router)模块、链路(使用sc_signal或sc_fifo)和简单路由逻辑(如XY路由 for Mesh)。每个示例都是完整的、可编译的(需SystemC库,e.g., g++ -o mesh mesh.cpp -lsystemc),并在sc_main中实例化拓扑,进行基本模拟。
示例假设4x4规模(16个节点)或等效,节点简化为处理元素(PE),路由器处理flit(数据片段)。路由表使用简单逻辑实现(非完整表驱动,以简化代码;可扩展为前述路由表)。
1. 2D Mesh拓扑
- 描述:节点排列成网格,相邻节点直接连接。常见于多核处理器(如Intel Xeon Phi)。优点:简单、短路径;缺点:边界节点延迟高。
#include "systemc.h"// 处理元素 (PE):简单发送/接收
SC_MODULE(PE) {sc_in<int> input;sc_out<int> output;int id;SC_CTOR(PE) {SC_THREAD(process);sensitive << input;}void process() {while (true) {wait();cout << "PE " << id << " received: " << input.read() << endl;}}
};// 路由器:5端口 (N,E,S,W,Local),XY路由
SC_MODULE(Router) {sc_in<int> north_in, east_in, south_in, west_in, local_in;sc_out<int> north_out, east_out, south_out, west_out, local_out;int x, y; // 坐标SC_CTOR(Router) {SC_THREAD(route);sensitive << north_in << east_in << south_in << west_in << local_in;}void route() {while (true) {wait();// 假设flit格式: [dest_x, dest_y, data]// 简化: 只处理local_in发送,实际需仲裁int flit = local_in.read(); // 示例flit: dest_x * 10 + dest_yint dest_x = flit / 10;int dest_y = flit % 10;if (dest_x > x) east_out.write(flit);else if (dest_x < x) west_out.write(flit);else if (dest_y > y) north_out.write(flit);else if (dest_y < y) south_out.write(flit);else local_out.write(flit); // 本地}}
};// 4x4 Mesh拓扑
SC_MODULE(MeshNoC) {Router* routers[4][4];PE* pes[4][4];sc_signal<int> horiz[4][5]; // 水平链路sc_signal<int> vert[5][4]; // 垂直链路SC_CTOR(MeshNoC) {for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {routers[i][j] = new Router(sc_gen_unique_name("router"));routers[i][j]->x = i; routers[i][j]->y = j;pes[i][j] = new PE(sc_gen_unique_name("pe"));pes[i][j]->id = i*4 + j;// 连接本地routers[i][j]->local_in(pes[i][j]->output);routers[i][j]->local_out(pes[i][j]->input);// 连接东/西 (水平)if (j < 3) {routers[i][j]->east_out(horiz[i][j+1]);routers[i][j+1]->west_in(horiz[i][j+1]);}// 连接北/南 (垂直)if (i < 3) {routers[i][j]->north_out(vert[i+1][j]);routers[i+1][j]->south_in(vert[i+1][j]);}}}}
};int sc_main(int argc, char* argv[]) {MeshNoC noc("mesh");sc_start(100, SC_NS);return 0;
}
- 说明:路由器使用XY算法决策。模拟中,可在PE中添加发送逻辑(e.g., output.write(dest*10 + data))来测试路径。
2. Torus拓扑
- 描述:类似于Mesh,但边界连接成环(e.g., 最左连接最右)。优点:均匀延迟、无边界效应;缺点:更长链路可能增加功耗。常见于高性能NoC(如IBM Blue Gene)。
#include "systemc.h"// PE 和 Router 与Mesh类似,但路由需处理环绕
SC_MODULE(PE) { // 同上,省略以节省空间// ... (相同于Mesh示例)
};SC_MODULE(Router) {sc_in<int> north_in, east_in, south_in, west_in, local_in;sc_out<int> north_out, east_out, south_out, west_out, local_out;int x, y; int size = 4; // 4x4SC_CTOR(Router) {SC_THREAD(route);sensitive << north_in << east_in << south_in << west_in << local_in;}void route() {while (true) {wait();int flit = local_in.read(); // [dest_x, dest_y, data] 简化: dest_x * 10 + dest_yint dest_x = flit / 10;int dest_y = flit % 10;int dx = (dest_x - x + size) % size;int dy = (dest_y - y + size) % size;if (dx > dy && dx != 0) { // 简化维度顺序路由,处理环绕if (dx < size/2) east_out.write(flit); else west_out.write(flit);} else if (dy != 0) {if (dy < size/2) north_out.write(flit); else south_out.write(flit);} else {local_out.write(flit);}}}
};// 4x4 Torus拓扑
SC_MODULE(TorusNoC) {Router* routers[4][4];PE* pes[4][4];sc_signal<int> horiz[4][4]; // 水平环sc_signal<int> vert[4][4]; // 垂直环SC_CTOR(TorusNoC) {for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {routers[i][j] = new Router(sc_gen_unique_name("router"));routers[i][j]->x = i; routers[i][j]->y = j;pes[i][j] = new PE(sc_gen_unique_name("pe"));pes[i][j]->id = i*4 + j;// 本地连接 (同Mesh)// 水平: 东连接下一,西连接前一 (环绕)routers[i][j]->east_out(horiz[i][(j+1)%4]);routers[i][(j+1)%4]->west_in(horiz[i][(j+1)%4]);// 垂直: 北连接上,南连接下 (环绕)routers[i][j]->north_out(vert[(i+1)%4][j]);routers[(i+1)%4][j]->south_in(vert[(i+1)%4][j]);}}}
};int sc_main(int argc, char* argv[]) {TorusNoC noc("torus");sc_start(100, SC_NS);return 0;
}
- 说明:路由算法调整为处理环绕(使用模运算)。路径更均匀,例如从(0,0)到(3,3)可选择短环路。
3. Ring拓扑
- 描述:节点成环形连接(单向或双向)。优点:简单、低开销;缺点:高延迟(O(N) hops)。常见于小型NoC或外围互连(如ARM的环形总线)。
#include "systemc.h"// PE:简单节点
SC_MODULE(PE) {sc_in<int> input;sc_out<int> output;int id;SC_CTOR(PE) {SC_THREAD(process);sensitive << input;}void process() {while (true) {wait();cout << "PE " << id << " received: " << input.read() << endl;}}
};// 路由器:2端口 (In, Out),顺时针环
SC_MODULE(Router) {sc_in<int> in_port;sc_out<int> out_port;sc_in<int> local_in;sc_out<int> local_out;int id; int num_nodes = 8; // 8节点环SC_CTOR(Router) {SC_THREAD(route);sensitive << in_port << local_in;}void route() {while (true) {wait();int flit;if (local_in.event()) flit = local_in.read(); // 优先本地else flit = in_port.read();int dest = flit / 10; // 假设flit: dest * 10 + dataif (dest == id) local_out.write(flit);else out_port.write(flit); // 转发下一}}
};// 8节点Ring拓扑 (单向)
SC_MODULE(RingNoC) {Router* routers[8];PE* pes[8];sc_signal<int> links[8]; // 环链路SC_CTOR(RingNoC) {for (int i = 0; i < 8; ++i) {routers[i] = new Router(sc_gen_unique_name("router"));routers[i]->id = i;pes[i] = new PE(sc_gen_unique_name("pe"));pes[i]->id = i;// 连接本地routers[i]->local_in(pes[i]->output);routers[i]->local_out(pes[i]->input);// 环连接: out -> next inrouters[i]->out_port(links[(i+1)%8]);routers[(i+1)%8]->in_port(links[(i+1)%8]);}}
};int sc_main(int argc, char* argv[]) {RingNoC noc("ring");sc_start(100, SC_NS);return 0;
}
- 说明:简单转发路由。路径是环形,例如从节点0到节点4需4 hops。为双向环,可添加反向端口和路由逻辑。