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 指针每次只改变一位,但若不同位的物理路由延时差异过大,接收端仍可能同时看到来自不同更新的变化。同步器属性不能代替总线约束,因此本工程对两方向指针分别设置最大数据路径延时和位间偏斜,并审查首级到第二级同步器的本域路径。软件仿真中的理想连线无法替代这一过程。
按当前板卡时钟填写约束
板上写域一百兆赫、读域五十兆赫由同一 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 综合网表端点和全部五位路径必须实际核对。
# 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、例外、总线偏斜、数据路径和常规建立保持脉宽,再填写构建审查记录。脚本检查集合数量只是早期错误检测,不能证明所有目标位和有效约束都正确。
- 核对时钟
预期与判定:100/50 MHz 关系与真实板卡一致。
- 核对结构
预期与判定:五位指针、两级同步器、RAM 与输出槽符合预期。
- 核对物理报告
预期与判定:延时、偏斜、RAM 数据路径和规则检查都有结论。
- 生成发布物
预期与判定:同次 bit/ltx 与 BUILD_ID、哈希清单一起保存。
在解压后的 fpga-stream 目录执行;软件测试需要 Python 3、iverilog 和 vvp。
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 映射和数据读路径得到核查。
- 硬件发布前保留完整审查记录。
延伸阅读与来源
本文为黄河电子原创教学说明。产品命令与支持范围请以实际安装版本的官方文档为准。
- Arm IHI0051A · AXI4-Stream Protocol
握手、字节限定与包尾;本文工程与测试为原创实现。
- AMD UG903 · CDC Constraints
跨域最大延时与总线偏斜约束。
- AMD UG474 · Distributed RAM Timing
分布式 RAM 的写入与异步读取时序特性。
- AMD UG908 · Programming and Debugging
ILA、探针文件与采集流程。
继续阅读
FPGA从 RTL 到板上运行的完整流程
建立约束、实现、下载与观测的最小工程闭环。
第一个工程的引脚与时钟约束
区分电气连接与时间要求,避免“能生成位流就算正确”。
如何读懂时序报告
从起点、终点、时钟和裕量找出失败路径的原因。
黄河电子