一个同步 FIFO,带你看懂 Vivado 全流程:不是教程,是踩坑笔记
'刚在 Vivado 里点完'Generate Bitstream',板子一上电,LED 不亮、ILA 没波形、串口吐乱码……你不是代码写错了,是整个设计链路中某处'隐性假设'崩了。' ——这是我给新同事讲 Vivado 时,第一堂课必放的截图:一个红框标出的
Timing Summary: 123 paths failed。
这不是一篇'手把手教你新建工程'的入门指南。它是一份 从实验室原型走向工业可用系统的实战备忘录 ,主角是一个只有 200 行 Verilog 的同步 FIFO 控制器。但它背后串起了 Vivado 里最常被忽略、却最致命的五个断点:
- 工程创建时
-part填错型号,后面全白干; - RTL 里用了
initial块,仿真飞起,上板哑火; - XDC 里忘了
create_clock,时序报告全是问号; - Testbench 没覆盖空满翻转边界,功能验证形同虚设;
- 没在 RTL 里预留 ILA 探针,调试靠猜,三天变三周。
下面,我们就用这个 FIFO,一环扣一环地走完真实项目该走的每一步。
一、别急着写代码:先搞清 Vivado 到底在管理什么
很多新手以为 Vivado 是个'高级编辑器',其实它本质是一个 基于 Tcl 的依赖驱动型构建系统 ——和 Makefile、CMake、Bazel 是同一类东西,只是领域特定。
它的核心不是图形界面,而是 .xpr 工程数据库。你点 GUI 做的每件事(加文件、改约束、跑综合),最终都变成一条 Tcl 命令,存进这个数据库。所以:
✅ 正确姿势:用 Tcl 脚本建工程,GUI 只做辅助调试; ❌ 危险操作:纯 GUI 建好工程后导出 Tcl,再删掉原始工程重来——你会发现有些配置根本导不出来(比如某些 IP 核的私有属性)。
来看一段真正能进 CI 流水线的初始化脚本:
# fifo_demo.tcl —— 可直接 source 运行,也可粘贴进 Tcl Console
create_project fifo_demo ./proj -part xc7z020clg400-1 -force
set_property BOARD_PART xilinx.com:zybo_z7_20:part0:1.0 [current_project]
# 关键!必须显式指定 fileset,否则 add_files 无效
add_files -fileset sources_1 ./src/fifo_ctrl.v
add_files -fileset constrs_1 ./constrs/fifo_top.xdc
# 仿真文件必须单独建 fileset,且不能混进 sources_1
create_fileset -simset sim_1
add_files -fileset sim_1 ./tb/tb_fifo.v
# 启动综合(异步后台任务)
launch_runs synth_1
⚠️ 注意两个魔鬼细节:
-part xc7z020clg400-1必须和你手头那块 Zybo Z7-20 开发板的 FPGA 封装完全一致。少一个字符(比如写成xc7z020clg400没写-1),后续布局布线会报ERROR: [Place 30-605] Cannot place pins...——因为引脚定义对不上。add_files不带-fileset参数?文件就进了默认 fileset,但那个 fileset 根本不参与综合或约束流程。你会纳闷:'我明明加了 XDC,怎么 Report Timing 里啥都没?'
二、RTL 不是写 Python:每一行都在和综合器博弈
我们写的 Verilog,在 Vivado 眼里不是'程序',而是一张 电路连接蓝图。综合器的任务,是把 always @(posedge clk) 翻译成触发器链,把 assign a = b & c 翻译成 LUT 查找表。它不理解'意图',只认语法模式。
所以,这段代码看着很美,但 根本无法综合 :
// ❌ 危险示范:仿真友好,硬件致盲
integer i;
initial begin
for (i=0; i<16; i=i+1) mem[i] = 0;
end

