FPGA 流式实战 · 05 Gray 总线与存储路径时序约束

约束跨域指针的延时和位间偏斜,同时保留真实时钟关系与 RAM 输出路径审查。

先修知识完成 FPGA AXI / CDC 进阶课程;掌握同步 FIFO、握手、Gray 编码和时序报告基础。

适用环境Basys 3 / Artix-7;板上写 100 MHz、读 50 MHz;Python 3、Icarus Verilog;Vivado 2024.1 命令参考。

验证状态六场景 RTL 测试、两类故障检出及顶层软件模型已验证;性能表为仿真测量,Vivado 与板上 ILA 尚需实测。

本文目录逻辑 Gray 正确仍需要物理预算按当前板卡时钟填写约束综合实现与发布检查典型故障:全局例外掩盖 Gray 约束

逻辑 Gray 正确仍需要物理预算

本地 Gray 指针每次只改变一位,但若不同位的物理路由延时差异过大,接收端仍可能同时看到来自不同更新的变化。同步器属性不能代替总线约束,因此本工程对两方向指针分别设置最大数据路径延时和位间偏斜,并审查首级到第二级同步器的本域路径。软件仿真中的理想连线无法替代这一过程。

指针约束和 RAM 数据路径审查分别处理,不对所有跨域路径一刀切。注册 Gray本地相邻变化一位物理布线延时与位间偏斜首级同步五位全部覆盖第二级同步本域时序仍分析仅在本域 VALID 与 READY 同时为 1 的时钟沿转移数据
指针约束和 RAM 数据路径审查分别处理,不对所有跨域路径一刀切。(原创示意,非器件引脚图;窄屏可横向滑动)

按当前板卡时钟填写约束

板上写域一百兆赫、读域五十兆赫由同一 Clocking Wizard 产生,应保留生成时钟关系。写 Gray 到读域首级使用十纳秒预算,读 Gray 到写域首级使用二十纳秒预算,分别对应当前源域周期。调整频率、换用独立外部时钟或改变结构后,必须重新审查约束和数据路径,不能把这份板卡 XDC 当成所有异步 FIFO 的模板。

设计契约与检查依据
项目工程含义
set_max_delay -datapath_only限制 Gray 数据路径传播时间
set_bus_skew限制不同位到达时间差,需查看 bus_skew.rpt
不能叠加宽泛 false_path避免覆盖同路径的最大延时检查
RAM → 输出槽保留同源时钟下时序分析,核对 RAM 原语与读路径
复位链异步入口只对同步复位链的异步端点设例外

Basys 3 当前配置;Vivado 综合网表端点和全部五位路径必须实际核对。

tcl
# Basys 3 only. Match the physical board revision and bank voltage before programming.
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 generates related 100 MHz write and 50 MHz read clocks.
set_false_path -to [get_ports {led[*]}]
set rp [get_pins -hier -filter {NAME =~ *u_reset_*/pipe_reg*/PRE}]
if {[llength $rp]!=6} {error "STREAM_XDC: expected six reset synchronizer PRE pins"}
set_false_path -to $rp
# Gray pointer bus: constrain arrival delay and skew. No false-path override here.
foreach {src dst limit} {wgray wgray_meta 10.000 rgray rgray_meta 20.000} {
 set from_cells [get_cells -hier -filter "NAME =~ *u_fifo/${src}_reg*"]
 set to_cells [get_cells -hier -filter "NAME =~ *u_fifo/${dst}_reg*"]
 if {[llength $from_cells]!=5 || [llength $to_cells]!=5} {error "STREAM_XDC: inspect all five bits of $src -> $dst"}
 set_max_delay $limit -datapath_only -from $from_cells -to $to_cells
 set_bus_skew $limit -from $from_cells -to $to_cells
}
# Memory payload is protected by pointer ownership and delayed publication, not bit synchronizers.
# Keep RAM-to-output timing analyzed with related clocks; inspect RAM primitive mapping and read paths.
# Never blanket-cut all write/read clocks. Independent board clocks require a new payload timing review.

综合实现与发布检查

综合后应确认存储阵列采用符合预期的分布式 RAM 结构,读端输出槽仍存在,指针同步级没有被不当合并。实现后审查时钟、CDC、例外、总线偏斜、数据路径和常规建立保持脉宽,再填写构建审查记录。脚本检查集合数量只是早期错误检测,不能证明所有目标位和有效约束都正确。

  1. 核对时钟

    预期与判定:100/50 MHz 关系与真实板卡一致。

  2. 核对结构

    预期与判定:五位指针、两级同步器、RAM 与输出槽符合预期。

  3. 核对物理报告

    预期与判定:延时、偏斜、RAM 数据路径和规则检查都有结论。

  4. 生成发布物

    预期与判定:同次 bit/ltx 与 BUILD_ID、哈希清单一起保存。

在解压后的 fpga-stream 目录执行;软件测试需要 Python 3、iverilog 和 vvp。

bash
python3 flow.py prepare baseline --ila
python3 flow.py vivado baseline synth
python3 flow.py vivado baseline impl
# 检查 reports/bus_skew.rpt、cdc.rpt、exceptions.rpt
# clocks.rpt、clock_interaction.rpt、routed_timing.rpt、DRC
cp build/baseline/review.template.txt build/baseline/review.txt
# 填写真实 Gray 位级路径、RAM 读路径和 STA 审查证据
python3 flow.py vivado baseline bit

典型故障:全局例外掩盖 Gray 约束

为了减少跨域报告而给两个时钟添加全局异步分组,会覆盖本来用于限制指针延时的约束。表面上告警减少并不表示硬件更可靠。应检查例外优先级和实际有效路径,保留明确的指针物理预算;RAM 数据通过所有权协议跨域,也需要单独核查存储结构和时序,不能用同一句全切路径处理所有问题。

完成检查

  • 所有 Gray 位的延时与偏斜都有有效约束。
  • RAM 映射和数据读路径得到核查。
  • 硬件发布前保留完整审查记录。

延伸阅读与来源

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

继续阅读

FPGA

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

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

10 分钟
FPGA

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

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

11 分钟
FPGA

如何读懂时序报告

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

10 分钟