| name | vivado-debug |
| description | 当用户需要 Vivado 系统调试、硬件编程或调试核配置方面的帮助时使用此技能。这包括 ILA(集成逻辑分析仪)配置和触发策略、VIO(虚拟 I/O)用于信号监控和控制、JTAG-to-AXI Master 用于生成 AXI 事务、mark_debug 属性和调试探针流程(网表插入、HDL 实例化)、设置调试向导、ILA 交叉触发架构、调试核时序影响和缓解、Vivado 硬件管理器操作、FPGA/SoC 器件编程、Versal 调试架构(AXI4 Debug Hub、CIPS 集成)、SVF 文件编程、调试时钟要求以及常见调试错误故障排除。此技能提供调试策略和决策知识——如需执行 TCL 命令使用 vivado-tcl,如需实现策略使用 vivado-impl,如需时序分析使用 vivado-analysis。 |
Vivado 编程与调试指南
基于 UG908(v2025.2)。此技能帮助选择调试策略、配置调试核和排除硬件调试故障。完整命令语法请参阅 REFERENCE.md。如需执行 TCL,请使用 vivado-tcl。
调试核选择
根据需要观察或控制的内容选择调试核:
| 调试核 | 版本 | 目的 | 关键能力 |
|---|
| ILA(集成逻辑分析仪) | v6.2 | 在系统速度下触发事件并捕获数据 | 波形捕获、高级触发、存储限定 |
| VIO(虚拟输入/输出) | v3.0 | 以 JTAG 扫描速率监控或控制信号 | 实时信号读写,无波形捕获 |
| JTAG-to-AXI Master | v1.2 | 生成 AXI 事务以与 AXI 从机核交互 | 读写 AXI Full 和 AXI Lite 接口 |
| ILA 交叉触发 | (ILA 功能) | 在 ILA 核之间或 ILA 与处理器之间同步触发 | 跨时钟域触发协调 |
决策指南:
需要以全速捕获信号波形?
是 --> ILA
否 --> 需要实时读写信号?
是 --> VIO(低带宽,JTAG 速率)
否 --> 需要读写 AXI 从机寄存器?
是 --> JTAG-to-AXI Master
否 --> 需要跨时钟域协调触发?
是 --> 启用交叉触发的 ILA
调试探针流程选择
添加调试核的四种方法,各有不同权衡:
| 场景 | 流程 | 工作原理 | 适用于 |
|---|
| 在 HDL 中标记信号,稍后使用向导 | mark_debug + 网表插入 | 在 VHDL/Verilog 中添加 mark_debug 属性。综合后,使用设置调试向导插入 ILA 核。 | 灵活性,无需 HDL 更改即可启用/禁用调试 |
| 在综合后网表 GUI 中标记信号 | GUI 标记调试 | 在网表/原理图视图中右键网络并选择标记调试。使用设置调试向导。 | 无需修改源代码快速选择信号 |
| 自动化脚本流程 | TCL 自动化 | 使用 set_property 设置 mark_debug,然后使用 create_debug_core / connect_debug_port TCL 命令。 | 可重复、版本控制的调试插入 |
| HDL 源中的完全控制 | HDL 实例化 | 在 HDL 中手动实例化 ILA/VIO/JTAG-to-AXI Master IP 并连接到信号。 | 每探针比较器控制、交叉触发端口、VIO 核 |
mark_debug 属性
Vivado 综合语法
Verilog:
(* mark_debug = "true" *) wire [7:0] char_fifo_dout;
VHDL:
attribute mark_debug : string;
attribute mark_debug of char_fifo_dout: signal is "true";
有效值:"TRUE" 或 "FALSE"(Vivado 综合不支持 "SOFT" 值)。
config_flows -mark_debug 模式
综合后控制 MARK_DEBUG 行为,无需修改源文件:
| 模式 | 综合行为 | 实现行为 | 何时使用 |
|---|
enable(默认) | 不优化 MARK_DEBUG 网络 | 不优化 MARK_DEBUG 网络 | 活跃调试,需要保留网络 |
disable | 自由优化 | 自由优化 | 生产构建,移除所有调试开销 |
synthesis_only | 不优化(网络在 impl 开始时可用) | 自由优化 | 希望调试网络可用但允许 impl 优化 |
Vivado IDE 中的调试网络图标
空心绿色图标 = MARK_DEBUG 已设置,未连接到任何 ILA 核
实心绿色图标 = MARK_DEBUG 已设置,连接到 ILA 核
黄色图标 = 网络上没有 MARK_DEBUG,但连接到 ILA 核
ILA 配置决策
数据深度选择
C_DATA_DEPTH 属性控制 ILA 存储多少样本。更大深度消耗更多 Block RAM:
| C_DATA_DEPTH | 样本数 | BRAM 影响 | 推荐使用 |
|---|
| 1024(默认) | 1K | 低 | 初始调试,快速触发验证 |
| 2048 | 2K | 低-中等 | 短协议序列 |
| 4096 | 4K | 中等 | 典型协议调试 |
| 8192 | 8K | 中等-高 | 较长事件序列 |
| 16384 | 16K | 高 | 多阶段协议分析 |
| 32768 | 32K | 高 | 大预/后触发窗口的罕见事件捕获 |
| 65536 | 64K | 非常高 | 扩展捕获,确保 BRAM 预算允许 |
| 131072 | 128K | 非常高 | 最大捕获深度,显著资源成本 |
经验法则: 从 1024 开始。仅在需要更多预/后触发上下文时才增加。每次翻倍大致使每个探针位的 BRAM 使用量翻倍。
关键 ILA 属性决策表
| 属性 | 默认值 | 设为 TRUE 时 | 影响 |
|---|
| C_ADV_TRIGGER | false | 需要基于状态机的触发、计数器触发或范围触发 | 添加触发逻辑资源 |
| C_EN_STRG_QUAL | false | 需要基本捕获控制(过滤哪些样本被存储) | 使用 1 个比较器进行捕获控制 |
| C_INPUT_PIPE_STAGES | 0 | ILA 探针输入时序违规;增加到 1-6 | 添加 FF 流水线级,以样本延迟为代价改善时序 |
| C_TRIGIN_EN | false | 需要交叉触发输入(来自另一个 ILA 或处理器) | 添加 TRIG_IN/TRIG_IN_ACK 端口 |
| C_TRIGOUT_EN | false | 需要交叉触发输出(到另一个 ILA 或处理器) | 添加 TRIG_OUT/TRIG_OUT_ACK 端口 |
| C_MEMORY_TYPE(仅 Versal) | 0 (BRAM) | 高 BRAM 利用率,希望使用 UltraRAM | 0=BRAM,1=URAM;URAM 可缓解 BRAM 时序 |
探针配置:数据 / 触发 / 两者
每个探针端口可以独立配置:
| 探针类型 | 捕获数据 | 参与触发 | BRAM 使用 | 何时使用 |
|---|
| 数据和触发 | 是 | 是 | 完整 | 需要同时观察和触发信号(最常见) |
| 仅数据 | 是 | 否 | 完整 | 仅需观察信号值,无需触发 |
| 仅触发 | 否 | 是 | 减少 | 仅需触发信号,不需要波形显示 |
提示: 当不需要波形时,将宽总线配置为"仅触发"可显著减少 BRAM 使用。
匹配单元(比较器)
- 每个探针 1 到 16 个比较器(C_ALL_PROBE_SAME_MU_CNT)
- 如果 C_ADV_TRIGGER=false 且 C_EN_STRG_QUAL=false:可以是 1-16
- 如果 C_ADV_TRIGGER=false 且 C_EN_STRG_QUAL=true:必须是 2-16(1 个保留用于捕获控制)
- 如果 C_ADV_TRIGGER=true 且 C_EN_STRG_QUAL=false:可以是 1-16
- 如果 C_ADV_TRIGGER=true 且 C_EN_STRG_QUAL=true:必须是 2-16
- 每个 ILA 允许的最大比较器:1024
- 如果启用捕获控制,您有 1 到 15 个比较器(1 个保留)
重要: 在网表插入流程中,所有探针共享相同数量的比较器。使用 HDL 实例化流程为每个探针设置不同比较器计数。
ILA 交叉触发
架构
交叉触发实现在不同时钟域的 ILA 核之间,或 ILA 核与处理器(例如 Zynq-7000 SoC)之间的触发协调。
+------------------+ +------------------+
| ILA 1 | | ILA 2 |
| | | |
| trig_in <-----+------------------+-- trig_out |
| trig_in_ack ---+------------------+-> trig_out_ack |
| | | |
| trig_out ------+------------------+-> trig_in |
| trig_out_ack <-+------------------+-- trig_in_ack |
+------------------+ +------------------+
要求:
- 在核生成时启用 C_TRIGIN_EN 和/或 C_TRIGOUT_EN
- 使用 HDL 实例化方法将 TRIG_IN/TRIG_OUT 端口连接到设计网络
- 驱动
trig_in 的逻辑必须与 ILA 时钟同步
交叉触发时序
| 信号 | 延迟 | 备注 |
|---|
| trig_in --> trig_in_ack | 1 时钟周期 | ACK 在 trig_in 置位 1 时钟后置位 |
| trig_in(或触发条件)--> trig_out | 9 时钟周期 | TRIG_OUT 在满足触发条件 9 时钟后置位 |
| trig_in_ack / trig_out_ack 取消置位 | 当触发取消置位时 | 仅当触发信号取消置位时,ACK 信号才变低 |
行为: TRIG_OUT 保持高电平直到收到 TRIG_OUT_ACK。如果 TRIG_OUT_ACK 连接到低,TRIG_OUT 保持高电平直到用户重新武装 ILA。如果 TRIG_OUT_ACK 连接到低,只有 TRIG_OUT 变低。
交叉触发用例
- 从快速时钟域中检测到的事件触发慢时钟域中的 ILA
- 从 Zynq/Versal 处理器上的软件断点触发 ILA 捕获
- 链接多个 ILA 核以捕获设计中事件序列
VIO 使用指南
VIO(虚拟输入/输出)核以 JTAG 扫描速率(而非系统速度)监控和控制信号。
端口类型
| 端口方向 | 硬件视角 | 在 Vivado 中使用 | 典型用途 |
|---|
| 输入端口 | 直接连接到设计信号以监控 | 在 VIO 仪表板中定期刷新读取值 | 状态指示器、计数器值、状态机状态 |
| 输出端口 | 驱动信号到设计以进行控制 | 从 VIO 仪表板或 TCL 写入值 | 复位控制、MUX 选择、使能信号、加载值 |
典型 VIO 用例
- 电路板启动: 切换复位信号,无需重新编译即可启用/禁用子系统
- 状态监控: 实时观察 PLL 锁定、FIFO 满/空、错误标志
- 刺激注入: 以低速将测试模式驱动到数据路径
- ILA 触发协调: 使用 VIO 输出门控 ILA 触发条件
- 寄存器访问替代: 当 JTAG-to-AXI Master 不可用时读写控制寄存器
VIO 操作模型
VIO 基于 set/commit 和 refresh/get 模型操作:
写入流程: set_property OUTPUT_VALUE <val> [get_hw_probes <probe>]
commit_hw_vio [get_hw_probes {<probe>}]
读取流程: refresh_hw_vio [get_hw_vios {hw_vio_1}]
get_property INPUT_VALUE [get_hw_probes <probe>]
推荐刷新率:500 ms 或更长(非常小的值会使 Vivado 变慢)。
JTAG-to-AXI Master
功能
- 支持所有内存映射 AXI Full 和 AXI-Lite 接口
- 32 位或 64 位数据宽度
- 通过 TCL 创建和运行读写突发事务
- 排队操作:最多 16 个读写事务背靠背
典型用例
- 无处理器读写外设寄存器
- 板启动期间验证 AXI 从机 IP 功能
- 注入数据到 AXI 连接的 BRAM 用于测试
- 调试 AXI 互连路由问题
基本事务流程
1. reset_hw_axi [get_hw_axis hw_axi_1]
2. create_hw_axi_txn read_txn [get_hw_axis hw_axi_1] \
-type READ -address 00000000 -len 4
3. run_hw_axi [get_hw_axi_txns read_txn]
4. report_hw_axi_txn [get_hw_axi_txns read_txn]
重要: 如果重新编程设备,所有现有 jtag_axi 事务将被删除,必须重新创建。
Versal 调试架构
Versal 自适应 SoC 使用与 7 series/UltraScale/UltraScale+ 不同的调试基础设施。
CIPS 要求
每个带调试核的 Versal 设计都需要在块设计中有一个控制、接口和处理系统(CIPS)IP 实例:
- 在 IP Integrator 中创建块设计
- 将 CIPS IP 添加到画布
- 生成 HDL 包装器
- 继续网表插入、HDL 实例化或 IP Integrator 调试流程
- 在
opt_design 期间,AXI4 Debug Hub 自动插入并连接
AXI4 Debug Hub
AXI4 Debug Hub 取代了以前架构中使用的基于 BSCAN 的调试 Hub。它通过 AXI4-Stream 将 CIPS AXI4 接口连接到调试核。
Versal 上支持的调试核:
- AXI4-Stream ILA(AXIS-ILA)— 包括 ILA 和 System-ILA 功能
- AXI4-Stream VIO(AXIS-VIO)
- PCI Express 链路调试器
三种连接方法
| 方法 | 自动插入 | 调试核连接 | 何时使用 |
|---|
| 自动 AXI4 Debug Hub 插入和连接 | 是,在 opt_design 期间 | 自动 | 大多数设计(推荐)。不能与 DFX 一起使用。 |
| 手动 AXI4 Debug Hub 实例化,自动调试核连接 | 用户实例化 Debug Hub | 在 opt_design 期间自动 | 需要手动地址分配或使用 DFX。Vivado 用正确配置的替换用户的 Debug Hub。 |
| 手动实例化,手动调试核连接 | 用户实例化 Debug Hub | 用户连接每个核的 AXI4-Stream 主/从 | 完全手动控制。DFX 必需。设置确切的调试核数量。 |
推荐 AXI 连接: 使用 PMC NoC 接口作为 AXI4 Debug Hub。FPD/LPD 接口也可以,但不支持扩展地址范围 0x004_0000_0000 (8G) 和 0x400_0000_0000 (1T)。
BSCAN 后备
当无法使用来自 PS/PMC 的基于 AXI 的接口(例如 AXI 超时)时,BSCAN 后备提供替代通信路径。
| 连接选项 | 描述 | 建议用途 |
|---|
| AXI4 | 仅启用 AXI4 路径 | 大多数硬件调试用例 |
| AXI4, BSCAN 后备 | 两个路径可用,AXI4 默认 | 系统级 AXI 超时调试 |
| AXI4, BSCAN 后备(BSCAN 默认) | 两个路径可用,BSCAN 默认 | 启动时无法访问 AXI 路径 |
| AXI4(未连接),BSCAN(默认) | 仅 BSCAN 路径 | 独占 BSCAN 连接到 Debug Hub |
启用 BSCAN 后备的步骤:
- 手动实例化 AXI4 Debug Hub(无法在自动插入的 hub 上启用)
- 在 CIPS/PS Wizard 上启用 BSCAN 端口
- 在 Debug Hub 和 Processing System 之间实例化 BSCAN Switch IP
- 将 AXI4 接口(如果使用)连接到所需 PS 接口(例如 NoC)
- 连接 aclk 和 aresetn 端口
调试时序影响与缓解
ILA 核可能影响设计时序。添加调试核后出现时序违规时,请遵循此决策树:
添加调试核后出现时序违规?
|
+-- 违规路径在 ILA 或 AXIS-ILA 核探针输入中?
| |
| 是 --> 增加 C_INPUT_PIPE_STAGES(尝试 1,然后增加到 6)
| 仍然失败? --> 尝试 URAM 存储(Versal:C_MEMORY_TYPE=1)
| 仍然失败? --> 尝试 impl 策略:
| Performance_Explore 或
| Performance_ExtraTimingOpt
|
+-- 违规路径在 debug_hub (dbg_hub) 核中?
| |
| 是 --> 1. 将 C_CLK_INPUT_FREQ_HZ 设置为实际时钟频率
| 2. 将 C_ENABLE_CLK_DIVIDER 设置为 true
| 3. 重新实现设计
| (这添加 MMCM 时钟分频器以在内部实现 ~100 MHz)
|
+-- 违规路径在其他地方但因调试而恶化?
|
是 --> 1. 在添加调试核之前关闭时序
2. 选择更窄的探针宽度
3. 减少 C_DATA_DEPTH
4. 使用 Performance_Explore impl 策略
5. 对于 Versal:为 AXI4-Debug Hub 使用 100-250 MHz 时钟
额外时序指南:
- 确保 ILA 时钟是自由运行且稳定的
- 确保 ILA 时钟与被探测的信号同步
- 如果时钟来自 MMCM/PLL,确保 LOCKED 信号在调试操作之前为高
- AMD 建议 Debug Hub 时钟频率约为 100 MHz
硬件调试六步流程
使用 ILA 调试核在硬件中调试设计的步骤:
1. 连接到硬件目标并编程 FPGA/SoC
--> open_hw_manager
--> connect_hw_server -url localhost:3121
--> program_hw_devices [lindex [get_hw_devices] 0]
2. 设置 ILA:配置触发和捕获控制
--> 在触发设置窗口中添加探针
--> 设置比较值、运算符、进制
--> 选择触发模式:BASIC_ONLY 或 ADVANCED(状态机)
--> 配置捕获模式:ALWAYS 或条件
3. 武装 ILA 触发
--> run_hw_ila hw_ila_1
4. 在波形窗口中查看捕获的数据
--> wait_on_hw_ila hw_ila_1
--> display_hw_ila_data [upload_hw_ila_data hw_ila_1]
5. 使用 VIO 核驱动控制信号并查看状态
--> 在 VIO 仪表板中添加探针
--> 设置 OUTPUT_VALUE 并 commit_hw_vio
--> 读取 refresh_hw_vio 后的 INPUT_VALUE
6. 使用 JTAG-to-AXI Master 运行 AXI 事务
--> reset_hw_axi, create_hw_axi_txn, run_hw_axi
调试时钟要求
对于非 Versal 架构(7 series、UltraScale、UltraScale+):
按调试阶段的时钟要求
| 调试阶段 | JTAG 时钟 | Debug Hub 时钟 | 调试核时钟 |
|---|
| 连接到目标 | 稳定 | N/A | N/A |
| 编程 | 稳定 | N/A | N/A |
| 调试核发现 | 稳定 | 稳定 | N/A |
| 调试核测量 | 稳定 | 稳定 | 稳定 |
注:
- "稳定" = 事件期间不暂停/停止的时钟
- 调试核时钟列假设调试核时钟与 Debug Hub 时钟不同
- 调试核测量包括对调试核的任何属性
get 或 set
2.5 倍 JTAG 规则
对于非 Versal 架构: 如果设计包含调试核,确保 JTAG 时钟比 Debug Hub 时钟慢 2.5 倍。
JTAG_clock_frequency < Debug_Hub_clock_frequency / 2.5
示例:如果 Debug Hub 时钟是 100 MHz,JTAG 必须 < 40 MHz。
降低 JTAG 频率:
set_property PARAM.FREQUENCY 250000 [get_hw_targets \
*/xilinx_tcf/Digilent/210203327962A]
AMD 建议 Debug Hub 时钟频率约为 100 MHz。可以更改 Debug Hub 时钟:
connect_debug_port dbg_hub/clk [get_nets <clock net name>]
Versal 时钟
Versal 调试核使用基于 AXI 的连接,不受 BSCAN 时序指南约束。对于 Versal,如果在添加调试核后观察到时序故障,请为 AXI4-Debug Hub 使用 100-250 MHz 之间的时钟。
常见错误故障排除
"debug hub not detected"
错误消息:
INFO: [Labtools 27-1434] Device xxx (JTAG device index = 0) is programmed
with a design that has no supported debug core(s) in it.
WARNING: [Labtools 27-3123] The debug hub core was not detected at User
Scan Chain 1 or 3.
原因和解决方案:
- Debug Hub 时钟不是自由运行或不活跃
- 确保连接到
dbg_hub 核的时钟是自由运行且稳定的
- 如果来自 MMCM/PLL,验证 LOCKED 为高
- 用户扫描链不匹配
- 使用以下命令启动 hw_server:
hw_server -e "set xsdb-user-bscan <C_USER_SCAN_CHAIN scan_chain_number>" 在用户扫描链 2 或 4 上检测调试 hub
- 检查设置:
get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub]
- BSCAN_SWITCH_USER_MASK 设置不正确
"unrecognizable debug core"
错误消息:
CRITICAL WARNING: [Labtools 27-1433] Device xxx is programmed
with a design that has an unrecognizable debug core (slave type = 17) at
user chain = 1, index = 0.
Resolution:
1) Ensure that the clock signal connected to the debug core and/or debug
hub is clean and free-running.
2) Ensure that the clock connected to the debug core and/or debug hub meets
all timing constraints.
3) Ensure that the clock connected to debug core and/or debug hub is faster
than the JTAG clock frequency.
原因和解决方案:
- 调试核时钟不活跃或不稳定
- 调试核时钟比 JTAG 时钟慢
- 降低 JTAG 频率或使用更快的调试时钟
- 记住 2.5 倍规则:调试 hub 时钟必须 > 2.5 倍 JTAG 时钟
- 调试 hub 或调试核中的时序违规
- 在 dbg_hub 上启用时钟分频器(C_ENABLE_CLK_DIVIDER)
- 在 ILA 上添加输入管道级(C_INPUT_PIPE_STAGES)
Debug Bridge IP 冲突
错误消息:
[Chipscope 16-336] Failed to find or create hub core for debug slave
<debug core name>. Insertion of debug hub is not supported when there are
instantiated debug bridge cores in either master mode or switch enabled in
the design.
解决方案: 确保设计至少有一个处于 BSCAN-to-Debug Hub 模式的 Debug Bridge IP。或者移除调试从机核或在调试从机区域实例化调试桥接主核。
SVF 文件编程
串行向量格式(SVF)提供离线 FPGA/配置内存编程,无需实时 JTAG 连接。
注意: SVF 编程在 AMD Versal 器件上不支持。
SVF 文件创建流程
1. create_hw_target my_svf_target ;# 创建离线 SVF 目标
2. open_hw_target ;# 打开 SVF 目标
3. create_hw_device -part <part> ;# 添加器件以定义 JTAG 链
4. set_property PROGRAM.FILE {file.bit} $device
program_hw_devices $device ;# 记录编程操作
5. write_hw_svf my_output.svf ;# 将缓存的操作写入 SVF 文件
6. close_hw_target ;# 关闭 SVF 目标
重要: 首先创建链中的所有器件,然后执行编程操作。交错 create_hw_device 和 program_hw_devices 会产生不正确的 SVF 序列。
SVF 执行
execute_hw_svf my_file.svf
- 使用
-verbose 选项查看 JTAG_TCL 操作
- 大小限制: Vivado 支持小于 500 MB 的 SVF 文件。对于更大的文件,使用第三方 SVF 播放器。
- XSVF 文件格式在 Vivado IDE 中不支持。
调试可配置报告策略
report_debug_core 使用
插入调试核后,使用 report_debug_core 验证调试配置:
# 报告设计中的所有调试核
report_debug_core
# 报告的关键信息:
# - 调试核实例和类型
# - 连接的探针网络和宽度
# - 时钟域分配
# - 核属性(C_DATA_DEPTH、C_ADV_TRIGGER 等)
有用的调试验证命令
| 命令 | 目的 |
|---|
report_debug_core | 列出所有调试核、它们的探针和属性 |
get_debug_cores | 返回设计中调试核对象列表 |
get_debug_ports | 返回调试端口对象列表 |
report_property [get_debug_cores u_ila_0] | 显示特定 ILA 核的所有属性 |
get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub] | 检查 BSCAN 用户扫描链设置 |
get_property C_DATA_DEPTH [get_debug_cores u_ila_0] | 检查 ILA 捕获深度 |
report_hw_targets | 报告所有活动硬件目标、器件和属性 |
实现后调试验证
# 实现后,验证调试核完整
open_run impl_1
report_debug_core
report_utilization -cells [get_cells -hierarchical -filter {IS_DEBUG_CORE}]
# 编程后检查 DONE 状态
get_property REGISTER.IR.BIT5_DONE [lindex [get_hw_devices] 0]
# 对于 Versal 器件(不同的寄存器)
get_property REGISTER.JTAG_STATUS.BIT[34]_DONE [lindex [get_hw_devices] 1]