3、开发流程入门:FPGA设计流程与第一个工程
各位同学,欢迎来到第三章。这一章咱们要动真格的了。
前面两章我们聊了FPGA是什么、能干什么。但光说不练假把式,今天我们就来走一遍完整的FPGA开发流程。从设计到下载,每一步我都会结合自己的经验来讲。
嗯,先给你看一张图,这是我画的一个FPGA开发流程框架。你把它印在脑子里,后面每一步都会对应到这张图上。
这张图我画了好几次才满意。你仔细看,它是个闭环——不是走完就完事了,经常要回头改。
3.1 FPGA设计流程:四步走
FPGA开发说白了就四个步骤:设计 → 综合 → 实现 → 下载。我当年刚入行时,以为写代码就是全部,结果被综合报错折磨得够呛。后来才明白,每一步都有它的门道。
3.1.1 设计(Design Entry)
这是第一步,也是你最需要花心思的一步。
- 编写RTL代码:用Verilog或VHDL描述你的逻辑功能。我个人习惯用Verilog,简洁明了。
- 原理图输入:有些老工程师喜欢画原理图,但说实话,复杂项目还是代码靠谱。
- 功能仿真:写代码后先跑一遍仿真,看看波形对不对。这一步能省下后面大量调试时间。
3.1.2 综合(Synthesis)
综合就是把你的Verilog代码翻译成FPGA能理解的“门级网表”。
你想想看,你写了个 assign led = ~btn;,综合工具会把它变成查找表(LUT)和触发器(FF)的组合。
我曾经遇到过一个坑:写了一个很大的组合逻辑,综合后资源爆了。后来拆成流水线,才解决问题。所以综合报告一定要看,尤其是资源利用率。
3.1.3 实现(Implementation)
实现包含三个子步骤:
- 映射(Map):把门级网表映射到FPGA的具体资源上。
- 布局布线(Place & Route):决定每个逻辑单元放在芯片的哪个位置,怎么连线。
- 时序分析(Timing Analysis):检查你的设计能不能跑在目标频率上。
3.1.4 下载(Download)
最后一步,生成比特流文件(.bit或.mcs),通过下载器烧到FPGA里。
嗯,这里要注意:下载前一定要确认板子供电正常、JTAG线接对了。我第一次下载时,线没插紧,折腾了半小时才发现。
3.2 Lattice Diamond软件安装与界面介绍
我们课程用的是Lattice的FPGA,所以配套软件是Diamond。这个软件我用了好几年,从3.0版本到现在的3.12,界面变化不大。
3.2.1 安装要点
- 版本选择:建议用3.11或3.12,比较稳定。
- 安装路径:不要有中文和空格。我见过有人装在“Program Files (x86)”里,结果license死活认不到。
- License配置:安装后要配置license文件。环境变量
LM_LICENSE_FILE指向你的license文件路径。
3.2.2 界面布局
Diamond的界面分为几个区域:
| 区域 | 功能 | 我的建议 |
|---|---|---|
| 左侧:文件列表 | 显示工程文件、源文件、约束文件 | 把文件分好文件夹,别全堆在根目录 |
| 中间:编辑区 | 代码编辑、原理图查看 | 字体调大一点,保护眼睛 |
| 下方:输出窗口 | 显示综合、实现、下载的日志 | 养成看日志的习惯,错误信息都在这里 |
| 右侧:进程视图 | 显示当前执行的任务进度 | 双击可以重新运行某一步 |
3.3 第一个工程:点亮LED
好了,理论说完了,咱们来动手。第一个工程永远是点亮LED,这是硬件界的“Hello World”。
3.3.1 创建工程
- 打开Diamond,点击 File → New → Project。
- 输入工程名,比如
led_test,选择保存路径。 - 选择器件型号。我们用的是Lattice MachXO2系列,具体型号看板子上的丝印。
- 点击Finish,工程就建好了。
3.3.2 编写代码
新建一个Verilog文件,命名为 led_top.v。输入以下代码:
module led_top (
input wire clk, // 板载时钟,比如12MHz
input wire rst_n, // 复位,低有效
output reg led // LED输出
);
// 分频计数器,让LED闪烁
reg [23:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 24'd0;
else
cnt <= cnt + 1'b1;
end
// 取最高位驱动LED
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led <= 1'b0;
else
led <= cnt[23]; // 约0.7秒闪烁一次(12MHz时钟)
end
endmodule
这段代码很简单:用计数器分频,把最高位输出到LED。这样LED就会以大约0.7秒的频率闪烁。
3.3.3 综合与实现
- 在进程视图中双击 Synthesize Design,开始综合。
- 综合完成后,双击 Map Design 和 Place & Route。
- 每一步完成后,检查输出窗口有没有错误或警告。
我习惯在综合后先看一眼资源报告。如果LUT用得太多了,说明代码可能有问题。
3.3.4 下载到板子
- 连接下载器(比如FTDI或Lattice专用下载线)到板子。
- 点击 Tools → Programmer,打开下载工具。
- 选择生成的bit文件(通常在
impl/目录下)。 - 点击 Program,等待进度条走完。
3.3.5 验证结果
下载成功后,板子上的LED应该开始闪烁了。如果不亮,别慌:
- 检查LED是否共阳还是共阴,代码里的极性对不对。
- 检查复位引脚是否拉高(如果rst_n是高有效,代码要改)。
- 用示波器或逻辑分析仪看看时钟有没有进来。
我记得第一次点亮LED时,板子没反应。后来发现是复位引脚没接上拉电阻。嗯,这种小问题最磨人。
3.4 本章小结
这一章我们走完了FPGA开发的完整流程。从设计到下载,每一步都有它的意义。你可能会觉得点亮一个LED太简单了,但相信我,这个流程会贯穿你所有的FPGA项目。
Diamond软件虽然不如Vivado那么花哨,但胜在轻量、稳定。用习惯了你会发现,它其实很顺手。
下一章我们会深入Verilog语法,开始写更复杂的逻辑。但今天,先享受一下LED闪烁的成就感吧。
公众号:蓝海资料掘金营,微信deep3321