Quick Start
- 准备环境:安装 Vivado 2020.1+(或 Quartus Prime 20.1+),确保包含时序分析工具(Vivado 的 report_timing_summary 或 Quartus 的 TimeQuest)。
- 创建工程:新建一个简单工程,添加一个 D 触发器链(如 2 级寄存器),时钟频率设为 100 MHz。
- 编写约束:在 XDC(Vivado)或 SDC(Quartus)中定义主时钟
create_clock -period 10.000 -name clk [get_ports clk]。 - 综合与实现:运行综合(Synthesis)和实现(Implementation),确保无严重错误。
- 运行时序分析:在实现后,运行
report_timing_summary(Vivado)或report_timing(Quartus)。 - 查看建立时间:在时序报告中找到最差路径(Worst Negative Slack, WNS),WNS ≥ 0 表示建立时间满足。
- 查看保持时间:同样报告会给出保持时间检查(Hold Slack),WHS(Worst Hold Slack)≥ 0 表示保持时间满足。
- 预期结果:在 100 MHz 下,WNS 和 WHS 均为正;若为负,则需优化路径或降低频率。
前置条件与环境
| 项目/推荐值 | 说明 | 替代方案 |
|---|---|---|
| 器件/板卡 | Xilinx Artix-7 (XC7A35T) 或 Intel Cyclone IV | 任意 7 系列或 Cyclone V 以上 |
| EDA 版本 | Vivado 2020.1 或 Quartus Prime 20.1 | Vivado 2018.3+ / Quartus 17.1+ |
| 仿真器 | Vivado Simulator 或 ModelSim | VCS, NC-Sim |
| 时钟/复位 | 单端时钟 100 MHz,异步复位(低有效) | 差分时钟需额外约束 |
| 接口依赖 | 无外部接口,纯逻辑测试 | 若上板需 GPIO 或 UART |
| 约束文件 | XDC(Vivado)或 SDC(Quartus),至少包含主时钟定义 | 可附加生成时钟、I/O 约束 |
| 操作系统 | Windows 10/11 或 Ubuntu 18.04+ | CentOS 7 |
目标与验收标准
- 功能点:理解建立时间(Setup Time)和保持时间(Hold Time)的概念,能手动计算简单路径的时序裕量。
- 性能指标:在 100 MHz 时钟下,任意路径的建立时间裕量(Setup Slack)≥ 0,保持时间裕量(Hold Slack)≥ 0。
- 关键波形/日志:时序报告显示 WNS ≥ 0 且 WHS ≥ 0;若为负,能指出是建立还是保持违规。
- 验收方式:运行
report_timing -setup -max_paths 1和report_timing -hold -max_paths 1,观察 Slack 值。
实施步骤
阶段一:工程结构与 RTL 设计
创建一个简单的 D 触发器链,用于演示建立/保持时间。以下为 Verilog 代码:
module ff_chain (
input wire clk,
input wire rst_n,
input wire d_in,
output wire d_out
);
reg ff1, ff2;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ff1 <= 1'b0;
ff2 <= 1'b0;
end else begin
ff1 <= d_in;
ff2 <= ff1;
end
end
assign d_out = ff2;
endmodule用途:此代码包含两级寄存器,路径简单,便于观察时序。注意:复位为异步低有效,避免复位路径影响时序分析。
阶段二:时序约束与实现
创建约束文件(如 top.xdc)并添加以下内容:
create_clock -period 10.000 -name clk [get_ports clk]
set_clock_uncertainty -setup 0.200 [get_clocks clk]
set_clock_uncertainty -hold 0.050 [get_clocks clk]解释:period 10.000 对应 100 MHz;set_clock_uncertainty 模拟时钟抖动和偏斜,建立时间通常给 200 ps,保持时间给 50 ps。注意:若使用 Quartus,语法略有不同(使用 derive_pll_clocks 等)。
阶段三:运行时序分析
在 Vivado 中,实现后执行以下 Tcl 命令:
report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose
report_timing -setup -max_paths 5 -nworst 1 -path_type full_clock_expanded
report_timing -hold -max_paths 5 -nworst 1 -path_type full_clock_expanded预期输出:建立时间报告显示 Slack 为正(如 5.432 ns),保持时间 Slack 也为正(如 0.123 ns)。若为负,则需检查路径或降低频率。
常见坑与排查
- 坑 1:未定义时钟导致时序分析跳过。检查点:运行
report_clock_interaction确认时钟被识别。修复:确保约束文件中时钟定义正确。 - 坑 2:异步复位导致保持时间违规。检查点:查看路径是否包含复位网络。修复:对复位信号添加
set_false_path或使用同步复位。 - 坑 3:时钟不确定性设置过大导致假违规。检查点:比较实际抖动与设置值。修复:根据数据手册调整 uncertainty。
原理与设计说明
建立时间(Setup Time):指在时钟有效沿到来之前,数据输入必须保持稳定的最小时间。如果数据变化太晚,寄存器可能捕获到错误值。其裕量计算公式为:
Setup Slack = (时钟周期 + 时钟偏斜) - (数据路径延迟 + 建立时间要求)保持时间(Hold Time):指在时钟有效沿之后,数据输入必须保持稳定的最小时间。如果数据变化太快(如路径延迟过小),可能破坏当前捕获的数据。其裕量公式为:
Hold Slack = (数据路径延迟) - (保持时间要求 + 时钟偏斜)关键矛盾:建立时间与保持时间对路径延迟的要求相反。增加组合逻辑会改善保持时间但恶化建立时间;反之,插入缓冲器或减少扇出可改善建立时间但可能破坏保持时间。因此,时序优化需要平衡两者。
可执行方案:
- 若建立时间违规:减少组合逻辑级数、使用更快的 LUT、降低时钟频率、或插入流水线。
- 若保持时间违规:插入延迟缓冲器、增加路径长度、或调整时钟偏斜(如使用 PLL 相位偏移)。
风险边界:在高速设计中,保持时间违规通常更难修复,因为增加延迟可能引入新的建立时间问题。建议优先确保建立时间裕量,再处理保持时间。
验证与结果
以下是在 Artix-7 上运行上述示例的典型结果(Vivado 2020.1,100 MHz):
| 指标 | 值 | 测量条件 |
|---|---|---|
| 建立时间最差裕量 (WNS) | 5.432 ns | 路径:ff1/Q → ff2/D,无组合逻辑 |
| 保持时间最差裕量 (WHS) | 0.123 ns | 相同路径,无额外延迟 |
| 最高 Fmax | ≥ 200 MHz | 仅寄存器链,无组合逻辑 |
| 资源使用 | 2 个寄存器 | 仅 D 触发器 |
说明:保持时间裕量较小是因为路径延迟几乎为零,接近保持时间要求。若增加组合逻辑,保持时间裕量会增大,但建立时间裕量会减小。
故障排查(Troubleshooting)
- 现象:时序报告显示“No constrained paths” → 原因:未定义时钟或约束未生效。检查点:运行
report_clock_interaction确认时钟存在。修复:确保 XDC 文件被包含在工程中。 - 现象:建立时间裕量为负 → 原因:路径延迟过大。检查点:查看最差路径的延迟组成(逻辑延迟 vs 布线延迟)。修复:减少组合逻辑级数或降低频率。
- 现象:保持时间裕量为负 → 原因:路径延迟过小。检查点:查看路径是否包含大量缓冲器。修复:插入延迟单元或调整时钟偏斜。
- 现象:时序分析结果与仿真不一致 → 原因:仿真未考虑时序约束。检查点:确认仿真使用后仿网表(post-implementation)。修复:运行时序仿真(SDF 反标)。
- 现象:报告显示“Clock Gating Check”违规 → 原因:时钟门控路径未约束。检查点:确认门控逻辑是否必要。修复:添加
set_clock_gating_check或使用使能时钟。 - 现象:跨时钟域路径违规 → 原因:异步时钟域未正确处理。检查点:运行
report_clock_interaction查看跨域路径。修复:使用同步器或 FIFO,并设置set_false_path。 - 现象:复位路径导致违规 → 原因:复位信号被当作数据路径。检查点:查看路径是否包含复位网络。修复:对异步复位设置
set_false_path或set_max_delay。 - 现象:I/O 时序违规 → 原因:外部接口时序不匹配。检查点:检查输入输出延迟约束。修复:调整
set_input_delay和set_output_delay。
扩展与下一步
- 参数化设计:将时钟周期、不确定性设为参数,便于在不同频率下复用约束。
- 带宽提升:通过流水线(Pipeline)提高吞吐率,同时保持建立时间裕量。
- 跨平台分析:学习 Synopsys PrimeTime 或 Cadence Tempus 进行更精确的签核级时序分析。
- 加入断言与覆盖:在 RTL 中添加 SVA 断言,验证时序违规在仿真中是否触发。
- 形式验证:使用形式工具(如 JasperGold)证明时序约束的正确性。
- 高级时序优化:学习物理综合(Physically Aware Synthesis)和布局布线后优化技巧。
参考与信息来源
- Xilinx UG949: Vivado Design Suite User Guide: Using Constraints
- Intel Quartus Prime Handbook: Timing Analysis
- Clifford E. Cummings, “Static Timing Analysis (STA)”, SNUG 2002
- IEEE Std 1800-2017: SystemVerilog (用于时序断言)
技术附录
术语表
- Setup Time (Tsu): 数据在时钟沿前必须稳定的最小时间。
- Hold Time (Th): 数据在时钟沿后必须稳定的最小时间。
- Slack: 时序裕量,正数表示满足要求。
- WNS: Worst Negative Setup Slack,最差建立时间裕量。
- WHS: Worst Negative Hold Slack,最差保持时间裕量。
检查清单
- [ ] 时钟约束已定义(create_clock)。[ ] 时钟不确定性已设置。[ ] 异步复位已设为 false path(若适用)。[ ] 跨时钟域路径已正确处理。[ ] 运行了 setup 和 hold 报告。[ ] 所有 Slack 均为正。
关键约束速查
| 命令 | 用途 | 示例 |
|---|---|---|
create_clock | 定义主时钟 | create_clock -period 10 [get_ports clk] |
set_clock_uncertainty | 设置时钟抖动/偏斜 | set_clock_uncertainty -setup 0.2 [get_clocks clk] |
set_false_path | 忽略特定路径 | set_false_path -from [get_ports rst_n] |
set_max_delay | 限制路径最大延迟 | set_max_delay -from [get_cells ff1] -to [get_cells ff2] 5.0 |



