面向模块的综合技术之重定时优化(六)

面向模块的综合技术之重定时优化(六)


文章目录

  • 面向模块的综合技术之重定时优化(六)
  • 前言
      • ✅ 一、Retiming 的基本原理
      • ✅ 二、Vivado 中的 Retiming 类型
      • ✅ 三、常用 Retiming 属性
          1. `retiming_forward`
          1. `retiming_backward`
      • ✅ 四、模块级控制(BLOCK_SYNTH.RETIMING)
      • ✅ 五、Retiming 的限制与注意事项
      • ✅ 六、Retiming 的实际效果
      • ✅ 七、总结建议

前言


在 Vivado 中,Retiming(重定时)是一种不改变电路功能、仅移动寄存器位置优化时序性能 的关键综合技术。它的核心思想是:通过在组合逻辑之间前后移动寄存器 ,来平衡逻辑延迟 ,从而缩短关键路径延迟提高时钟频率


✅ 一、Retiming 的基本原理

Retiming 遵循 Leiserson-Saxe 定理,即:

在不改变输入输出行为的前提下,通过前后移动寄存器,优化逻辑级数分布,从而改善时序。

Vivado 会自动识别逻辑路径中的寄存器,并尝试将其前移或后移,以减少高逻辑级数路径的延迟


✅ 二、Vivado 中的 Retiming 类型

类型 控制方式 描述
全局 Retiming 综合选项 -retiming 对整个设计自动进行寄存器移动,需配合时序约束使用
局部 Retiming RTL 属性或 XDC 约束 精确控制某寄存器或路径是否参与 retiming,适用于精细优化

✅ 三、常用 Retiming 属性

你可以在 RTL 或 XDC 中使用以下属性:

1. retiming_forward

允许寄存器向前移动(朝输出方向),穿越组合逻辑。

verilog 复制代码
(* retiming_forward = 1 *) reg my_reg;
2. retiming_backward

允许寄存器向后移动(朝输入方向),穿越组合逻辑。

verilog 复制代码
(* retiming_backward = 1 *) reg my_reg;

注意:这些属性不受全局 retiming 设置影响,可独立生效


✅ 四、模块级控制(BLOCK_SYNTH.RETIMING)

你也可以对某个模块开启 retiming:

tcl 复制代码
set_property BLOCK_SYNTH.RETIMING 1 [get_cells inst1/inst2]

这会对该模块内的逻辑进行寄存器重定时,适用于局部优化


✅ 五、Retiming 的限制与注意事项

  • 以下情况不会 进行 retiming:
    • 寄存器上有 DONT_TOUCHMARK_DEBUG 属性
    • 路径上有 false_pathmulticycle_path 约束
    • 用户实例化的寄存器(非推断寄存器)

✅ 六、Retiming 的实际效果

  • 减少逻辑级数分布不均带来的时序压力
  • 无需修改 RTL 代码,即可提升性能
  • 可配合 report_design_analysis -logic_level_distribution 分析优化效果

✅ 七、总结建议

Vivado 眼里的一条"路径"并不是一根线,而是 "起点 FF → 组合云 → 终点 FF"

场景 建议
时序收敛困难 开启全局 retiming(-retiming
局部路径时序差 使用 retiming_forward/backward 精确控制
模块级优化 使用 BLOCK_SYNTH.RETIMING
调试阶段 避免对调试信号使用 retiming(加 DONT_TOUCH

以下情况下不能进行重定时操作:

  1. 寄存器时序异常(多循环路径、错误的路径、最大延迟路径),即时序例外不可
工具不敢搬的原因 Vivado 实际行为 一句话定位 放行/变通办法
搬动后"锚点"消失,多周期/假路径/MaxDelay 约束失去参照,时序报告会错。 综合日志出现 Retiming blocked: user timing exception;对应寄存器 retiming_forward/retiming_backward 被内部强制 0。 report_timing_exceptions -retiming_blocked 把例外粒度从"时钟到时钟"改成"端口到端口"或"寄存器到寄存器",再允许搬动;例外结束后重新加回。

| 搬动后"锚点"消失,多周期/假路径/MaxDelay 约束失去参照,时序报告会错。 | 综合日志出现 Retiming blocked: user timing exception;对应寄存器 retiming_forward/retiming_backward 被内部强制 0。 | report_timing_exceptions -retiming_blocked | 把例外粒度从"时钟到时钟"改成"端口到端口"或"寄存器到寄存器",再允许搬动;例外结束后重新加回。 |

  1. 寄存器的类型属性不能改变(DONT_TOUCH, MARK_DEBUG)
工具不敢搬的原因 Vivado 实际行为 一句话定位 放行/变通办法
这些属性="网表节点必须比特级固定",任何优化(含 retiming)都跳过,否则调试/层次化会崩。 opt_design 日志 Retiming blocked: attribute DONT_TOUCHreport_retiming 显示 0 registers moved `get_cells -hier -filter {DONT_TOUCH MARK_DEBUG}` 调试阶段保留;最终发布前脚本批量 set_property DONT_TOUCH false 再跑一轮综合。
  1. 要执行后向重定时操作,组合逻辑必须仅驱动寄存器,而不是扇出到其他逻辑。要执行前向重定时操作,门的每个输入必须由具有相同控制集
工具不敢搬的原因 Vivado 实际行为 一句话定位 放行/变通办法
时钟/使能/复位/置位任意一项不同,搬动后 RTL 行为会变(如 CE 无效时多采一次)"不同控制集 = 不同采样规则"搬动寄存器 = 改变采样时刻 → latency/数值都可能变 → 功能不再等价。因此 Vivado 内部规则:跨控制集 → 立即阻断 retiming,除非用户手动统一控制集。。 日志 Retiming blocked: incompatible control set;同一条数据链上寄存器无法合并或穿越。 report_control_sets -verbose 统一控制集:给无 CE 寄存器包一层 CE=1'b1;或手动复制同控集寄存器供工具搬。

原始:

din ──►│LUT1│──►│LUT2│──►(a_reg)──►│LUT3│──►(q_reg)

时序报告:

LUT3 延迟 0.9 ns,关键路径 0.9 ns → WNS = -0.2 ns

目标:把 q_reg 搬过 LUT3,让 LUT3 的延迟不再属于"a→q"路径

搬动后:

din ──►│LUT1│──►│LUT2│──►│LUT3│──►(q_reg_new)──►(a_reg) <- 顺序反了

组合云从 {LUT3} 变成 {},路径延迟 -0.9 ns → WNS 转正

但 a_reg 与 q_reg_new 必须同控制集,否则工具报:

Retiming blocked: incompatible control set

retiming 的"滑块"必须横跨组合云,且滑块两端触发器必须同款控制集;只要 a_reg 与 q_reg 的 CLK/CE/SR 任一不同,滑块就被卡住,整条路径动不了。因此所谓"只搬 q"是不存在的------搬 q 的同时一定要求 a 与 q 同控制级,否则工具直接拒绝。

  1. 寄存器驱动输出或由输入驱动(除非设计被标记为 out-of-context)。
工具不敢搬的原因 Vivada 实际行为 一句话定位 放行/变通办法
顶层端口是"芯片边界",搬动会改变 I/O 时序协议 (Hold、Setup、skew、对齐)。 非 OOC 模式下,工具看不到外部世界,不敢改边界寄存器。 综合日志 Retiming blocked: boundary registerreport_retimingBOUNDARY_REGISTER 分类为 0 moved。 get_cells -filter {IS_BOUNDARY_REGISTER} 1. 把顶层包成 OOC 模块,set_property IS_OOC true [current_fileset] → 工具把端口当内部节点,可自由搬。 2. 不改 OOC 则手动在边界加/减寄存器,再允许内部搬动。
  1. 重定时无法提升反馈循环中的关键路径的示例:当路径的源寄存器和目标寄存器相同时,重定时优化有可能无法改善逻辑层次。反馈环 = 单 FF 闭环,重定时因"寄存器数量守恒"无法滑动;手动插入一级 dummy FF → 变成"双 FF 链",工具就能搬动,频率提升,代价是 latency +1。
相关推荐
仲南音16 小时前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner1 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20201 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy2 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia2 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20202 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子2 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安3 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi
千寻xun3 天前
二、实战篇-NVME SSD控制之ZYNQ实现(六)-读写NVME SSD硬盘数据
fpga开发·nvme·nvme ssd
千寻xun3 天前
二、实战篇-NVME SSD控制之ZYNQ实现(三)
fpga开发·nvme ssd·nvme协议