当前位置: 首页 > news >正文

【IC】NoC设计入门 -- router模块

“零件”全部制造完毕,我们终于来到了“总装车间”!

这是最激动人心的一步。我们将把我们亲手制造的4种“砖块”:

  1. simple_fifo (停车场)
  2. routing_logic (GPS)
  3. arbiter_4_to_1 (交警)
  4. crossbar_5x5 (立交桥)

组装成一个完整的、可以工作的**router (路由器) 模块**。

这是一个“结构化”的Verilog设计过程。我们不会再写新的“功能”,我们只做“连接”。


1. 📐 路由器的“总蓝图” (Top-Level Interface)

首先,我们要为这个“总装”好的router模块设计一个“对外接口”。当我们要用它来搭建“城市路网 (Mesh)”时,我们只关心这个接口。

我们采用行业标准的**“Valid / Ready”握手协议**来进行“流控”。

  • 发送方 (e.g., router_A):
    • o_flit (Flit数据)
    • o_valid (置1,表示“嘿,我的数据有效!”)
  • 接收方 (e.g., router_B):
    • o_ready (置1,表示“嘿,我没满,我准备好了!”)
  • 传输条件: 只有当 o_valido_ready 同时为1时,Flit才算真正传输成功。
/** 模块: 5x5 路由器 (Router) - 总装模块* 功能: 将 FIFO, RC, Arbiter, Crossbar 组装起来* 握手: Valid/Ready (Valid-Ready Handshake)*/
module router #(parameter FLIT_WIDTH  = 32, // Flit 位宽parameter FIFO_DEPTH  = 8,  // 内部FIFO深度parameter COORD_WIDTH = 4   // 坐标位宽 (用于XY路由)
)(input clk,input rst_n,// 路由器的“身份”坐标 (在Mesh中实例化时传入)input [COORD_WIDTH-1:0] i_my_x,input [COORD_WIDTH-1:0] i_my_y,// ---- 5个输入通道 (N, S, E, W, L) ----input [FLIT_WIDTH-1:0] i_flit_N,  input i_valid_N,  output o_ready_N,input [FLIT_WIDTH-1:0] i_flit_S,  input i_valid_S,  output o_ready_S,input [FLIT_WIDTH-1:0] i_flit_E,  input i_valid_E,  output o_ready_E,input [FLIT_WIDTH-1:0] i_flit_W,  input i_valid_W,  output o_ready_W,input [FLIT_WIDTH-1:0] i_flit_L,  input i_valid_L,  output o_ready_L,// ---- 5个输出通道 (N, S, E, W, L) ----output [FLIT_WIDTH-1:0] o_flit_N,  output o_valid_N,  input i_ready_N,output [FLIT_WIDTH-1:0] o_flit_S,  output o_valid_S,  input i_ready_S,output [FLIT_WIDTH-1:0] o_flit_E,  output o_valid_E,  input i_ready_E,output [FLIT_WIDTH-1:0] o_flit_W,  output o_valid_W,  input i_ready_W,output [FLIT_WIDTH-1:0] o_flit_L,  output o_valid_L,  input i_ready_L
);// TODO: 1. 实例化所有 16 个子模块// TODO: 2. 用 "wire" 连接它们endmodule

2. 🔩 “总装”步骤 (Internal Wiring)

我们将在router模块内部,定义大量的wire(电线),来连接我们的16个“零件”。

**(为了代码的可读性,我将只展示“北输入 (N)”和“东输出 (E)”的相关逻辑,其他4个方向的逻辑是完全一样的,只是复制粘贴和修改端口名。) **

步骤 2.0:定义Flit格式

“GPS”(RC)需要从Flit中“读”出目的地。我们必须先定义一个Flit格式

  • 假设: 我们的 FLIT_WIDTH=32。我们规定:
    • [31:24] (8 bits): 目的地 Y 坐标 (Dest Y)
    • [23:16] (8 bits): 目的地 X 坐标 (Dest X)
    • [15:0] (16 bits): 真实数据 (Payload)
    • (注意:我们暂时简化,不区分Head/Body/Tail Flit,假设所有Flit都带地址)
// ---- 内部“电线” (Wires) ----// 1. "停车场" (FIFO) 的输出
wire [FLIT_WIDTH-1:0] w_fifo_data_N; // 北FIFO的队首Flit
wire                  w_fifo_empty_N; // 北FIFO是“空”吗?
wire                  w_fifo_full_N;  // 北FIFO是“满”吗?
wire                  w_fifo_read_en_N; // "北FIFO,你可以出队了!"// ... (S, E, W, L 类似)// 2. "GPS" (RC) 的输出
wire w_rc_req_N_to_N, w_rc_req_N_to_S, w_rc_req_N_to_E, w_rc_req_N_to_W, w_rc_req_N_to_L;
// ... (S, E, W, L 类似)// 3. "交警" (Arbiter) 的输出
wire [3:0] w_gnt_for_N; // 授权给“北出口”的4个请求
wire [3:0] w_gnt_for_S;
wire [3:0] w_gnt_for_E;
wire [3:0] w_gnt_for_W;
wire [3:0] w_gnt_for_L;// 4. "立交桥" (Crossbar) 的输出
wire [FLIT_WIDTH-1:0] w_xbar_data_N; // "北出口"的最终Flit
// ... (S, E, W, L 类似)
步骤 2.1:“放置”所有16个零件 (Instantiation)
// ---- 1. 实例化 5 个“停车场” (FIFOs) ----
simple_fifo #(.FLIT_WIDTH(FLIT_WIDTH),.FIFO_DEPTH(FIFO_DEPTH)
) fifo_N (.clk        (clk),.rst_n      (rst_n),.i_write_en (i_valid_N && o_ready_N), // 仅当"有效"且"我准备好"时写入.i_data     (i_flit_N),.o_full     (w_fifo_full_N),.i_read_en  (w_fifo_read_en_N), // "何时读" 是最复杂的控制信号!.o_data     (w_fifo_data_N),.o_empty    (w_fifo_empty_N)
);
// ... (实例化 fifo_S, fifo_E, fifo_W, fifo_L)// ---- 2. 实例化 5 个“GPS” (Routing Logics) ----
routing_logic #(.COORD_WIDTH(COORD_WIDTH)
) rc_N (.i_dest_x   (w_fifo_data_N[23:16]), // 从FIFO队首Flit中“读”地址.i_dest_y   (w_fifo_data_N[31:24]),.i_curr_x   (i_my_x), // 传入“我”的身份.i_curr_y   (i_my_y),.o_req_north(w_rc_req_N_to_N),.o_req_south(w_rc_req_N_to_S),.o_req_east (w_rc_req_N_to_E),.o_req_west (w_rc_req_N_to_W),.o_req_local(w_rc_req_N_to_L)
);
// ... (实例化 rc_S, rc_E, rc_W, rc_L)// ---- 3. 实例化 5 个“交警” (Arbiters) ----
// 以“东出口”的交警为例。
// 它需要处理来自 N, S, W, L 的请求 (XY路由中, E->E 不会发生)
arbiter_4_to_1 arb_E (.clk        (clk),.rst_n      (rst_n),// [0]=N, [1]=S, [2]=W, [3]=L.i_req      ({ (w_rc_req_L_to_E && !w_fifo_empty_L),(w_rc_req_W_to_E && !w_fifo_empty_W),(w_rc_req_S_to_E && !w_fifo_empty_S),(w_rc_req_N_to_E && !w_fifo_empty_N) }),.o_gnt      (w_gnt_for_E)
);
// ... (实例化 arb_N, arb_S, arb_W, arb_L)// ---- 4. 实例化 1 个“立交桥” (Crossbar) ----
crossbar_5x5 #(.FLIT_WIDTH(FLIT_WIDTH)
) xbar (// 数据输入.i_data_north(w_fifo_data_N),.i_data_south(w_fifo_data_S),.i_data_east (w_fifo_data_E),.i_data_west (w_fifo_data_W),.i_data_local(w_fifo_data_L),// 控制输入.i_gnt_for_north(w_gnt_for_N),.i_gnt_for_south(w_gnt_for_S),.i_gnt_for_east (w_gnt_for_E),.i_gnt_for_west (w_gnt_for_W),.i_gnt_for_local(w_gnt_for_L),// 数据输出.o_data_north(w_xbar_data_N),.o_data_south(w_xbar_data_S),.o_data_east (w_xbar_data_E),.o_data_west (w_xbar_data_W),.o_data_local(w_xbar_data_L)
);
步骤 2.2:“连接”最关键的控制线 (Control Path)

这是“总装”的灵魂。

// ---- 1. 输入握手 (Input Handshake) ----
// 我“准备好” = 我的“停车场”没满
assign o_ready_N = !w_fifo_full_N;
assign o_ready_S = !w_fifo_full_S;
// ... (E, W, L 类似)// ---- 2. “交警”请求逻辑 (Arbiter Request) ----
// (这步已在上面 arb_E 的实例化 `i_req` 中完成)
// 关键点:`i_req` 必须是 (GPS想去) AND (停车场不为空)
// .i_req({..., (w_rc_req_N_to_E && !w_fifo_empty_N) })// ---- 3. FIFO“出队”逻辑 (FIFO Read Enable) - 最复杂! ----
// "北FIFO" (fifo_N) 什么时候可以“出队” (read_en = 1) ?
// 答:当“北”请求的 *任何一个* 出口 (N,S,E,W,L) 
//     “交警” (Arbiter) 批准了它,
//     并且 那个出口的“下游” (i_ready) 也准备好了!
assign w_fifo_read_en_N = (w_gnt_for_N[?] && i_ready_N) |  // 假设arb_N授权了N (gnt[?])(w_gnt_for_S[?] && i_ready_S) |  // 假设arb_S授权了N(w_gnt_for_E[0] && i_ready_E) |  // (根据 arb_E 实例, [0]是N)(w_gnt_for_W[?] && i_ready_W) |(w_gnt_for_L[?] && i_ready_L);
// ... (fifo_S, E, W, L 的 read_en 逻辑类似)// ---- 4. 输出握手 (Output Handshake) ----// "东出口" (o_flit_E) 的 Flit
assign o_flit_E = w_xbar_data_E; // 数据来自“立交桥”// "东出口" 什么时候“有效” (o_valid_E = 1) ?
// 答:当“东出口交警” (arb_E) 批准了 *任何一个* 请求者。
// (w_gnt_for_E 是 [L,W,S,N])
assign o_valid_E = (w_gnt_for_E[0] | w_gnt_for_E[1] | w_gnt_for_E[2] | w_gnt_for_E[3]);
// (更简洁的Verilog: `assign o_valid_E = |w_gnt_for_E;` )// ... (o_flit_N/S/W/L 和 o_valid_N/S/W/L 逻辑类似)

🏁 最终章:我们做到了!

恭喜!你已经完成了第三阶段:动手实践全部内容。

我们从零开始,一块一块地“制造”了零件,最后成功地把它们“组装”成了一个功能完整的、采用“Valid/Ready”握手协议的、基于“XY路由”的NoC 路由器

你现在手中拿到的这个 router.v 模块,就是NoC(片上网络)的**“原子”**。

你已经完全掌握了从“理论”到“RTL实践”的全过程

接下来呢?

你的“工具箱”已经满了。现在的你可以:

  1. 开始“第四阶段”:

    • 目标一 (验证): 为我们刚写的 router.v 编写一个Testbench!这是最重要的一步。你需要写一个“测试台”,去“模拟”5个输入端口,发送上百个Flits,检查 o_flit 是否在正确的时间、出现在了正确的出口。
    • 目标二 (搭建Mesh): 在一个“顶层文件”里,实例化 16 个我们这个 router.v(比如 router r_0_0 (...), router r_0_1 (...)),然后把它们的o_flit_E连接到i_flit_W,把o_flit_N连接到i_flit_S
      • 你就亲手搭建出了一个 4x4 的 Mesh NoC!
    • 目标三 (NI): 尝试设计我们理论课上讲的 NI(网络接口),它负责把AXI总线“翻译”成我们这个Flit格式。
  2. 回到“第五阶段”(进阶理论):

    • 你现在可以去挑战我们之前跳过的“高级主题”了,比如**“虚拟通道 (VC)”**。
    • (提示:实现VC,就是把 simple_fifo 换成 virtual_channel_fifo,然后把 arbiter 拆成两级:VC仲裁 + Switch仲裁)。
http://www.dtcms.com/a/570280.html

相关文章:

  • 网站做项目网络营销方案策划书
  • 外贸功能网站建设电脑课程培训零基础
  • 网站建设策划公司凡科建站怎样建站中站
  • 侯捷STL标准库和泛型编程
  • BigDecimal是怎么比较大小的
  • 【MCU控制 初级手札】1.6 电解质 【化学基础】
  • Paimon 文件索引深度解析:以 Bitmap 索引为例
  • wap网站cms金乡网站建设多少钱
  • 能浏览的海外网站网页制作三剑客不包括
  • Python自己处理不了异步结束线程
  • 双指针。。。。。
  • 北京有多少家网站吉县网站建设
  • 教案怎么写模板抖音seo搜索引擎优化
  • 算法题(254):灾后重建
  • 理解全连接层:深度学习中的基础构建块
  • vs网站开发教程厦门模板建站
  • c sql网站开发wordpress搜索无效
  • 如何防止 iOS 应用资源文件被替换 工程化防护与多工具组合实战
  • 网站在线支付接口网络推广经验分享
  • 18-Python 操作 Redis 实战指南:redis-py 客户端全解析与场景落地
  • 【Android 性能分析】延伸阅读:关于异常捕获
  • 地方社区网站 备案十堰网站建设联系电话
  • 赣榆区城乡建设局网站网站优化工作
  • Python每日一练---第五天:轮转数组
  • 建设银行档案管理网站wordpress divi布局
  • p2p网站审批营销网站建设培训
  • 视频融合平台EasyCVR:打造智慧酒店一体化安防体系,筑牢安全管理防线
  • 能领免做卡的网站html5响应式设计公司网站模板整站html源码下载
  • 从需求到上线:体育比分系统完整开发流程详解
  • 微信二维码网站制作网站开发建设推荐