第三章 硬件设计基础回顾:数字电路基础与FPGA/ASIC设计流程
各位同学,欢迎来到第三章。在正式进入卷积神经网络的硬件加速之前,我觉得有必要先带大家回顾一下数字电路的基础知识。说白了,不管你是用FPGA还是做ASIC,底层跑的都是这些最基本的逻辑单元。我自己带项目这么多年,发现很多同学算法推得飞起,一到RTL编码就卡壳,问题往往就出在基础不牢。
3.1 组合逻辑:一切计算的起点
组合逻辑,就是输出只取决于当前输入的逻辑电路。没有记忆,没有状态。你想想看,一个加法器、一个多路选择器,都是典型的组合逻辑。
我在项目中遇到过最典型的组合逻辑问题,就是竞争冒险。比如下面这个简单的例子:
// 一个简单的组合逻辑:Y = A & B
assign Y = A & B;
看起来没问题对吧?但如果A和B来自不同的路径,延迟不一样,Y就可能出现毛刺。嗯,这里要注意,组合逻辑的输出不能直接作为时钟信号或者异步复位信号,否则你的芯片会变得非常“神经质”。
3.2 时序逻辑:让电路有了“记忆”
时序逻辑就不一样了。它引入了时钟,输出不仅取决于当前输入,还取决于之前的状态。说白了,就是电路有了“记忆”。
最基本的时序单元是D触发器。我个人习惯用下面的模板来写:
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
这里有个关键点:非阻塞赋值(<=)。很多新手容易写成阻塞赋值(=),结果仿真和综合出来的电路完全不一样。我建议你记住一句话:时序逻辑用非阻塞,组合逻辑用阻塞。这是铁律。
3.3 流水线:用面积换速度的艺术
流水线是硬件加速的灵魂。你想想看,一个复杂的组合逻辑,如果路径太长,一个时钟周期内根本算不完。怎么办?把它切成几段,中间插上寄存器。
举个例子,一个32位加法器:
// 非流水线:一个周期算完
assign sum = a + b;
// 2级流水线:分成两个周期
reg [15:0] sum_low, sum_high;
always @(posedge clk) begin
sum_low <= a[15:0] + b[15:0];
sum_high <= a[31:16] + b[31:16] + (a[15:0] + b[15:0] > 16'hFFFF);
end
assign sum = {sum_high, sum_low};
非流水线版本,时钟频率可能只能跑到100MHz。但加了流水线,每级逻辑变短了,频率可以跑到200MHz甚至更高。代价是什么?延迟增加了1个周期,但吞吐量翻倍了。在CNN加速中,我们经常用几十级甚至上百级的流水线,就是为了把乘法器和加法器跑得飞快。
3.4 FPGA架构简介:LUT、DSP、BRAM
FPGA说白了就是一块“万能积木”。你通过编程,把里面的基本单元连接起来,实现任意数字电路。FPGA的核心资源有三种:LUT、DSP、BRAM。
| 资源类型 | 全称 | 功能 | 典型数量(以Xilinx XC7K325T为例) |
|---|---|---|---|
| LUT | Look-Up Table | 实现任意组合逻辑(本质是一个小RAM) | 203,800 |
| DSP | Digital Signal Processing | 实现乘法、乘加运算 | 840 |
| BRAM | Block RAM | 实现数据存储(36Kb每块) | 445 |
LUT:一个6输入LUT,可以看成是一个64x1的RAM。你输入6位地址,它输出1位数据。任何6输入的组合逻辑,都可以通过查表实现。我刚开始学FPGA时,觉得这玩意儿很神奇——原来逻辑门是“算”出来的,不是“搭”出来的。
DSP:这是CNN加速的核心。一个DSP48E2(Xilinx 7系列)可以做一个25x18的乘法,然后累加。在卷积运算中,我们大量使用DSP来做乘加运算。我个人习惯把DSP配置成流水线模式,这样每个时钟周期都能出一个结果。
BRAM:用来存权重和中间结果。一个BRAM是36Kb,可以配置成各种位宽和深度。比如配置成512x72(512个地址,每个地址72位),非常适合存卷积核的权重。
3.5 ASIC设计流程简介
ASIC和FPGA不一样。FPGA是现成的芯片,你只需要编程。ASIC是从零开始设计一颗芯片。流程复杂得多,但性能、功耗、成本都有优势。
典型的ASIC设计流程分为以下几个阶段:
- 架构设计:确定芯片的功能、性能指标、接口协议。这个阶段我一般会用SystemC或者Python做快速原型验证。
- RTL编码:用Verilog/VHDL写出寄存器传输级描述。和FPGA开发一样,但要求更严格。
- 功能仿真:验证RTL逻辑是否正确。我建议用UVM验证方法学,虽然学习曲线陡,但覆盖率确实高。
- 逻辑综合:把RTL代码转换成门级网表。工具会告诉你面积、时序、功耗。这一步很关键,我曾经因为综合策略没选对,导致芯片面积超标20%。
- 布局布线:把门级网表放到芯片的物理位置上,并连好线。这一步决定了芯片能不能跑在目标频率上。
- 静态时序分析:检查所有路径是否满足建立时间和保持时间。嗯,这一步不能省。
- 流片:把设计交给晶圆厂生产。从提交到拿到芯片,一般要3-6个月。
3.6 本章知识体系
下面这张图,是我自己画的本章知识体系。你可以把它当作一个思维导图,快速回顾本章的核心内容。
好了,这一章的内容就到这里。数字电路基础、FPGA架构、ASIC流程,这三块是后续所有硬件加速设计的基石。你如果觉得哪里不太清楚,建议回头再看看。下一章我们开始真正进入CNN硬件加速的核心——卷积运算的硬件实现。