第一章:数字电路基础回顾
各位同学,欢迎来到《可编程逻辑设计快速上手手册》。
我是你们的讲师,一个在FPGA圈子里摸爬滚打十几年的老工程师。今天咱们聊点最基础的,但也是最重要的——数字电路基础。
你可能会想:“都什么年代了,还讲晶体管?” 别急,我见过太多人,上来就写Verilog,结果综合出来一堆莫名其妙的毛刺,查了半天发现是组合逻辑没搞明白。基础不牢,地动山摇。咱们花点时间,把地基夯实了。
核心观点: 数字电路设计的本质,就是用晶体管搭积木。你只有知道积木长什么样,才能搭出漂亮的城堡。
1.1 从晶体管到逻辑门
数字电路最底层的单元是什么?是晶体管。你可以把它想象成一个水龙头,或者一个开关。
栅极(Gate)就是开关的把手。给栅极加电压,开关就通了,电流能从源极流到漏极。不加电压,开关就断开。就这么简单。
那怎么用开关搭出逻辑门呢?
举个最简单的例子:非门(反相器)。
一个PMOS管在上,一个NMOS管在下。输入是1,上面的PMOS关断,下面的NMOS导通,输出被拉到地,就是0。输入是0,上面的PMOS导通,下面的NMOS关断,输出被拉到电源,就是1。
你看,这不就是取反吗?
我的小经验: 刚开始学的时候,别死记硬背PMOS和NMOS的导通条件。你就记住:PMOS是“高电平关断”,NMOS是“高电平导通”。我在项目中调试一个IO口驱动能力不足的问题,最后发现就是PMOS和NMOS的尺寸比例没调好。嗯,模拟的东西,有时候就是得靠经验。
有了非门,再组合一下,就能得到与非门、或非门。再组合,就能得到与门、或门。再往下,就是加法器、比较器、多路选择器……
说白了,整个数字世界,就是从这一个开关开始的。
1.2 组合逻辑 vs 时序逻辑
这是新手最容易混淆的地方。我当年也犯过傻。
组合逻辑: 输出只取决于当前的输入。输入一变,输出立刻变(当然,有门延迟)。没有记忆功能。
比如一个加法器:你输入1+1,它立刻输出2。你输入2+2,它立刻输出4。它不记得刚才算过什么。
时序逻辑: 输出不仅取决于当前输入,还取决于电路之前的状态。它有记忆功能。
比如一个计数器:你给它一个时钟,它就在0、1、2、3...之间跳。它记得自己现在数到几了。
| 特性 | 组合逻辑 | 时序逻辑 |
|---|---|---|
| 输出依赖 | 仅当前输入 | 当前输入 + 历史状态 |
| 记忆能力 | 无 | 有(触发器/锁存器) |
| 时钟 | 不需要 | 通常需要 |
| 典型电路 | 加法器、译码器、多路选择器 | 计数器、寄存器、状态机 |
| 毛刺风险 | 高(路径延迟不同) | 低(时钟同步采样) |
避坑指南: 我曾经在一个项目中,用组合逻辑做了一个复杂的地址译码器。结果因为不同路径的延迟不一样,输出出现了毛刺,导致后面的寄存器误触发。查了整整两天,最后加了一级流水线寄存器才搞定。所以,跨时钟域或者对时序敏感的信号,一定要用寄存器打一拍。
1.3 同步设计的基本概念
什么是同步设计?说白了,就是所有时序逻辑都听同一个时钟的指挥。
时钟就像阅兵式上的指挥官。他说“走”,大家就一起迈左脚。他说“停”,大家就一起立正。这样队伍才整齐,不会你撞我、我撞你。
在FPGA里,这个“指挥官”就是全局时钟网络。它负责把时钟信号低抖动、低偏斜地送到每一个触发器。
同步设计的核心规则:
- 单时钟域: 尽量让整个设计跑在同一个时钟下。如果必须用多个时钟,一定要做跨时钟域处理(比如用双触发器同步器)。
- 避免组合逻辑反馈: 不要试图用组合逻辑搭一个“锁存器”。这在FPGA里是禁忌,综合工具会给你一堆警告。
- 寄存器化输出: 模块的输出信号,最好都从寄存器直接出来。这样时序干净,不容易出问题。
一个简单的同步计数器示例(Verilog):
module counter (
input wire clk, // 时钟
input wire rst_n, // 异步复位,低有效
output reg [3:0] cnt // 4位计数器
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 4'b0; // 复位到0
else
cnt <= cnt + 1'b1; // 每个时钟上升沿加1
end
endmodule
你看这个代码:always @(posedge clk or negedge rst_n),这就是同步设计的标志。所有赋值都在时钟上升沿发生。你想想看,如果不用时钟,而是用组合逻辑去控制这个计数器,会是什么后果?
嗯,后果就是:计数器的值会在一个时钟周期内跳变多次,完全不可控。
我的习惯: 写代码之前,我会先画一个简单的时序图。把时钟、复位、输入、输出画清楚。这样写出来的代码,基本不会有时序问题。我建议你也试试。
好了,这一章就到这里。数字电路的基础,说白了就是三件事:晶体管怎么当开关,组合逻辑和时序逻辑的区别,以及为什么要听时钟的话。这些东西,你以后写每一行代码都会用到。
记住:同步设计是FPGA的基石。尊重时钟,时钟也会尊重你。