FPGA 入门指南
一、什么是 FPGA
刚接触硬件的同学可能会疑惑:FPGA 和单片机有什么区别?简单来说,FPGA(Field Programmable Gate Array,现场可编程门阵列)就像一张白纸。你可以用硬件描述语言(如 Verilog)在上面'画'出任意数字电路。
单片机是现成的芯片(固定架构),而 FPGA 允许你从底层构建电路。如果把单片机比作组装好的乐高套装,FPGA 就是一堆零散的积木块,想拼成飞机还是坦克全看你的代码怎么写。这也是它被称为'数字电路橡皮泥'的原因。
二、开发环境搭建
1. 安装包获取
前往 Xilinx 官网下载 Vivado Design Suite(社区版免费)。建议选择 2020.1 之后的版本,对新手更友好。安装时记得勾选 "Vivado HL Design Edition" 和对应器件支持(比如 Artix-7 系列)。
2. 硬件准备
推荐先用在线仿真器练手,等基础扎实了再入手开发板:
- Nexys A7(约 $200)
- Basys3(入门级首选)
- DE10-Nano(带 ARM 双核)
3. 第一个工程创建
打开 Vivado → 点击 Create Project → 选择 RTL Project → 添加新 Verilog 文件。重点:器件型号选 xc7a35tcsg324-1(对应多数入门开发板)。
三、Verilog 核心语法
// 基础结构模板
module my_module(
input wire clk, // 时钟信号
input wire rst_n, // 复位信号(低有效)
output reg led // LED 输出
);
// 组合逻辑用 assign
assign led = 1'b1;
// 时序逻辑用 always 块
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
led <= 1'b0; // 复位时 LED 灭
end else begin
led <= ~led; // 翻转 LED 状态
end
end
endmodule
必须掌握的 10 个核心语法点:
module/endmodule➔ 电路模块定义input/output➔ 输入输出端口wire/reg➔ 线网与寄存器assign➔ 组合逻辑赋值always➔ 过程块(时序逻辑)posedge/negedge➔ 时钟边沿检测if/else➔ 条件判断case➔ 多路选择parameter➔ 参数定义#➔ 延时控制(仅仿真用)
四、实战:LED 流水灯
1. 代码实现
module led_run(
input clk_100MHz, // 开发板上的 100MHz 时钟
input rst_n, // 复位按键(低电平有效)
output reg [3:0] leds // 4 位 LED 输出
);
// 分频器:100MHz -> 1Hz
reg [26:0] counter;
always @(posedge clk_100MHz or negedge rst_n) begin
if (!rst_n) begin
counter <= 0;
end else begin
counter <= (counter == 27'd99_999_999) ? 0 : counter + 1;
end
end
// LED 流水效果
always @(posedge clk_100MHz or negedge rst_n) begin
if (!rst_n) begin
leds <= 4'b0001; // 初始状态
end else if (counter == 27'd99_999_999) begin
leds <= {leds[2:0], leds[3]}; // 循环左移
end
end
endmodule
2. 仿真测试
创建 testbench 文件进行验证:
`timescale 1ns / 1ps
module tb_led_run();
reg clk, rst_n;
wire [3:0] leds;
// 实例化被测模块
led_run uut(.clk_100MHz(clk), .rst_n(rst_n), .leds(leds));
// 生成时钟信号
initial begin
clk = 0;
forever #5 clk = ~clk; // 100MHz 周期=10ns
end
// 测试流程
initial begin
rst_n = 0; // 初始复位
#100;
rst_n = 1; // 释放复位
#200000000; // 等待 2 秒(仿真时间)
$stop;
end
endmodule
3. 上板验证
- 生成 bit 流文件:点击 "Generate Bitstream"
- 连接开发板:通过 USB-JTAG 接口
- 烧录程序:Open Hardware Manager → Auto Connect → Program Device
- 观察结果:检查 LED 是否按预期循环流动
五、学习路线
阶段一:数字电路基础
- 掌握二进制/十六进制转换
- 理解组合逻辑(与或非门)
- 搞定时序逻辑(触发器、计数器)
阶段二:Verilog 进阶
- 状态机设计(Moore vs Mealy)
- FIFO/存储器接口
- 跨时钟域处理(CDC)
阶段三:实战项目
- 电子时钟(数码管驱动)
- VGA 图像显示
- 简单 CPU 设计(比如 RISC-V 核)
推荐资源
- 《Verilog 数字系统设计教程》夏宇闻
- Xilinx 官方文档 UG901
- FPGA4FUN 项目网站
六、常见问题
- 阻塞与非阻塞赋值
=(阻塞)用在组合逻辑,<=(非阻塞)用在时序逻辑!混用会导致难以调试的电路故障。 - 未初始化寄存器
FPGA 上电时寄存器值是随机的!务必通过复位信号初始化所有状态。 - 时钟域混乱
不同频率的时钟信号要隔离处理,否则会出现亚稳态(Metastability)。 - 仿真与实机差异
仿真通过的代码不一定能上板运行!特别注意时序约束(.xdc 文件)。
小技巧:遇到诡异的问题时,先检查:是否所有输出都有驱动?是否出现锁存器(Latch)?时钟使能信号是否正确?
FPGA 的精髓在于并行思维。忘记软件的顺序执行,学会用硬件的方式思考问题。点亮 LED 只是开始,接下来可以尝试神经网络加速、视频处理等方向,你会发现硬件编程的无限可能。


