二、数字逻辑基础:二进制、布尔代数、逻辑门、真值表、组合逻辑与时序逻辑的基本概念
数字逻辑是FPGA设计的基石。FPGA内部的所有功能——无论是简单的接口协议、复杂的信号处理算法,还是嵌入式处理器软核——最终都是通过海量的基本逻辑单元(查找表、触发器、布线资源)组合与级联来实现的。本章将系统梳理数字逻辑的核心概念:从二进制数制出发,建立布尔代数的数学框架,理解逻辑门与真值表的对应关系,并严格区分组合逻辑与时序逻辑这两大设计范式。这些概念不仅是理论铺垫,更直接决定了你编写Verilog/VHDL代码时的思维方式与硬件实现结果。
2.1 二进制数制与编码基础
数字系统只认识两个物理状态:高电平和低电平,分别抽象为逻辑“1”和逻辑“0”。二进制(Base-2)正是基于这一物理现实构建的计数体系。每一位的权值为2的幂次方,从最低位(LSB)的2^0开始递增。例如,8位二进制数1011_0101转换为十进制为:1×2^7 + 0×2^6 + 1×2^5 + 1×2^4 + 0×2^3 + 1×2^2 + 0×2^1 + 1×2^0 = 128 + 32 + 16 + 4 + 1 = 181。
在FPGA开发中,二进制书写冗长且易错,因此常用十六进制(Base-16)作为缩写形式,每4位二进制对应1位十六进制。例如1011_0101可写作0xB5。此外,有符号数通常采用二进制补码(Two's Complement)表示,最高位为符号位,其优势在于加减法运算统一,无需单独处理符号。补码的转换规则为:正数原码即补码;负数则对其值取反加1。例如,-5在8位补码中表示为1111_1011。
| 数制 | 基数 | 有效数字 | 示例(十进制181) | FPGA应用场景 |
|---|---|---|---|---|
| 二进制 | 2 | 0,1 | 1011_0101 | 位操作、状态编码、硬件底层 |
| 八进制 | 8 | 0-7 | 265 | 较少使用,Unix权限等 |
| 十进制 | 10 | 0-9 | 181 | 人机交互、参数配置 |
| 十六进制 | 16 | 0-9,A-F | 0xB5 | 地址、数据总线、调试显示 |
| BCD码 | 10 | 0000-1001 | 0001_1000_0001 | 数码管显示、十进制运算 |
8'd181 表示8位十进制181,8'hB5 表示8位十六进制0xB5。避免在代码中混用不同进制导致阅读混乱或综合错误。
2.2 布尔代数:数字逻辑的数学语言
布尔代数由乔治·布尔于19世纪提出,是描述和处理二进制变量关系的数学体系。其基本运算有三种:与(AND,符号·)、或(OR,符号+)、非(NOT,符号上划线或!)。布尔代数的公理体系定义了0和1的运算规则:0·0=0,0·1=0,1·1=1;0+0=0,0+1=1,1+1=1;!0=1,!1=0。
基于这些公理,可以推导出若干重要定律,这些定律是化简逻辑表达式、优化FPGA资源消耗的理论工具:
- 交换律:A·B = B·A;A+B = B+A
- 结合律:(A·B)·C = A·(B·C);(A+B)+C = A+(B+C)
- 分配律:A·(B+C) = A·B + A·C;A + B·C = (A+B)·(A+C)
- 吸收律:A + A·B = A;A·(A+B) = A
- 德摩根定律:!(A·B) = !A + !B;!(A+B) = !A · !B
德摩根定律在FPGA设计中尤为常用,它允许我们在与非门(NAND)或或非门(NOR)之间进行等效转换,从而匹配FPGA底层查找表(LUT)的物理实现结构。例如,一个复杂的逻辑表达式F = !(A·B + C·D),通过德摩根定律可改写为F = (!A + !B) · (!C + !D),便于用LUT直接实现。
2.3 逻辑门与真值表
逻辑门是布尔代数在硬件中的物理实现。FPGA内部并不直接使用分立逻辑门,而是通过查找表(LUT)来模拟任意组合逻辑功能。但理解基本逻辑门的真值表,是分析复杂电路和调试问题的基本功。常见逻辑门包括:与门(AND)、或门(OR)、非门(NOT)、与非门(NAND)、或非门(NOR)、异或门(XOR)、同或门(XNOR)。
真值表是列出所有输入组合及其对应输出的表格,它是逻辑功能的完整描述。以2输入与非门为例,其真值表如下:
| A | B | Y = !(A·B) |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
从真值表可以推导出逻辑表达式。方法是将输出为1的每一行写成最小项(输入变量相与),再将所有最小项相或。例如,对于异或门(XOR),输出为1的行是A=0,B=1和A=1,B=0,因此表达式为Y = (!A)·B + A·(!B),简写为Y = A ⊕ B。
assign Y = A && B;)让工具自动优化。
2.4 组合逻辑:无记忆的决策网络
组合逻辑电路的特点是:任意时刻的输出仅取决于该时刻的输入,与电路的历史状态无关。它没有存储元件,也没有反馈回路。典型的组合逻辑模块包括:多路选择器(MUX)、译码器(Decoder)、编码器(Encoder)、加法器(Adder)、比较器(Comparator)等。
在Verilog中,组合逻辑有两种常用描述方式:
// 方式一:assign 连续赋值
assign y = (sel == 1'b1) ? a : b;
// 方式二:always 块 + 阻塞赋值
always @(*) begin
if (sel == 1'b1)
y = a;
else
y = b;
end
组合逻辑设计的关键问题之一是竞争冒险。当输入信号经过不同路径到达逻辑门的时间不一致时,输出端可能出现短暂的错误脉冲(毛刺)。例如,一个2输入与门,当A从1变为0、B从0变为1时,理论上输出应保持0,但由于A和B的翻转时间存在微小差异,可能瞬间出现A=1且B=1的状态,导致输出产生一个正向毛刺。消除毛刺的常用方法包括:在输出端增加D触发器采样(同步设计)、使用格雷码编码状态、或增加冗余项消除逻辑险象。
d0~d3,选择信号sel[1:0],输出y。使用case语句实现时,务必列出所有sel组合(包括default分支),否则综合器可能推断出锁存器(Latch),导致时序问题。正确写法应包含default: y = 8'h00;。
2.5 时序逻辑:携带记忆的状态机
时序逻辑电路的输出不仅取决于当前输入,还取决于电路的历史状态。其核心存储元件是触发器(Flip-Flop,FF),在FPGA中通常为D触发器。D触发器在时钟上升沿(或下降沿)到来时,将输入D的值锁存到输出Q,其余时间Q保持不变。这种边沿触发特性是同步时序设计的基础。
时序逻辑的基本结构由存储元件和组合逻辑两部分组成。组合逻辑负责根据当前状态和输入计算下一状态及输出,触发器负责在时钟沿更新状态。典型的时序逻辑模块包括:计数器、移位寄存器、有限状态机(FSM)、FIFO、RAM控制器等。
在Verilog中,时序逻辑使用always @(posedge clk)块和非阻塞赋值(<=)描述:
// 8位同步计数器
reg [7:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 8'h00;
else if (en)
cnt <= cnt + 1'b1;
end
同步设计的核心原则是:所有触发器共享同一个时钟域,避免使用门控时钟或异步复位(除非必要)。异步电路虽然在某些低功耗场景有优势,但会带来复杂的时序约束和亚稳态风险,初学者应优先掌握同步设计方法。
2.6 组合逻辑与时序逻辑的对比与工程选择
理解两类逻辑的本质区别,是FPGA设计分水岭。下表从多个维度进行对比:
| 对比维度 | 组合逻辑 | 时序逻辑 |
|---|---|---|
| 输出决定因素 | 仅当前输入 | 当前输入 + 历史状态 |
| 存储元件 | 无 | 触发器/锁存器 |
| 时钟依赖 | 不依赖时钟 | 依赖时钟沿 |
| Verilog描述 | assign / always@(*) | always@(posedge clk) |
| 赋值方式 | 阻塞赋值 = | 非阻塞赋值 <= |
| 典型电路 | 加法器、MUX、译码器 | 计数器、FSM、移位寄存器 |
| 时序分析 | 关注传播延迟、毛刺 | 关注建立/保持时间、时钟偏斜 |
| FPGA实现 | LUT + 布线 | LUT + FF + 布线 |
在实际工程中,一个完整的数据通路通常由组合逻辑与时序逻辑交替构成。例如,一个UART接收模块:接收移位寄存器(时序逻辑)将串行数据逐位移入,起始位检测逻辑(组合逻辑)判断数据有效,波特率计数器(时序逻辑)产生采样时钟,最终并行数据输出(组合逻辑)送到数据总线。这种“寄存器-组合逻辑-寄存器”的流水线结构是FPGA高性能设计的核心范式。
always @(posedge clk)块,但忘记处理复位信号,导致上电后计数器状态不确定。分析:FPGA上电后触发器初始值可能是0或1,若不复位,计数起点不可控。解决:添加异步复位端口rst_n,在复位有效时将计数器清零。操作步骤:1) 定义reg [3:0] cnt;2) 在always块敏感列表中加入negedge rst_n;3) 复位分支使用阻塞赋值cnt <= 4'h0;4) 使能分支cnt <= cnt + 1'b1。结果:计数器从0开始稳定递增。风险:异步复位信号本身可能存在亚稳态,需通过同步器处理后再接入系统。复盘:复位策略是时序设计的首要决策点,必须明确异步复位、同步释放的原则。
2.7 本章小结与设计复盘
数字逻辑基础是FPGA设计的“语法”和“词汇”。二进制与编码决定了数据如何表示,布尔代数提供了逻辑化简的数学工具,逻辑门与真值表是硬件行为的抽象描述,而组合逻辑与时序逻辑的区分则定义了电路的结构范式。在实际编码前,建议先画出数据通路草图,明确哪些模块是组合的、哪些是时序的,再动手写RTL。这样能显著减少综合后的功能错误和时序违例。