2026年Q2:开源FPGA工具链Yosys+NextPNR上手教程

二牛学FPGA
文章2026-05-14
40

Quick Start

  1. 安装依赖:在 Ubuntu 22.04/24.04 中执行 sudo apt install build-essential clang bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 python3-pip
  2. 克隆 Yosys 仓库:git clone https://github.com/YosysHQ/yosys.git,进入目录执行 make -j$(nproc) 编译,完成后 sudo make install
  3. 克隆 NextPNR 仓库:git clone https://github.com/YosysHQ/nextpnr.git,进入目录执行 cmake . -DARCH=ice40 && make -j$(nproc) && sudo make install(以 iCE40 为例)。
  4. 安装 IceStorm 工具(用于 iCE40 位流生成):git clone https://github.com/YosysHQ/icestorm.git,进入目录执行 make -j$(nproc) && sudo make install
  5. 编写一个简单的 Verilog 模块(如 LED 闪烁计数器),保存为 top.v
  6. 运行综合:yosys -p "read_verilog top.v; synth_ice40 -json top.json"
  7. 运行布局布线:nextpnr-ice40 --json top.json --pcf top.pcf --asc top.asc(需预先编写引脚约束文件 top.pcf)。
  8. 生成位流:icepack top.asc top.bin
  9. 下载到板卡(以 iCEstick 为例):iceprog top.bin
  10. 观察 LED 按预期闪烁,即完成首次开源工具链全流程。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Lattice iCE40-HX1K (iCEstick)开源工具链支持最成熟的 FPGA 系列ECP5 (nextpnr-ecp5)、Gowin (apicula)
EDA 版本Yosys 0.45+ (2026 Q2)主分支持续更新,支持最新 SystemVerilog 语法OSS CAD Suite 预编译包
仿真器Icarus Verilog (iverilog) 12.0+免费、与 Yosys 配合良好Verilator (仅支持可综合子集)
时钟/复位板载 12 MHz 晶振,外部复位(可选)iCEstick 提供 12 MHz 时钟输入内部 PLL (iCE40 有 2 个 PLL)
接口依赖USB 下载(FTDI 芯片)iceprog 通过 FTDI 驱动烧写JTAG (openFPGALoader)
约束文件物理约束文件 (.pcf)定义引脚位置与 I/O 标准SDC (部分支持,需 nextpnr 实验性功能)
操作系统Ubuntu 22.04 / 24.04 LTS依赖包齐全,社区支持好Windows (WSL2) / macOS (Homebrew)

目标与验收标准

  • 功能点:实现一个 1 Hz 闪烁的 LED(12 MHz 分频至 1 Hz),通过开源工具链完成综合、布局布线、位流生成与下载。
  • 性能指标:Fmax 不低于 50 MHz(示例设计目标,实际以时序报告为准);逻辑资源占用不超过 20 个 LC(查找表+触发器)。
  • 资源/Fmax 验收方式:运行 nextpnr-ice40 --json top.json --pcf top.pcf --asc top.asc --report top.rpt,查看报告中的 Max frequencyLC usage
  • 关键波形/日志:仿真时使用 iverilog + GTKWave 观察分频器输出波形;下载后 LED 以约 1 Hz 频率亮灭。

实施步骤

工程结构

  • 创建项目目录 led_blink/,包含以下文件:
    • top.v:顶层 Verilog 模块
    • top.pcf:物理约束文件
    • top_tb.v:仿真测试文件(可选)
    • Makefile:自动化编译脚本
  • 推荐使用 Makefile 串联流程,避免重复输入命令。
  • 常见坑:文件名与模块名不一致会导致 Yosys 报错;确保 top.v 中模块名与 read_verilog 引用的顶层一致。

关键模块:LED 闪烁计数器

// top.v - LED Blink for iCEstick
module top (
    input  wire clk_12m,
    output wire led
);

    reg [23:0] counter;
    always @(posedge clk_12m) begin
        counter <= counter + 1;
    end

    assign led = counter[23];  // 12 MHz / 2^24 ≈ 0.715 Hz

endmodule

逐行说明

  • 第 1 行:注释,标明文件用途。
  • 第 2 行:模块声明,名称为 top,与文件名一致。
  • 第 3-4 行:端口声明——clk_12m 为输入时钟(12 MHz),led 为输出,连接到板载 LED。
  • 第 6 行:声明 24 位寄存器 counter,综合后映射为 24 个 D 触发器。
  • 第 7-9 行always 块在时钟上升沿触发,每个时钟周期 counter 加 1。这是典型的二进制计数器,无复位信号时初始值未知(仿真中为 X),但上电后实际 FPGA 寄存器状态随机,不影响功能。
  • 第 11 行:将 counter 的最高位(bit 23)赋值给 led。由于 counter 每 2^24 个时钟周期翻转一次最高位,LED 以约 0.715 Hz 频率闪烁。
  • 第 13 行:模块结束。
  • 综合意图:Yosys 会将 reg [23:0] 推断为 24 个 D 触发器,counter + 1 推断为 24 位加法器。由于加法器仅递增 1,综合工具会优化为增量器(+1 逻辑),资源开销较小。
  • 对仿真与上板的影响:仿真时 counter 初始为 X,需要复位或赋初值才能看到确定波形;上板后寄存器上电状态随机,但 counter 会从随机值开始递增,LED 最终会闪烁,只是初始相位不确定。

引脚约束文件 (top.pcf)

# top.pcf for iCEstick (iCE40-HX1K)
set_io clk_12m 21
set_io led     95

逐行说明

  • 第 1 行:注释,说明约束文件针对 iCEstick 板卡。
  • 第 2 行:将顶层端口 clk_12m 映射到 FPGA 的第 21 号引脚(iCEstick 上连接 12 MHz 晶振的引脚)。
  • 第 3 行:将顶层端口 led 映射到第 95 号引脚(iCEstick 上连接用户 LED 的引脚)。
  • 注意:引脚编号因板卡而异,请查阅具体板卡原理图或 icestorm 提供的 iCEstick.pcf 示例文件。

时序/CDC/约束

  • 本示例为单时钟域设计,无需 CDC 处理。
  • 时序约束:NextPNR 默认不读取 SDC 文件;对于 iCE40,时钟频率较低(通常 < 100 MHz),简单设计可无需显式约束。若需更高频率,可尝试 nextpnr-ice40 --sdc constraints.sdc(实验性支持)。
  • 常见坑:若设计包含跨时钟域,务必使用同步器(双级触发器)或异步 FIFO,否则 Yosys 不会报错,但上板可能出现亚稳态导致功能异常。

验证

// top_tb.v - Testbench for LED Blink
`timescale 1ns / 1ps
module top_tb;
    reg clk;
    wire led;

    top uut (
        .clk_12m(clk),
        .led(led)
    );

    initial begin
        clk = 0;
        forever #41.667 clk = ~clk;  // 12 MHz period ≈ 83.333 ns
    end

    initial begin
        #20000000;  // simulate 20 ms
        $finish;
    end

    initial begin
        $dumpfile("top_tb.vcd");
        $dumpvars(0, top_tb);
    end
endmodule

逐行说明

  • 第 1-2 行:时间尺度设置,1 ns 精度。
  • 第 3 行:测试模块声明。
  • 第 4-5 行:声明 reg 类型时钟激励与 wire 类型输出观测。
  • 第 7-10 行:实例化被测试模块 top,端口连接。
  • 第 12-14 行:初始化时钟为 0,每 41.667 ns 翻转一次(12 MHz 周期 83.333 ns,半周期 41.667 ns)。
  • 第 16-18 行:仿真运行 20 ms 后结束。
  • 第 20-22 行:生成 VCD 波形文件,用于 GTKWave 查看。
  • 运行仿真iverilog -o top_tb.vvp top_tb.v top.v && vvp top_tb.vvp && gtkwave top_tb.vcd
  • 验收点:在 GTKWave 中观察 counter[23] 波形,应看到约 0.715 Hz 的方波。

上板

  • 确保 iCEstick 通过 USB 连接,并已安装 FTDI 驱动(Linux 下通常自动识别)。
  • 执行 iceprog top.bin,应看到烧写进度条,完成后 LED 开始闪烁。
  • 常见坑
    • iceprog 报错“FTDI not found”:检查 USB 连接,或运行 lsusb 确认设备 ID (0403:6010)。
    • 烧写后 LED 不亮:检查 top.pcf 引脚编号是否正确,或检查板卡电源指示灯。

原理与设计说明

Yosys 是一个基于 ABC 综合引擎的开源逻辑综合工具,支持 Verilog-2005 及部分 SystemVerilog 语法。它将 RTL 描述转换为门级网表(BLIF/JSON 格式)。NextPNR 则负责布局布线,将网表映射到具体 FPGA 的 LUT、FF、BRAM 等资源上,并生成位流配置数据。

为什么选择 Yosys+NextPNR?

  • 免费与开放:无许可证限制,适合教育、原型验证与低成本项目。
  • 可定制:可通过插件(如 synth_ice40 命令)扩展对特定器件的支持。
  • 社区活跃:截至 2026 年 Q2,Yosys 已支持 Lattice iCE40/ECP5、Gowin、Xilinx 7 系列(实验性)等。
  • trade-off:相比厂商工具(如 Lattice Radiant),开源工具在 Fmax 优化上通常低 10-20%(示例数据,以实际设计为准),但资源利用率相近。对于低速控制逻辑,差异可忽略。
  • 风险与边界:不支持部分高级原语(如高速 SERDES、硬核处理器);时序约束支持有限;部分器件(如 Xilinx Ultrascale)仍处于实验阶段。

验证与结果

指标测量值(示例)测量条件
Fmax85 MHziCE40-HX1K,12 MHz 时钟,无额外时序约束
LC 占用24 个 LC(24 个 LUT + 24 个 FF)24 位计数器,综合后优化为增量器
延迟无组合逻辑路径(仅寄存器输出)LED 输出直接来自寄存器
吞吐N/A(控制逻辑,非数据通路)
波形特征LED 输出频率 0.715 Hz,占空比 50%12 MHz / 2^24

注意:以上数据为示例值,实际结果因 Yosys/NextPNR 版本、优化选项而异。请以实际工程报告为准。

故障排查

  • 现象:位流烧写后 FPGA 无反应,但 iceprog 成功
    • 现象yosys 报错“ERROR: Module ‘top’ not found!”

      原因:Verilog 文件中模块名与 read_verilog 指定的顶层不匹配。

      检查点:检查 module 声明后的名称。

      修复建议:统一模块名与文件名(如 top.v 内声明 module top)。

    • 现象nextpnr-ice40 报错“Can’t find port ‘clk_12m’ in JSON.”

      原因:Yosys 输出 JSON 中端口名与 PCF 不一致。

      检查点:运行 yosys -p "read_verilog top.v; synth_ice40 -json top.json" 后,用 cat top.json | grep ports 查看端口名。

      修复建议:修改 PCF 中的端口名与 JSON 一致。

    • 现象iceprog 报错“FT_Open failed.”

      原因:未安装 FTDI 驱动或权限不足。

      检查点:运行 lsusb 查看是否有 0403:6010 设备;运行 dmesg | grep ftdi 查看驱动加载。

      修复建议:安装 libftdi1-dev,并将用户加入 dialout 组(sudo usermod -a -G dialout $USER),然后注销重登。

    • 现象:烧写后 LED 常亮或常灭。

      原因:引脚约束错误或设计逻辑错误。

      检查点:核对 PCF 中引脚编号与板卡原理图;仿真验证 led 波形是否翻转。

      修复建议:若仿真中 led 为 X,说明寄存器未初始化,添加复位逻辑或赋初值。

    • 现象make 编译 Yosys 时出错“fatal error: readline/readline.h: No such file or directory”。

      原因:缺少 libreadline-dev

      检查点:运行 dpkg -l | grep libreadline

      修复建议sudo apt install libreadline-dev

    • 现象:NextPNR 布局布线时间过长(超过 5 分钟)。

      原因:设计规模较大或使用了高密度器件。

      检查点:检查 --seed 参数或尝试不同优化策略。

      修复建议:使用 --placer-heap 选项(默认),或降低器件利用率。

    • 现象:仿真中 counter 为 X。

      原因:寄存器未初始化。

      检查点:检查 initial 块或复位逻辑。

      修复建议:在测试文件中添加 #0 force top_tb.uut.counter = 0;(仅仿真),或修改 RTL 添加复位端口。

    • 现象:Yosys 综合后报告大量“Warning: wire ‘…’ is assigned but not used.”

      原因:设计中有未连接端口或冗余逻辑。

      检查点:检查模块实例化是否遗漏连接。

      修复建议:删除未使用逻辑,或使用 /* verilator lint_off UNUSED */ 抑制警告。

    • 现象nextpnr-ecp5 报错“Unsupported device.”

      原因:指定的器件型号不在支持列表中。

      检查点:运行 nextpnr-ecp5 --help 查看 --device 可选值。

      修复建议:使用 --device LFE5U-12F 等正确型号。

    • 现象:位流烧写后 FPGA 无反应,但 iceprog 成功

  • 分类
    技术分享
    标签
    fpgaYosys开源工具链
    浏览 40
    分享:

    相关推荐

    同频道 · 相近分类

    暂无相关推荐

    作者

    二牛学FPGA查看主页

    同分类阅读

    文章

    延伸阅读与实操

    • 文章 + 课程联动深度文章常对应体系课章节,可一键选课。
    • 学习产出可参考笔记与作业案例在学习产出广场持续更新。

    探索全站