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 生成,具有工具可追踪的频率和相位关系;使用握手结构并不会把它们自动变成异步时钟。软件测试额外使用不同周期和初相位,是为了检验协议的事件排列。两者各有目的,约束必须描述实际硬件时钟网络,而不是照着测试平台的时钟产生语句填写。

时序覆盖、握手稳定性和同步器布局需要一起审查。100 MHz 输入Basys 3 晶振Clocking Wizard100 / 50 MHz局部 CDC 例外仅控制首级数据物理界限20 ns / 10 ns保留 generated clock 关系;不使用跨域全局时钟组例外
时序覆盖、握手稳定性和同步器布局需要一起审查。(原创示意,非器件引脚图;窄屏可横向滑动)

理解两个数据路径上限

源端数据只有在请求往返期间保持稳定,才能在目的域可靠采样。本工程给出源保持寄存器到 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 中确认。

tcl
# 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 的集合非空检查只负责早期发现明显错误,不能证明三十二位路径都被约束;需要在实际网表中逐项核查位宽和端点,确认约束未被更高优先级的例外覆盖后再签核。

  1. 核对时钟

    预期与判定:输入和两输出频率符合 100/100/50 MHz,生成时钟关系完整。

  2. 核对端点

    预期与判定:握手控制首级与两方向数据路径覆盖正确。

  3. 审查 CDC 与 STA

    预期与判定:解释全部相关提示,建立、保持、脉宽与 DRC 均有依据。

  4. 生成发布物

    预期与判定:同次构建 bit/ltx、BUILD_ID 与 SHA-256 清单一起保存。

在解压后的 fpga-advanced 目录执行。软件仿真不需要 Vivado;硬件步骤需目标工具与板卡。

bash
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

典型故障:消掉告警也消掉约束

当工程出现很多跨域提示时,添加一个覆盖两域的异步时钟组可能让报告安静,却同时让数据路径最大延时失效。这个修改没有改善硬件,只减少了工具检查范围。应回到协议真正允许例外的端点,保留数据物理边界,并查看例外优先级和时序覆盖,不能按告警数量判断设计质量。

完成检查

  • 同源时钟关系与实际板卡一致。
  • 全部数据位约束有效且例外未覆盖它们。
  • 审查记录与发布物来自同次构建。

延伸阅读与来源

本文为黄河电子原创教学说明。产品命令与支持范围请以实际安装版本的官方文档为准。

继续阅读

FPGA

从 RTL 到板上运行的完整流程

建立约束、实现、下载与观测的最小工程闭环。

10 分钟
FPGA

第一个工程的引脚与时钟约束

区分电气连接与时间要求,避免“能生成位流就算正确”。

11 分钟
FPGA

如何读懂时序报告

从起点、终点、时钟和裕量找出失败路径的原因。

10 分钟