基于 Vivado 2024.1,适用于 Linux 环境(Ubuntu 22.04/24.04)
涵盖 Project Mode 与 Non-Project Mode 两种工作流
目录
- [Vivado 命令行模式概览](#Vivado 命令行模式概览)
- 两种工作流对比
- [Non-Project Mode(推荐用于自动化)](#Non-Project Mode(推荐用于自动化))
- [Project Mode(推荐用于团队协作)](#Project Mode(推荐用于团队协作))
- [IP 核的纯命令行处理](#IP 核的纯命令行处理)
- 增量构建与缓存优化
- [Makefile 封装示例](#Makefile 封装示例)
- [CI/CD 集成(GitHub Actions)](#CI/CD 集成(GitHub Actions))
- 常见问题排查
1. Vivado 命令行模式概览
Vivado 提供三种命令行模式:
| 模式 | 启动命令 | 特点 | 适用场景 |
|---|---|---|---|
| Batch | vivado -mode batch -source script.tcl |
执行完脚本自动退出,无 GUI | 自动化构建、CI/CD |
| Tcl | vivado -mode tcl |
交互式 Tcl Shell,不启动 GUI | 调试脚本、交互式操作 |
| GUI | vivado |
完整图形界面 | 开发调试、可视化分析 |
1.1 启动 Batch 模式
bash
# 基本用法
vivado -mode batch -source build.tcl
# 传递参数给 Tcl 脚本
vivado -mode batch -source build.tcl -tclargs "PART=xc7k325tffg900-2" "TOP=top_module"
# 重定向日志
vivado -mode batch -source build.tcl -log build.log -journal build.jou
# 多线程加速( synthesis 和 implementation 并行)
vivado -mode batch -source build.tcl -jobs 4
1.2 环境变量配置
bash
# 添加到 ~/.bashrc 或 ~/.bash_profile
export PATH=/tools/Xilinx/Vivado/2024.1/bin:$PATH
# 设置许可证服务器(如有浮动许可)
export XILINXD_LICENSE_FILE=2100@license_server
# 设置 Vivado 缓存目录(避免默认目录空间不足)
export XILINX_VIVADO_CACHE=/tmp/vivado_cache
mkdir -p $XILINX_VIVADO_CACHE
2. 两种工作流对比
| 特性 | Non-Project Mode | Project Mode |
|---|---|---|
| 项目文件 | 无 .xpr 文件 |
生成 .xpr 项目文件 |
| 设计状态 | 纯内存操作,退出即丢失 | 自动保存到磁盘 |
| 源文件管理 | 手动控制,灵活 | 自动管理,有版本跟踪 |
| 中间文件 | 手动写 checkpoint | 自动生成在 runs 目录 |
| 报告生成 | 手动执行 report 命令 | 自动按策略生成 |
| IP 集成 | 需预生成 IP 输出产品 | 自动管理 IP 输出产品 |
| OOC 综合 | 不支持 | 支持(IP 级增量综合) |
| GUI 交叉探测 | 有限支持 | 完整支持 |
| CI/CD 友好度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 团队协作 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
选择建议:
- 自动化构建 / CI/CD → Non-Project Mode
- 团队协作 / 需要 GUI 调试 → Project Mode
- 两者不可混用,命令集完全不同
3. Non-Project Mode(推荐用于自动化)
Non-Project Mode 是纯内存流,没有项目文件,完全由 Tcl 脚本控制。这是** CI/CD 和自动化构建的首选**。
3.1 完整构建脚本
tcl
#!/bin/bash
# build_non_project.sh
# 用法: ./build_non_project.sh [part_number] [top_module]
# 示例: ./build_non_project.sh xcku5p-ffvb676-2 top
vivado -mode batch -source - <<'TCL_EOF'
# ============================================================
# 配置参数(可通过 -tclargs 传入)
# ============================================================
set part [lindex $argv 0]
set top_module [lindex $argv 1]
set output_dir [lindex $argv 2]
# 默认值
if {$part eq ""} {set part xcku5p-ffvb676-2}
if {$top_module eq ""} {set top_module top}
if {$output_dir eq ""} {set output_dir ./build}
puts "============================================================"
puts "FPGA Non-Project Build Flow"
puts "Part: $part"
puts "Top Module: $top_module"
puts "Output Dir: $output_dir"
puts "============================================================"
# 创建输出目录
file mkdir $output_dir
file mkdir $output_dir/reports
file mkdir $output_dir/checkpoints
# ============================================================
# STEP 1: 读取设计源文件
# ============================================================
puts "
### STEP 1: Reading Design Sources ###"
# Verilog 源文件
read_verilog [glob ./rtl/*.v]
read_verilog [glob ./rtl/submodules/*.v]
# SystemVerilog 源文件(如有)
# read_verilog -sv [glob ./rtl/*.sv]
# VHDL 源文件(如有)
# read_vhdl ./rtl/top.vhd
# read_vhdl -library work [glob ./rtl/lib/*.vhd]
# 约束文件
read_xdc ./constraints/top.xdc
read_xdc ./constraints/timing.xdc
# IP 核(预生成的 .xci 文件)
# read_ip ./ip/clk_wiz_0/clk_wiz_0.xci
# read_ip ./ip/ila_0/ila_0.xci
# 如有 EDIF/NGC 网表
# read_edif ./netlist/core.edif
# ============================================================
# STEP 2: 综合 (Synthesis)
# ============================================================
puts "
### STEP 2: Running Synthesis ###"
synth_design -top $top_module -part $part -flatten_hierarchy rebuilt
# 综合后报告
report_timing_summary -file $output_dir/reports/post_synth_timing.rpt -delay_type max
report_utilization -file $output_dir/reports/post_synth_util.rpt -hierarchical
report_power -file $output_dir/reports/post_synth_power.rpt
# 保存综合后 checkpoint
write_checkpoint -force $output_dir/checkpoints/post_synth.dcp
# ============================================================
# STEP 3: 优化 (Optimization)
# ============================================================
puts "
### STEP 3: Running Optimization ###"
opt_design
# opt_design -directive Explore # 使用更激进的优化策略
# 可选:功耗优化
# power_opt_design
# 优化后报告
report_drc -file $output_dir/reports/post_opt_drc.rpt
# ============================================================
# STEP 4: 布局 (Placement)
# ============================================================
puts "
### STEP 4: Running Placement ###"
place_design
# place_design -directive Explore # 探索更多布局方案
# 物理优化(可选,改善时序)
phys_opt_design
# phys_opt_design -directive AggressiveExplore
# 布局后报告
report_timing_summary -file $output_dir/reports/post_place_timing.rpt -delay_type min_max
report_clock_utilization -file $output_dir/reports/post_place_clock.rpt
report_utilization -file $output_dir/reports/post_place_util.rpt
# 保存布局后 checkpoint
write_checkpoint -force $output_dir/checkpoints/post_place.dcp
# ============================================================
# STEP 5: 布线 (Routing)
# ============================================================
puts "
### STEP 5: Running Routing ###"
route_design
# route_design -directive Explore # 探索更多布线方案
# 布线后报告
report_timing_summary -file $output_dir/reports/post_route_timing.rpt -delay_type min_max -report_unconstrained -max_paths 10
report_timing -sort_by group -max_paths 100 -path_type summary -file $output_dir/reports/post_route_timing_detail.rpt
report_clock_utilization -file $output_dir/reports/post_route_clock.rpt
report_utilization -file $output_dir/reports/post_route_util.rpt -hierarchical
report_power -file $output_dir/reports/post_route_power.rpt
report_drc -file $output_dir/reports/post_route_drc.rpt
report_route_status -file $output_dir/reports/post_route_status.rpt
# 保存布线后 checkpoint
write_checkpoint -force $output_dir/checkpoints/post_route.dcp
# 导出网表和约束(用于仿真或形式验证)
write_verilog -force $output_dir/${top_module}_impl_netlist.v
write_xdc -no_fixed_only -force $output_dir/${top_module}_impl.xdc
# ============================================================
# STEP 6: 生成 Bitstream
# ============================================================
puts "
### STEP 6: Generating Bitstream ###"
# Bitstream 配置
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
# 生成 bitstream
write_bitstream -force $output_dir/${top_module}.bit
# 同时生成 .bin 文件(用于 Flash 烧写)
write_bitstream -force -bin_file $output_dir/${top_module}.bin
# ============================================================
# STEP 7: 生成调试文件(如有 ILA)
# ============================================================
# write_debug_probes -force $output_dir/${top_module}.ltx
# ============================================================
# 构建完成
# ============================================================
puts "
============================================================"
puts "Build Completed Successfully!"
puts "Output files:"
puts " Bitstream: $output_dir/${top_module}.bit"
puts " Binary: $output_dir/${top_module}.bin"
puts " Reports: $output_dir/reports/"
puts " Checkpoints: $output_dir/checkpoints/"
puts "============================================================"
TCL_EOF
3.2 运行脚本
bash
chmod +x build_non_project.sh
./build_non_project.sh xcku5p-ffvb676-2 top ./build
3.3 仅综合(不跑实现)
bash
vivado -mode batch -source - <<'EOF'
read_verilog [glob ./rtl/*.v]
read_xdc ./constraints/top.xdc
synth_design -top top -part xcku5p-ffvb676-2
write_checkpoint -force ./build/post_synth.dcp
report_timing_summary -file ./build/post_synth_timing.rpt
EOF
3.4 从已有 Checkpoint 继续
bash
vivado -mode batch -source - <<'EOF'
open_checkpoint ./build/post_synth.dcp
opt_design
place_design
route_design
write_bitstream -force ./build/top.bit
EOF
4. Project Mode(推荐用于团队协作)
Project Mode 生成 .xpr 项目文件,适合需要 GUI 调试和团队协作的场景。
4.1 完整构建脚本
tcl
#!/bin/bash
# build_project.sh
vivado -mode batch -source - <<'TCL_EOF'
# ============================================================
# 配置参数
# ============================================================
set project_name "my_fpga_project"
set project_dir "./project"
set part "xcku5p-ffvb676-2"
set top_module "top"
puts "============================================================"
puts "FPGA Project Mode Build Flow"
puts "Project: $project_name"
puts "Part: $part"
puts "============================================================"
# 创建项目
create_project -force $project_name $project_dir -part $part
# 设置项目属性
set_property target_language Verilog [current_project]
set_property default_lib work [current_project]
set_property simulator_language Mixed [current_project]
set_property ip_output_repo $project_dir/ip_cache [current_project]
set_property ip_cache_permissions {read write} [current_project]
# ============================================================
# 添加源文件
# ============================================================
puts "
### Adding Sources ###"
# Verilog 源文件
add_files [glob ./rtl/*.v]
add_files [glob ./rtl/submodules/*.v]
# VHDL 源文件(如有)
# add_files [glob ./rtl/*.vhd]
# set_property library work [get_files *.vhd]
# 约束文件
add_files -fileset constrs_1 [glob ./constraints/*.xdc]
# IP 核(.xci 文件)
# add_files [glob ./ip/*/*.xci]
# 仿真文件
# add_files -fileset sim_1 [glob ./tb/*.v]
# 设置顶层模块
set_property top $top_module [get_filesets sources_1]
update_compile_order -fileset sources_1
# ============================================================
# 综合
# ============================================================
puts "
### Running Synthesis ###"
launch_runs synth_1 -jobs 4
wait_on_run synth_1
# 检查综合结果
set synth_status [get_property STATUS [get_runs synth_1]]
if {$synth_status ne "synth_design Complete!"} {
puts "ERROR: Synthesis failed with status: $synth_status"
exit 1
}
# 打开综合设计生成报告
open_run synth_1 -name synth_netlist
report_timing_summary -file $project_dir/post_synth_timing.rpt -delay_type max
report_utilization -file $project_dir/post_synth_util.rpt -hierarchical
close_design
# ============================================================
# 实现
# ============================================================
puts "
### Running Implementation ###"
# 设置实现策略(可选)
# set_property strategy Performance_Explore [get_runs impl_1]
launch_runs impl_1 -to_step write_bitstream -jobs 4
wait_on_run impl_1
# 检查实现结果
set impl_status [get_property STATUS [get_runs impl_1]]
if {$impl_status ne "write_bitstream Complete!"} {
puts "ERROR: Implementation failed with status: $impl_status"
exit 1
}
# ============================================================
# 生成报告
# ============================================================
puts "
### Generating Reports ###"
open_run impl_1
report_timing_summary -file $project_dir/post_impl_timing.rpt -delay_type min_max -report_unconstrained -max_paths 10
report_utilization -file $project_dir/post_impl_util.rpt -hierarchical
report_power -file $project_dir/post_impl_power.rpt
report_drc -file $project_dir/post_impl_drc.rpt
close_design
# ============================================================
# 复制输出文件
# ============================================================
puts "
### Copying Output Files ###"
file mkdir $project_dir/output
set bitstream_file [glob $project_dir/$project_name.runs/impl_1/*.bit]
file copy -force $bitstream_file $project_dir/output/${top_module}.bit
# 如有 bin 文件
set bin_file [glob -nocomplain $project_dir/$project_name.runs/impl_1/*.bin]
if {[llength $bin_file] > 0} {
file copy -force $bin_file $project_dir/output/${top_module}.bin
}
puts "
============================================================"
puts "Build Completed Successfully!"
puts "Bitstream: $project_dir/output/${top_module}.bit"
puts "============================================================"
TCL_EOF
4.2 从已有项目继续构建
bash
vivado -mode batch -source - <<'EOF'
open_project ./project/my_fpga_project.xpr
reset_run synth_1
launch_runs synth_1 -jobs 4
wait_on_run synth_1
launch_runs impl_1 -to_step write_bitstream -jobs 4
wait_on_run impl_1
close_project
EOF
4.3 导出项目为 Tcl 脚本(用于版本控制)
bash
# 在 Vivado GUI 中或命令行中执行
vivado -mode batch -source - <<'EOF'
open_project ./project/my_fpga_project.xpr
# 导出为可重建的 Tcl 脚本
write_project_tcl -force ./project_recreate.tcl
# 或使用 -no_copy_sources 保持引用原始文件
write_project_tcl -no_copy_sources -force ./project_recreate.tcl
close_project
EOF
5. IP 核的纯命令行处理
5.1 预生成 IP 输出产品(Non-Project Mode 必需)
bash
vivado -mode batch -source - <<'EOF'
# 读取 IP 配置
read_ip ./ip/clk_wiz_0/clk_wiz_0.xci
# 生成 IP 输出产品(OOC 综合、约束、仿真模型等)
generate_target all [get_ips]
# 单独综合 IP(OOC 模式)
synth_ip [get_ips clk_wiz_0]
EOF
5.2 创建和配置 IP(纯 Tcl)
bash
vivado -mode batch -source - <<'EOF'
# 创建 IP 目录
file mkdir ./ip
# 创建时钟向导 IP
create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name clk_wiz_0 -dir ./ip
# 配置 IP 参数
set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} CONFIG.CLKOUT1_USED {true} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {200.000} CONFIG.CLKOUT2_USED {true} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {100.000} CONFIG.USE_LOCKED {true} CONFIG.USE_RESET {true} CONFIG.RESET_TYPE {ACTIVE_LOW} ] [get_ips clk_wiz_0]
# 生成输出产品
generate_target all [get_ips clk_wiz_0]
# OOC 综合
synth_ip [get_ips clk_wiz_0]
EOF
5.3 批量处理所有 IP
bash
vivado -mode batch -source - <<'EOF'
# 读取所有 IP
set ip_files [glob ./ip/*/*.xci]
foreach ip_file $ip_files {
read_ip $ip_file
}
# 生成所有 IP 输出产品
generate_target all [get_ips]
# OOC 综合所有 IP
foreach ip [get_ips] {
synth_ip $ip
}
EOF
6. 增量构建与缓存优化
6.1 使用 DCP 实现增量综合
bash
vivado -mode batch -source - <<'EOF'
# 检查是否有上次的综合 checkpoint
if {[file exists ./build/post_synth.dcp]} {
puts "Using existing synthesis checkpoint..."
open_checkpoint ./build/post_synth.dcp
} else {
puts "Running full synthesis..."
read_verilog [glob ./rtl/*.v]
read_xdc ./constraints/top.xdc
synth_design -top top -part xcku5p-ffvb676-2
write_checkpoint -force ./build/post_synth.dcp
}
# 继续实现流程
opt_design
place_design
route_design
write_bitstream -force ./build/top.bit
EOF
6.2 增量实现(Incremental Implementation)
bash
vivado -mode batch -source - <<'EOF'
read_checkpoint -incremental ./build/reference_post_route.dcp
read_verilog [glob ./rtl/*.v]
read_xdc ./constraints/top.xdc
synth_design -top top -part xcku5p-ffvb676-2
opt_design
place_design
route_design
# 增量实现会自动复用上次布局布线结果
write_checkpoint -force ./build/post_route.dcp
write_bitstream -force ./build/top.bit
EOF
6.3 IP 缓存
bash
# 设置 IP 缓存目录(避免重复综合)
export XILINX_IP_CACHE=/shared/ip_cache
mkdir -p $XILINX_IP_CACHE
vivado -mode batch -source - <<'EOF'
set_property ip_output_repo /shared/ip_cache [current_project]
set_property ip_cache_permissions {read write} [current_project]
EOF
7. Makefile 封装示例
makefile
# Makefile for FPGA Build
# 用法: make PART=xcku5p-ffvb676-2 TOP=top
PART ?= xcku5p-ffvb676-2
TOP ?= top
BUILD_DIR ?= ./build
RTL_DIR ?= ./rtl
CONSTR_DIR ?= ./constraints
VIVADO ?= vivado
JOBS ?= 4
.PHONY: all clean synth impl bitstream program reports
all: bitstream
# 创建构建目录
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)/reports
mkdir -p $(BUILD_DIR)/checkpoints
# 综合
synth: $(BUILD_DIR)
$(VIVADO) -mode batch -source scripts/synth.tcl -tclargs "PART=$(PART)" "TOP=$(TOP)" "OUTDIR=$(BUILD_DIR)" -log $(BUILD_DIR)/synth.log
# 实现(从综合 checkpoint)
impl: synth
$(VIVADO) -mode batch -source scripts/impl.tcl -tclargs "TOP=$(TOP)" "OUTDIR=$(BUILD_DIR)" -log $(BUILD_DIR)/impl.log
# 生成 bitstream
bitstream: impl
$(VIVADO) -mode batch -source scripts/bitstream.tcl -tclargs "TOP=$(TOP)" "OUTDIR=$(BUILD_DIR)" -log $(BUILD_DIR)/bitstream.log
# 生成所有报告
reports: bitstream
$(VIVADO) -mode batch -source scripts/reports.tcl -tclargs "TOP=$(TOP)" "OUTDIR=$(BUILD_DIR)"
# 下载到 FPGA
program: bitstream
$(VIVADO) -mode batch -source scripts/program.tcl -tclargs "BITFILE=$(BUILD_DIR)/$(TOP).bit"
# 清理
clean:
rm -rf $(BUILD_DIR)
rm -rf .Xil
rm -f *.log *.jou
rm -f vivado*.str
# 深度清理(包括 IP 缓存)
distclean: clean
rm -rf ./ip/*/run
rm -rf ./ip/*/*.cache
scripts/synth.tcl
tcl
set part [lindex $argv 0]
set top [lindex $argv 1]
set output_dir [lindex $argv 2]
read_verilog [glob ../rtl/*.v]
read_xdc ../constraints/top.xdc
synth_design -top $top -part $part
write_checkpoint -force $output_dir/checkpoints/post_synth.dcp
report_timing_summary -file $output_dir/reports/post_synth_timing.rpt
report_utilization -file $output_dir/reports/post_synth_util.rpt
8. CI/CD 集成(GitHub Actions)
yaml
# .github/workflows/fpga-build.yml
name: FPGA Build
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 设置 Vivado 环境(需自行安装或挂载 Docker 镜像)
- name: Setup Vivado
run: |
# 方法1: 使用预装 Vivado 的 Docker 镜像
docker pull vivado:2024.1
# 方法2: 挂载网络共享的 Vivado 安装
# sudo mount -t nfs server:/tools/Xilinx /tools/Xilinx
- name: Build FPGA
run: |
# 在 Docker 中运行构建
docker run --rm -v $(pwd):/workspace -w /workspace vivado:2024.1 bash -c "source /tools/Xilinx/Vivado/2024.1/settings64.sh && make all"
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: bitstream
path: |
build/*.bit
build/*.bin
build/reports/*.rpt
- name: Check Timing
run: |
# 解析时序报告,检查是否有违例
if grep -q "Timing constraints are not met" build/reports/post_route_timing.rpt; then
echo "ERROR: Timing violations detected!"
exit 1
fi
echo "Timing check passed."
9. 常见问题排查
9.1 综合失败
bash
# 检查日志
tail -n 100 build/synth.log
# 常见问题:
# 1. 缺少源文件
# 2. 语法错误(Verilog/VHDL)
# 3. 顶层模块名不匹配
# 4. IP 未预生成
9.2 时序违例
tcl
# 在脚本中自动检查时序
set timing_report [report_timing_summary -return_string]
if {[string match "*VIOLATED*" $timing_report]} {
puts "WARNING: Timing violations detected!"
# 可选:退出并标记构建失败
# exit 1
}
9.3 资源超量
tcl
# 检查资源利用率
set util_report [report_utilization -return_string]
# 解析 LUT/FF/BRAM/DSP 使用率,超过阈值则报警
9.4 许可证问题
bash
# 检查许可证状态
vivado -mode batch -source - <<'EOF'
report_environment -file license_check.txt
EOF
# 或查看 lmstat
lmstat -c 2100@license_server -a
9.5 多线程问题
bash
# Vivado 综合/实现支持多线程
# 设置最大并行 job 数
vivado -mode batch -source - <<'EOF'
set_param general.maxThreads 8
launch_runs impl_1 -jobs 8
EOF
附录:常用 Tcl 命令速查
| 命令 | 用途 |
|---|---|
read_verilog |
读取 Verilog 源文件 |
read_vhdl |
读取 VHDL 源文件 |
read_xdc |
读取约束文件 |
read_ip |
读取 IP 核配置 |
read_edif |
读取 EDIF 网表 |
synth_design |
综合设计 |
opt_design |
逻辑优化 |
place_design |
布局 |
phys_opt_design |
物理优化 |
route_design |
布线 |
write_checkpoint |
保存设计检查点 |
open_checkpoint |
打开检查点 |
write_bitstream |
生成 bitstream |
report_timing_summary |
时序报告 |
report_utilization |
资源利用率报告 |
report_power |
功耗报告 |
report_drc |
设计规则检查 |
create_project |
创建项目(Project Mode) |
add_files |
添加文件(Project Mode) |
launch_runs |
启动运行(Project Mode) |
wait_on_run |
等待运行完成(Project Mode) |
参考文档
- AMD UG892: Vivado Design Flows Overview
- AMD UG893: Using the Vivado IDE
- AMD UG894: Vivado Implementation
- AMD UG895: System-Level Design Entry
- AMD UG835: Vivado Tcl Command Reference Guide
- AMD UG896: Designing with IP
- AMD UG900: Logic Simulation
- AMD UG908: Programming and Debugging
本教程基于 Vivado 2024.1 编写,适用于 7 系列、UltraScale、UltraScale+ 及 Versal 器件。