4. NPU架构基础

神经网络加速器(NPU)的本质,是将深度学习算法中高度重复的乘加运算(MAC)与数据搬运操作,映射到专用的硬件流水线上。理解NPU架构,首先需要拆解神经网络的基本计算原语(卷积、全连接、激活、池化),再掌握这些原语在硬件中如何组织成高效的数据流。本章将建立从算法算子到硬件微架构的映射思维,为后续RTL设计打下基础。

NPU 计算模式与数据流映射关系 算法算子层 卷积 (Conv) 全连接 (FC) 激活 (ReLU/Sigmoid) 池化 (Pooling) 归一化/残差 算子映射 硬件微架构层 MAC 计算阵列 脉动阵列 / 乘法器树 权重寄存器堆 (Weight Reg) 输入激活缓冲 (Act Buffer) 部分和累加 (PSUM) 片上 SRAM (NoC/缓存) 外部存储接口 指令解码 / 微码控制 / 地址生成器 (DMA 引擎 / 中断 / 同步) 控制信号 权重/激活 DDR/PCIe 图:算法算子到硬件计算单元、存储与控制逻辑的映射关系

4.1 核心计算模式:从算法到硬件原语

4.1.1 卷积运算的硬件本质

卷积层在NPU中并非直接实现滑窗,而是转化为矩阵乘加操作。对于输出特征图上的每个点,硬件需要完成输入通道维度的乘累加。以3×3卷积、输入通道C=64、输出通道K=64为例,单个输出像素需要 3×3×64 = 576 次乘加。RTL设计的关键在于:数据复用。权重在多个输出位置被复用,输入激活在多个输出通道被复用。因此,硬件架构通常采用权重固定(Weight Stationary)或输出固定(Output Stationary)的数据流策略,以减少片外DRAM访问。

硬件视角的卷积参数:
  • 并行度(Parallelism):通常以 MAC 阵列大小表示,如 16×16、32×32。RTL设计需权衡面积与吞吐率。
  • 位宽(Bit-width):INT8 是主流,但混合精度(INT4/FP16)需要可配置的乘法器。
  • 累加器位宽:为防止溢出,累加器通常比输入位宽宽 4-8 位(如 INT32)。

4.1.2 全连接层与矩阵乘法单元

全连接层本质是矩阵向量乘(GEMV)或矩阵矩阵乘(GEMM)。在NPU中,全连接层通常复用卷积的计算阵列,只是将卷积核大小设为1×1,或者直接调用专用的矩阵乘法单元。RTL实现时,需要关注权重矩阵的加载方式——是逐行加载还是分块加载,这直接影响DMA(Direct Memory Access)控制器的设计复杂度。

4.1.3 激活函数与池化的硬件实现

激活函数(ReLU、Sigmoid、Tanh)在硬件中通常使用查找表(LUT)或分段线性逼近实现。ReLU 只需比较器,而 Sigmoid 需要更复杂的逻辑。池化层(最大池化/平均池化)则相对简单,主要涉及数据选择与加法树。在RTL设计中,这些算子通常被集成在计算阵列的输出端,形成算子融合,减少中间数据的搬移。

计算模式硬件映射单元关键RTL组件数据复用策略
卷积 (3×3)脉动阵列 / 乘法器树MAC单元、移位寄存器、累加器权重广播、输入行缓存
全连接矩阵乘法单元乘加阵列、权重Buffer权重分块加载
激活 (ReLU)ALU / LUT比较器、多路选择器流水线直通
池化 (Max)比较树比较器、寄存器链窗口滑动复用

4.2 NPU数据流架构:从存储到计算的搬运

4.2.1 经典数据流范式

NPU的数据流决定了数据在存储层级间的移动方式。主流架构分为三类:

  1. 权重静止(Weight Stationary):权重从片上SRAM加载后保持不变,输入激活流经计算阵列。适合权重较大的网络,减少权重搬运。
  2. 输入静止(Input Stationary):输入激活驻留在寄存器中,权重流经阵列。适合激活图较小的场景。
  3. 输出静止(Output Stationary):部分和(PSUM)在累加器中保持,直到计算完成。减少了累加器的读写次数,是当前NPU最常用的策略。

在RTL设计中,选择数据流直接影响片上存储(SRAM)的容量划分和NoC(片上网络)的带宽设计。例如,输出静止架构需要较大的累加器阵列,但可以显著降低DRAM的写回压力。

4.2.2 计算单元与存储层次

一个典型的NPU计算单元包含:MAC阵列、激活Buffer、权重Buffer、累加器(PSUM)。数据流路径为:外部DDR → DMA → 片上SRAM(全局Buffer) → 局部Buffer → MAC阵列 → PSUM → 激活/池化 → 写回SRAM。RTL设计者需要关注带宽匹配:如果MAC阵列每周期需要消费 1024 个INT8数据,那么片上SRAM必须提供至少 1024B/cycle 的读取带宽。

设计经验:在编写RTL之前,建议先使用高层次的性能模型(如Python或SystemC)估算所需的MAC利用率。通常,MAC利用率低于 50% 意味着数据搬运存在瓶颈,需要优化循环分块(Tiling)策略或增加双缓冲(Double Buffering)机制。

4.3 案例拆解:一个8×8 MAC阵列的卷积数据流设计

4.3.1 场景与约束

假设我们要设计一个用于边缘设备的NPU子模块,输入为 32×32×16 的特征图,卷积核为 3×3×16×16,输出为 32×32×16。硬件约束:MAC阵列为 8×8(即64个MAC单元),片上SRAM容量为 256KB,时钟频率 500MHz。

4.3.2 初始目标与瓶颈分析

目标:完成一次卷积计算的总周期数最小化。初始方案:直接按输出通道循环,每次计算一个输出通道的所有像素。但这样会导致输入激活从DRAM重复加载 16 次,带宽不足。

4.3.3 优化操作步骤

  1. 循环分块(Tiling):将输出通道分为两组(每组8通道),输入通道也分为两组。这样,每次加载 16×16×8 的输入块和 3×3×8×8 的权重块,可重复利用数据。
  2. 双缓冲(Double Buffering):在DMA搬运下一块数据时,当前块正在计算,隐藏搬运延迟。
  3. 脉动阵列映射:将8×8 MAC阵列设计为脉动结构,权重预加载到每个PE的寄存器中,输入激活从左侧流入,部分和在下方累加。

4.3.4 结果对比与复盘

方案DRAM访问量计算周期数MAC利用率
朴素循环约 1.2 MB约 1,048,576 周期约 25%
分块+双缓冲约 0.4 MB约 524,288 周期约 68%

复盘经验:性能提升的关键在于数据复用。通过分块,输入激活的加载次数从16次降为4次。RTL实现时,需注意地址生成器的复杂度,它需要支持多维循环的地址跳变。

4.4 常见误区与设计总结

4.4.1 误区一:盲目增加MAC阵列规模

增加MAC数量并不总能提升性能。如果片上存储带宽不足,MAC阵列会处于“饥饿”状态。RTL设计应首先确保数据供给速率 ≥ 计算消耗速率。

4.4.2 误区二:忽略累加器溢出

在INT8计算中,16个通道的累加结果可能超过INT16范围。设计时必须使用INT32累加器,并在输出前进行截断或饱和处理。否则,会出现严重的精度损失。

4.4.3 误区三:控制逻辑与数据路径耦合过紧

将地址计算、状态机与MAC阵列的流水线耦合在一起,会导致时序收敛困难。建议采用解耦设计:控制模块通过简单的握手信号(valid/ready)与数据路径通信,数据路径内部采用深度流水线。

RTL实现要点:在编写卷积计算单元的RTL时,务必使用 generate 语句参数化MAC阵列的尺寸。例如:genvar i, j; generate for (i=0; i<8; i=i+1) begin : mac_row ... end endgenerate。这便于后续扩展或缩减阵列规模。

4.4.4 总结复盘

本章节的核心在于理解算法到硬件的映射。在RTL设计实战中,建议遵循以下流程:

  • 第一步:分析网络模型,提取计算量与数据量。
  • 第二步:确定数据流范式(推荐输出静止)。
  • 第三步:划分存储层次,计算所需带宽。
  • 第四步:编写参数化的MAC阵列与地址生成器RTL。
  • 第五步:通过仿真验证MAC利用率与功耗。

下一阶段,我们将深入MAC阵列内部的微架构设计,包括乘法器选择(基于LUT或DSP48)、流水线级数平衡以及低功耗技术(如操作数隔离、门控时钟)。