FPGA 进阶实战 · 05 双时钟约束与实现审查
从真实时钟关系出发,约束握手数据路径,防止全局例外掩盖跨域问题。
先修知识完成 FPGA FIFO 六章基础实战;理解同步时序、非阻塞赋值与 ready/valid。
适用环境Basys 3 / xc7a35tcpg236-1;板上 100/50 MHz 同源时钟;Icarus Verilog、Python 3;Vivado 2024.1 命令参考。
验证状态三组时钟 RTL 测试、两类负向测试及板上自检器的软件模型已通过;Vivado、物理 CDC 和 ILA 上板尚需实测。
先分清两个时钟的关系
板上两个时钟由同一 Clocking Wizard 生成,具有工具可追踪的频率和相位关系;使用握手结构并不会把它们自动变成异步时钟。软件测试额外使用不同周期和初相位,是为了检验协议的事件排列。两者各有目的,约束必须描述实际硬件时钟网络,而不是照着测试平台的时钟产生语句填写。
理解两个数据路径上限
源端数据只有在请求往返期间保持稳定,才能在目的域可靠采样。本工程给出源保持寄存器到 FIFO 存储的二十纳秒上限,以及返回寄存器到源端结果寄存器的十纳秒上限,用来限制真实路由时间。它们结合了当前频率和状态机提供的稳定窗口,并非可复制到所有 CDC 结构的固定常数;改变时钟或采样状态必须重新分析预算。
| 约束对象 | 审查依据 |
|---|---|
| req/ack 首级 D | 异步控制入口;后续同步级仍计时 |
| 复位同步器 PRE | 仅共同异步断言路径,释放由本域同步链处理 |
| held_data → FIFO 存储 | 全部有效位覆盖,20 ns datapath-only |
| return_data → 源 result | 全部有效位覆盖,10 ns datapath-only |
| 禁止宽泛时钟组例外 | 避免覆盖数据最大延时约束 |
| report_cdc 的总线提示 | 根据保持协议与路径证据逐项审查,不自动豁免 |
Basys 3 专用完整约束;综合网表端点需在实际 Vivado 中确认。
# Basys 3 only; verify physical board revision and bank voltages.
set_property PACKAGE_PIN W5 [get_ports clk]
set_property PACKAGE_PIN U18 [get_ports btnC]
set_property PACKAGE_PIN U16 [get_ports {led[0]}]
set_property PACKAGE_PIN E19 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {clk btnC led[*]}]
create_clock -name sys_clk -period 10.000 [get_ports clk]
# Clocking Wizard/MMCM generates related 100/50 MHz clocks. DO NOT group async.
set_false_path -to [get_ports {led[*]}]
# btnC or loss of MMCM lock asserts reset; ONLY reset synchronizer async pins.
set reset_pins [get_pins -hier -filter {NAME =~ *u_reset_*/pipe_reg*/PRE}]
if {[llength $reset_pins]!=6} {error "ADV_XDC: inspect reset synchronizer PRE pins"}
set_false_path -to $reset_pins
# Control synchronizers: first stage only, not subsequent stages.
foreach name {req_meta ack_meta} {
set pin [get_pins -hier -filter "NAME =~ *u_cdc/${name}_reg/D"]
if {[llength $pin]!=1} {error "ADV_XDC: missing first-stage pin $name"}
set_false_path -to $pin
}
# Bundled-data physical bounds. Full handshake keeps data stable well beyond these limits.
set tx [get_cells -hier -filter {NAME =~ *u_cdc/held_data_reg*}]
set rx [get_cells -hier -filter {NAME =~ *u_cdc/u_fifo/mem_reg*}]
set back [get_cells -hier -filter {NAME =~ *u_cdc/return_data_reg*}]
set result [get_cells -hier -filter {NAME =~ *u_cdc/result_reg*}]
foreach group [list $tx $rx $back $result] {
if {[llength $group]==0} {error "ADV_XDC: bundled-data endpoints missing; inspect synthesized hierarchy"}
}
set_max_delay 20.000 -datapath_only -from $tx -to $rx
set_max_delay 10.000 -datapath_only -from $back -to $result
# No blanket set_clock_groups/set_false_path across data paths.
按证据完成综合、实现和发布
先生成冻结配置,再综合和实现。除基础课程的时序与规则报告外,还要查看时钟列表、时钟交互、CDC 和例外报告。XDC 的集合非空检查只负责早期发现明显错误,不能证明三十二位路径都被约束;需要在实际网表中逐项核查位宽和端点,确认约束未被更高优先级的例外覆盖后再签核。
- 核对时钟
预期与判定:输入和两输出频率符合 100/100/50 MHz,生成时钟关系完整。
- 核对端点
预期与判定:握手控制首级与两方向数据路径覆盖正确。
- 审查 CDC 与 STA
预期与判定:解释全部相关提示,建立、保持、脉宽与 DRC 均有依据。
- 生成发布物
预期与判定:同次构建 bit/ltx、BUILD_ID 与 SHA-256 清单一起保存。
在解压后的 fpga-advanced 目录执行。软件仿真不需要 Vivado;硬件步骤需目标工具与板卡。
python3 flow.py prepare baseline --ila
python3 flow.py vivado baseline synth
python3 flow.py vivado baseline impl
# 查看 reports/clocks.rpt、clock_interaction.rpt、cdc.rpt
# exceptions.rpt、routed_timing.rpt、routed_drc.rpt
cp build/baseline/review.template.txt build/baseline/review.txt
# 写入真实 CDC / 位级路径覆盖 / STA / DRC 审查结论
python3 flow.py vivado baseline bit典型故障:消掉告警也消掉约束
当工程出现很多跨域提示时,添加一个覆盖两域的异步时钟组可能让报告安静,却同时让数据路径最大延时失效。这个修改没有改善硬件,只减少了工具检查范围。应回到协议真正允许例外的端点,保留数据物理边界,并查看例外优先级和时序覆盖,不能按告警数量判断设计质量。
完成检查
- 同源时钟关系与实际板卡一致。
- 全部数据位约束有效且例外未覆盖它们。
- 审查记录与发布物来自同次构建。
延伸阅读与来源
本文为黄河电子原创教学说明。产品命令与支持范围请以实际安装版本的官方文档为准。
- Arm AMBA AXI / ACE IHI0022H
A3 通道握手;B1 AXI4-Lite。寄存器行为与示例实现为本文原创设计。
- AMD UG903 · Constraining Asynchronous Signals
跨域数据路径最大延时与时钟组例外的优先级。
- AMD UG908 · Programming and Debugging
Hardware Manager 与 ILA 配置、触发及采集。
继续阅读
FPGA从 RTL 到板上运行的完整流程
建立约束、实现、下载与观测的最小工程闭环。
第一个工程的引脚与时钟约束
区分电气连接与时间要求,避免“能生成位流就算正确”。
如何读懂时序报告
从起点、终点、时钟和裕量找出失败路径的原因。
黄河电子