2. 理解NVDLA架构
任务目标
本案例要求基于NVDLA开源代码仓库,梳理其顶层模块划分,绘制一张准确的架构框图,并说明每个核心模块的功能定位。完成本案例后,读者应能不看文档即可说出NVDLA由哪几个主要硬件单元组成、各自承担什么计算任务,以及数据在模块间的流转关系。
源码获取与目录定位
NVDLA硬件代码位于开源仓库的 hw/ 目录下,使用SystemVerilog编写。获取方式:
git clone https://github.com/nvdla/hw.git
cd hw
# 顶层模块目录结构如下(v1.8.0分支):
# hw/
# ├── vmod/ # 可综合的RTL代码(核心)
# │ └── nvdla/ # 各子模块RTL
# └── vlib/ # 验证与公用库(非核心)
核心RTL位于 vmod/nvdla/,其中每个子目录对应一个硬件加速单元。顶层集成文件为 vmod/nvdla/nvdla_top.v,它例化了所有功能模块并完成全局互联。
顶层模块划分
NVDLA采用可配置的模块化架构,根据配置可裁剪部分单元。默认全功能配置下,顶层包含以下核心模块:
| 模块名 | RTL目录 | 功能定位 |
|---|---|---|
| CSB(Configuration Space Bus)从接口 | csb | 主机通过CSB总线访问寄存器,完成配置与状态读取 |
| CMDQ(Command Queue) | cmds | 解析主机下发的命令描述符,调度各计算单元 |
| BDMA(Bridge DMA) | bdma | 负责数据搬运,在外部存储器和内部SRAM之间传输数据 |
| Convolution Buffer(卷积缓冲) | buf | 片上SRAM,暂存输入激活值、权重和输出数据 |
| MAC(乘累加阵列) | mac | 执行卷积/全连接的核心乘累加运算 |
| CDP(Channel Data Processor) | cdp | 逐通道数据处理:激活函数(ReLU/ReLU6)、LUT查表、池化等 |
| PDP(Planar Data Processor) | pdp | 平面数据处理:最大/最小池化、全局池化、BN融合后处理 |
| Rubik(数据重排单元) | rubik | 执行数据格式转换(如NCHW与NHWC互转)、im2col、通道重排 |
| SDP(Single Data Processor) | sdp | 逐元素运算:偏置加、缩放、批归一化(BN)、激活函数 |
| Retiming(流水线重定时) | retiming | 跨时钟域同步与流水线寄存器插入,保证时序收敛 |
此外,nvdla_top.v 还包含全局时钟/复位管理、中断聚合逻辑以及可配置的总线接口单元(支持AXI/OCP协议,取决于配置)。
架构框图
数据流与模块协作
一次典型卷积推理的硬件流转路径如下:
- 配置阶段:主机通过CSB接口写入寄存器,配置输入尺寸、权重地址、卷积参数等;CMDQ获取命令描述符并解析。
- 数据载入:BDMA根据CMDQ指令,从外部存储读取输入特征图与权重,经总线接口写入卷积缓冲SRAM。
- 计算阶段:MAC阵列从卷积缓冲读取数据执行乘累加;中间结果可暂存于缓冲或直接送入SDP/CDP完成激活、BN等后处理。
- 池化/重排:若网络含池化层,由PDP处理;若需数据格式转换(如NCHW→NHWC),由Rubik完成。
- 写出结果:BDMA将最终输出从片上缓冲搬回外部存储,并触发中断通知主机。
验证方法
本案例为架构分析任务,验证方式为代码结构核对:
# 在hw仓库根目录执行以下命令,确认各模块RTL文件存在:
ls vmod/nvdla/
# 预期输出应包含:buf/ cdp/ cmds/ csb/ mac/ pdp/ rubik/ sdp/ bdma/ retiming/
# 以及顶层文件 nvdla_top.v
# 查看顶层例化关系:
grep -E "nvdla_(mac|cdp|pdp|sdp|rubik|bdma|cmds|csb)" vmod/nvdla/nvdla_top.v | head -20
# 应能看到各模块的实例化语句,与上述架构框图一一对应
通过条件:上述目录均存在,且 nvdla_top.v 中能找到对应模块例化;能对照本案例的框图说明每个模块在数据流中的位置与职责。