本节摘要:时序约束(XDC/SDC 文件)是设计者与工具之间的"合同"——你告诉工具时钟长什么样、管脚延迟是多少、哪些路径不需要检查。本节从最常用的时钟约束切入,讲清 create_clock、时钟组、输入输出延迟与伪路径,并解释为什么约束残缺是高速设计做不起来的头号原因。
先看一个反例。某团队新做了个图像处理加速器,芯片是支持 300MHz 的中端 FPGA,他们把目标定为 200MHz。综合布局布线一轮下来,工具报告"满足约束"。上板一测——图像偶尔花屏。查了很久,最后发现约束文件里根本没有时钟约束:工具默认把所有路径当"不用满足任何频率"来优化,自然怎么都能过。没有时钟目标,工具连"快"的方向都不知道,更别提给你出有意义的时序报告。
这个案例的教训:约束不是给工具添麻烦,是给工具指路。你不告诉它时钟周期是 5ns 还是 10ns,它就无法权衡"这条路径要不要多花布线资源压短"。约束残缺的设计,时序报告形同虚设,问题只在运行期以花屏、卡死、偶发错误的形式爆发——而到那时定位成本已经高得离谱。
主流工具用 XDC(Xilinx)或 SDC(Intel,业界标准 Synopsys 设计约束)格式,语法几乎互通。文件里是一系列命令,最常见的几条如下:
# 时钟约束:板载 50MHz 晶振,定义主时钟 create_clock -period 20.000 -name clk_50m [get_ports clk] # 衍生时钟:PLL 输出的 200MHz 时钟,由工具自动推导或显式声明 create_clock -period 5.000 -name clk_200m [get_pins pll_inst/clk_out1] # 不相关的时钟域:告诉工具这两个时钟域之间的路径不用检查 set_clock_groups -asynchronous -group {clk_50m} -group {clk_200m} # 输入延迟:外部芯片的数据相对时钟到达的窗口 set_input_delay -clock clk_50m -max 4.000 [get_ports data_in] # 伪路径:结构上存在但功能上永远不会同时激活的路径 set_false_path -from [get_clocks clk_50m] -to [get_clocks clk_200m]
逐条拆解背后的意图:
create_clock 是约束的基石。-period 20.000 表示时钟周期 20ns(即 50MHz),-name 给时钟起名方便引用,[get_ports clk] 指出这根时钟从哪个管脚进来。工具知道这根时钟的存在后,才会计算"一个时钟周期内,信号能不能从起点寄存器到达终点寄存器"。
set_clock_groups -asynchronous 声明两个时钟域互不相关。它有两个作用:一是告诉工具"这两个域之间不用做时序检查"(省下大量分析时间),二是配合 CDC 设计——但前提是你真的做了跨时钟域同步处理(4.3 的内容)。只声明不处理,就是自己给自己埋雷。
set_input_delay 描述芯片外部信号的时序。外部芯片的数据不是瞬间到达的,有芯片内部延迟和 PCB 走线延迟。告诉工具"数据晚到最多 4ns",它才能给输入端的寄存器留出余量。
set_false_path 声明"这条路径功能上不可能被同时触发,不用检查"。比如两个互斥使能的信号,硬件上连了,逻辑上永远不会同时有效。乱用 false_path 是高手也容易栽的坑——判断"功能上不可能"要极其保守,误删一条真实路径的检查,违例就漏网了。
给 1.3 那颗 50MHz 晶振的板子写第一版完整约束,这是每个工程的起步动作:
# 时钟 create_clock -period 20.000 -name clk_50m [get_ports clk] # 复位:异步复位信号,约束其恢复时间(可选,工具有默认处理) set_input_delay -clock clk_50m 0 [get_ports rst_n] # 输出:LED 输出,PCB 走线短,延迟约束给个保守值 set_output_delay -clock clk_50m -max 2.000 [get_ports led]
写完后跑一次综合,打开时序报告,你会看到每类路径都有了检查目标。判断约束是否"写全"有个朴素方法:查看综合报告里的时钟概况,所有时钟和所有跨时钟路径都声明清楚、没有意外——就合格了。
clk_200m 是从 clk_50m 衍生的,正确做法是让工具从 PLL 配置推导,或显式 create_generated_clock 声明倍数关系,而不是重复 create_clock——两个独立主时钟会导致跨域路径被错误忽略。⚠️ 常见坑:约束里的
-period 20.000写错成-period 200.000(漏了个 0),工具会以为你要 200ns 周期(5MHz),所有路径都轻松满足,报告一片绿,上板照样花屏。写完约束先自查周期换算:周期 ns = 1000 除以频率 MHz。
下一步进入 4.2:约束写全了,工具开始按约束检查——静态时序分析报告怎么读,是本节要教你的硬功夫。