【IC】NoC设计入门 --交换矩阵

你完全说对了!这确实是所有组件中**最"直观"**的一个。

它就是 "交换矩阵" (Crossbar) ,我们"十字路口"的**"立交桥""扳道岔"**系统。


1. 💡 "交换矩阵" (Crossbar) 的"顿悟"时刻

它听起来很"矩阵",很复杂,但它的核心功能非常简单:

一个 Crossbar 就是一堆"多路选择器" (Multiplexer, MUX) 的集合。

我们来思考一下。在我们的5x5路由器中,我们有5个输出端口(东、南、西、北、本地)。

让我们只看**"东输出" (East Output)** 这个端口:

  • 问题: 它的"数据"可以来自哪里?

  • 答案: 它可以来自"北输入"、"南输入"、"西输入"或"本地输入"。(在我们的XY路由中,它不会来自"东输入")。

  • 结论: "东输出"端口需要一个 "4选1"的MUX

  • MUX的数据输入: i_data_north, i_data_south, i_data_west, i_data_local

  • MUX的"选择"信号 (sel): 这个MUX由谁来"控制"?

  • 答案: 由我们刚刚设计的**"东出口仲裁器" (arbiter_for_east)** 来控制!

arbiter_for_easto_gnt (授权) 输出信号,就是这个MUX的"选择"信号!

因此,一个5x5的Crossbar,本质上就是5个并排的MUX:

  1. 一个 "4选1 MUX" 来决定**"东输出"**的数据。
  2. 一个 "4选1 MUX" 来决定**"北输出"**的数据。
  3. 一个 "4选1 MUX" 来决定**"南输出"**的数据。
  4. ...以此类推。

2. 🔌 模块"蓝图" (Module Interface)

这是一个纯组合逻辑 模块。它不需要 clkrst_n。它就是一堆"开关"和"电线","授权"信号一来,它就"立刻"接通。

verilog 复制代码
/*
 * 模块:5x5 交换矩阵 (Crossbar)
 * 功能:基于仲裁器的"授权"信号,将输入数据"切换"到正确的输出端口
 * 类型:纯组合逻辑 (Combinational)
 */
module crossbar_5x5 #(
    parameter FLIT_WIDTH = 32 // 必须和 FIFO 的 FLIT_WIDTH 保持一致
)(
    // ---- 5个"数据"输入 (来自5个Input Port的FIFO输出) ----
    input [FLIT_WIDTH-1:0] i_data_north,
    input [FLIT_WIDTH-1:0] i_data_south,
    input [FLIT_WIDTH-1:0] i_data_east,
    input [FLIT_WIDTH-1:0] i_data_west,
    input [FLIT_WIDTH-1:0] i_data_local,

    // ---- 5组"控制"输入 (来自5个Arbiter的"授权"输出) ----
    // 注意:每个都是 4-bit, 对应 4 个可能的请求者
    input [3:0] i_gnt_for_north, // 授权给"北出口"的One-Hot向量
    input [3:0] i_gnt_for_south,
    input [3:0] i_gnt_for_east,
    input [3:0] i_gnt_for_west,
    input [3:0] i_gnt_for_local,

    // ---- 5个"数据"输出 (去往5个Output Port) ----
    output [FLIT_WIDTH-1:0] o_data_north,
    output [FLIT_WIDTH-1:0] o_data_south,
    output [FLIT_WIDTH-1:0] o_data_east,
    output [FLIT_WIDTH-1:0] o_data_west,
    output [FLIT_WIDTH-1:0] o_data_local
);

    // TODO: 实现 5 个并行的 One-Hot MUX
    
endmodule

3. 🚦 核心逻辑实现 (One-Hot MUX)

我们如何用"仲裁器"的One-Hot (独热) 输出 (o_gnt) 来实现一个MUX?

  • arbiter_for_east (东出口仲裁器) 的 i_gnt_for_east 是一个4位向量,我们假设它的"请求者"顺序是:[0]=North, [1]=South, [2]=West, [3]=Local
  • 如果它授权给"North",i_gnt_for_east 将是 4'b0001
  • 如果它授权给"West",i_gnt_for_east 将是 4'b0100
  • 如果它谁也没授权,i_gnt_for_east 将是 4'b0000

我们可以用一种非常"硬件化"、非常高效的方式来实现这个MUX:

verilog 复制代码
/*
 * 模块:5x5 交换矩阵 (Crossbar)
 * ... (接口同上) ...
 */
module crossbar_5x5 #(
    parameter FLIT_WIDTH = 32
)(
    // ... (输入/输出接口同上) ...

    // ---------------------------------------------
    // 核心逻辑:5个并行的 MUX
    // ---------------------------------------------

    // -- 1. "东" 出口的 MUX --
    // "东"出口可以被 N, S, W, L 请求
    // 假设 i_gnt_for_east[0] = Grant to North
    //       i_gnt_for_east[1] = Grant to South
    //       i_gnt_for_east[2] = Grant to West
    //       i_gnt_for_east[3] = Grant to Local
    assign o_data_east = 
        (i_data_north & {FLIT_WIDTH{i_gnt_for_east[0]}}) | // "与": 如果gnt[0]是0, 结果是0
        (i_data_south & {FLIT_WIDTH{i_gnt_for_east[1]}}) | // "或": 因为是One-Hot,
        (i_data_west  & {FLIT_WIDTH{i_gnt_for_east[2]}}) | // 最多只有1项不是0
        (i_data_local & {FLIT_WIDTH{i_gnt_for_east[3]}});

    // -- 2. "北" 出口的 MUX --
    // "北"出口可以被 S, E, W, L 请求
    // 假设 i_gnt_for_north[0] = Grant to South
    //       i_gnt_for_north[1] = Grant to East
    //       i_gnt_for_north[2] = Grant to West
    //       i_gnt_for_north[3] = Grant to Local
    assign o_data_north = 
        (i_data_south & {FLIT_WIDTH{i_gnt_for_north[0]}}) |
        (i_data_east  & {FLIT_WIDTH{i_gnt_for_north[1]}}) |
        (i_data_west  & {FLIT_WIDTH{i_gnt_for_north[2]}}) |
        (i_data_local & {FLIT_WIDTH{i_gnt_for_north[3]}});

    // -- 3. "南" 出口的 MUX --
    // "南"出口可以被 N, E, W, L 请求
    assign o_data_south = 
        (i_data_north & {FLIT_WIDTH{i_gnt_for_south[0]}}) |
        (i_data_east  & {FLIT_WIDTH{i_gnt_for_south[1]}}) |
        (i_data_west  & {FLIT_WIDTH{i_gnt_for_south[2]}}) |
        (i_data_local & {FLIT_WIDTH{i_gnt_for_south[3]}});

    // -- 4. "西" 出口的 MUX --
    // "西"出口可以被 N, S, E, L 请求
    assign o_data_west = 
        (i_data_north & {FLIT_WIDTH{i_gnt_for_west[0]}}) |
        (i_data_south & {FLIT_WIDTH{i_gnt_for_west[1]}}) |
        (i_data_east  & {FLIT_WIDTH{i_gnt_for_west[2]}}) |
        (i_data_local & {FLIT_WIDTH{i_gnt_for_west[3]}});

    // -- 5. "本地" 出口的 MUX --
    // "本地"出口可以被 N, S, E, W 请求
    assign o_data_local = 
        (i_data_north & {FLIT_WIDTH{i_gnt_for_local[0]}}) |
        (i_data_south & {FLIT_WIDTH{i_gnt_for_local[1]}}) |
        (i_data_east  & {FLIT_WIDTH{i_gnt_for_local[2]}}) |
        (i_data_west  & {FLIT_WIDTH{i_gnt_for_local[3]}});

endmodule

🔍 代码解析

  1. assign

    • 我们在这里 用了 assign 关键字。这告诉Verilog:"这是一个纯组合逻辑的'连接'"。
    • o_data_east 不是 一个 reg(寄存器),它就是一根"导线" (wire),它的"值"完全由 assign 右侧的计算结果立即决定。
  2. {FLIT_WIDTH{...}} (Verilog复制操作符)

    • 这是实现"One-Hot MUX"的"黑魔法"。
    • i_gnt_for_east[0] 是一个 1-bit 信号 (1'b11'b0)。
    • {FLIT_WIDTH{i_gnt_for_east[0]}} 的意思是:"把这个 1-bit 信号复制 FLIT_WIDTH 次(比如32次)"。
    • 结果:
      • 如果 i_gnt_for_east[0]1'b1 (授权),它就变成 32'b111...1 (即 32'hFFFFFFFF)。
      • 如果 i_gnt_for_east[0]1'b0 (未授权),它就变成 32'b000...0 (即 32'h0)。
  3. & (按位与) 和 | (按位或)

    • (i_data_north & 32'hFFFFFFFF) 的结果是 i_data_north
    • (i_data_north & 32'h00000000) 的结果是 32'h0
    • 因为 i_gnt_for_east 是 One-Hot(最多只有1位是'1'),所以 assign o_data_east = ...| (或) 运算中,最多只有一项是"真实数据",其他所有项都是 32'h0
    • 这就在硬件上完美地实现了一个 MUX!

🏁 恭喜!你完成了所有"砖块"!

我们已经成功地"制造"了建造一个路由器(十字路口)所需的全部4个核心组件

  1. simple_fifo:"停车场"(时序逻辑,存储)
  2. routing_logic:"GPS导航仪"(组合逻辑,计算)
  3. arbiter_4_to_1:"交通警察"(时序逻辑,状态机)
  4. crossbar_5x5:"立交桥"(组合逻辑,连接)

"理论课"和"零件制造课"到此结束。

你已经准备好进入"总装"阶段了。


相关推荐
xier_ran15 小时前
Transformer:Decoder 中,Cross-Attention 所用的 K(Key)和 V(Value)矩阵,是如何从 Encoder 得到的
深度学习·矩阵·transformer
西西弗Sisyphus16 小时前
线性代数 - LU分解(LU-Factorization、LU Decomposition)
线性代数·矩阵·矩阵分解
西西弗Sisyphus1 天前
线性代数 - 矩阵求逆
线性代数·矩阵·矩阵求逆·逆矩阵·单位矩阵
无风听海1 天前
神经网络之正交矩阵
人工智能·神经网络·矩阵
巴里巴气2 天前
第73题 矩阵置零
线性代数·算法·矩阵
短视频矩阵源码定制2 天前
矩阵系统软件哪家好?2025年选型指南与深度品牌剖析
线性代数·矩阵
云茧2 天前
【数学基础(二)】向量、矩阵、行列式与线性变换
线性代数·矩阵
无风听海2 天前
神经网络之PPMI矩阵
人工智能·神经网络·矩阵
短视频矩阵源码定制3 天前
矩阵系统源码推荐:技术架构与功能完备性深度解析
java·人工智能·矩阵·架构