2. 时序约束入门:时钟周期约束、输入延迟约束、输出延迟约束
各位同学,咱们今天聊聊时序约束里最基础、也最绕不开的三个东西:时钟周期约束、输入延迟约束、输出延迟约束。
说实话,我刚入行那会儿,觉得时序约束就是随便写个时钟周期完事。结果第一次做项目,综合出来的电路时序一塌糊涂,老板拿着报告问我怎么回事,我支支吾吾答不上来。后来才明白,约束没写对,后面全是坑。
好,咱们一个一个来拆解。
2.1 时钟周期约束——芯片的“心跳”
时钟周期约束,说白了就是告诉工具:我这个时钟跑多快。工具会根据这个约束去优化路径,确保所有寄存器之间的组合逻辑延迟不超过一个时钟周期。
在 HLS 里,最常用的写法是 create_clock 命令。比如:
create_clock -name clk -period 10 [get_ports clk]
这条命令的意思是:时钟 clk 的周期是 10ns,也就是 100MHz。工具会努力让所有路径的延迟都小于 10ns。
关键点:时钟周期约束是所有时序约束的基石。你给它一个宽松的周期,工具就偷懒;你给它一个紧张的周期,工具就拼命优化。但别太贪心,我曾经设过一个 2ns 的周期(500MHz),结果工具优化了三天三夜还没跑完……
嗯,这里要注意:时钟周期约束不光影响组合逻辑,还影响 I/O 接口的时序。因为输入输出信号也是跟着时钟走的。
2.2 输入延迟约束——信号从外面进来花了多久
输入延迟约束,描述的是外部信号从芯片引脚到内部第一个寄存器之间的延迟。这个延迟包括 PCB 走线、外部器件的输出延迟等。
我个人习惯这样写:
set_input_delay -clock clk -max 5 [get_ports data_in]
set_input_delay -clock clk -min 2 [get_ports data_in]
这里 -max 5 表示最大延迟 5ns,-min 2 表示最小延迟 2ns。工具会在这两个边界之间做分析。
为什么要有最大和最小?你想想看,外部信号可能因为温度、电压变化,延迟会波动。最大延迟用来检查建立时间,最小延迟用来检查保持时间。两个都得写,缺一不可。
小技巧:如果你不确定输入延迟的具体值,可以先用一个保守的估计,比如时钟周期的 60%。等后端布局布线完成后,再根据实际结果调整。我曾经因为输入延迟设得太小,导致芯片在高温下工作不稳定,后来花了整整一周才定位到问题。
2.3 输出延迟约束——信号从芯片出去要多久
输出延迟约束,描述的是内部最后一个寄存器到芯片输出引脚之间的延迟。这个延迟决定了外部器件能不能正确采样到我们的信号。
写法类似:
set_output_delay -clock clk -max 4 [get_ports data_out]
set_output_delay -clock clk -min 1 [get_ports data_out]
这里的 -max 4 表示外部器件要求数据在时钟沿之后 4ns 内到达,-min 1 表示数据至少保持 1ns 不变。
说白了,输出延迟约束就是告诉工具:外面那个家伙对时序的要求是什么。工具会根据这个要求,去调整内部逻辑的布局和走线。
避坑指南:我曾经犯过一个低级错误——把输入延迟和输出延迟写反了。结果综合出来的电路时序完全不对,仿真也通过不了。后来检查约束文件才发现,输入延迟应该写在输入端口上,输出延迟应该写在输出端口上。千万别搞混!
2.4 三种约束的关系
这三种约束不是孤立的。它们共同决定了芯片能不能正常工作。我画了一张图,帮你理清它们之间的关系:
从这张图可以看出来:输入延迟约束了外部信号进入芯片的路径,时钟周期约束了芯片内部的路径,输出延迟约束了信号离开芯片的路径。三条路径串起来,就是完整的时序链路。
在实际项目中,我一般会先确定时钟周期,再根据外部器件的 datasheet 去算输入输出延迟。算的时候留点余量,别卡得太死。毕竟芯片制造有工艺偏差,温度电压也会变化。
总结一下:
- 时钟周期约束:告诉工具芯片跑多快
- 输入延迟约束:告诉工具外部信号进来花了多久
- 输出延迟约束:告诉工具信号出去要满足什么要求
这三个约束写好了,时序分析就成功了一大半。剩下的就是跑 STA 看报告,哪里不满足就优化哪里。
好,今天就聊到这儿。下次咱们讲讲更复杂的多时钟域约束和异步信号处理。记住,约束不是写给别人看的,是写给工具看的。工具读懂了,才能帮你做出靠谱的芯片。