前言
前面几篇文章更多的是讲理解时序的作用,这一篇开始具体的讲一些步骤,可以当成工具书来看,我也会加一些相关的理解。
主时钟是什么
主时钟就是为整个FPGA设计树立一个"时间标尺"。没有它,时序分析就无从谈起。它定义了时间的起点和节拍,后续所有的输入延迟、输出延迟、时序例外等约束,都是基于这个标尺来进行衡量和计算的。
没有这个信号,所有关于"数据是否提前/延迟到达"的分析都将失去意义。具体来说,约束主时钟是为了告诉STA工具:
周期(Period) :寄存器间数据传输可用的时间单位。
波形(Waveform) :时钟上升沿和下降沿出现的具体时间点。
端口(Port) :时钟信号从哪个物理引脚进入FPGA。
工具会根据你提供的这个基准,去计算数据在寄存器之间的传输时间(Data Arrival Time
)是否满足要求(Data Required Time
),并最终给出时序裕量(Slack
)。
主时钟的约束命令如下
cpp
create_clock -name <clock_name> -period <period> -waveform {}[get_ports <clock_port_name>]
-name
:为你约束的这个时钟起一个名字。这个名字将在后续所有其他约束(如set_input_delay
)中作为参考。如果不命名的话**,工具会使用端口名作为时钟名。
** -period
:时钟周期,单位通常是纳秒(ns)。例如,100MHz的时钟,周期是10.0 ns。
-waveform {}:时钟上升沿和下降沿的具体时刻。
[get_ports ...]
:指定时钟信号输入到FPGA的物理引脚端口名。这是最关键的一点,它指明了时钟的物理来源。
主时钟约束的具体实例
场景1:最简单的单端时钟
板载50MHz晶振连接到FPGA,该引脚在代码中的端口名为sys_clk。
cpp
create_clock -name sys_clk -period 20.0 [get_ports sys_clk]
周期20.0ns
对应频率50MHz
。工具会默认假设该时钟的占空比为50%,即上升沿在0ns,下降沿在10ns。
场景2:指定非50%占空比或相位偏移
一个时钟周期为10ns,但高电平持续时间为7ns,低电平持续3ns。
create_clock -name clk_odd -period 10.0 -waveform {0 7} [get_ports clk_p]
**-waveform {<rise_time> <fall_time>}
**:用于精确描述时钟波形。
{0 7}
表示第一个上升沿在0ns,第一个下降沿在7ns。下一个上升沿在0+10=10ns,下一个下降沿在7+10=17ns,依此类推。
场景3:差分时钟
高速时钟通常以差分对(如clk_p
和clk_n
)的形式输入。你只需要约束正端(P端)。
create_clock -name diff_clk -period 5.0 [get_ports clk_p]
工具会自动识别这是一个差分对,并正确处理其电气特性。你不需要也不能对clk_n
再创建一个主时钟约束。
场景4:多个主时钟(异步时钟域)
板级提供了两个不同源的时钟,分别连接到clk_a
和clk_b
引脚。
create_clock -name clk_a -period 10.0 [get_ports clk_a]
create_clock -name clk_b -period 12.5 [get_ports clk_b]
关键点 :工具默认认为所有主时钟之间是异步的 。它们驱动的寄存器之间的路径将被视为异步时钟域路径 。除非你用set_clock_groups
或false_path
明确告知工具如何处理,否则工具会尝试分析它们之间的时序(这通常是不必要且无法实现的)。
场景5:同一个引脚输入,但有多钟时钟模式
例如,一个引脚clk_in
有时输入100MHz时钟,有时输入50MHz时钟。
# 模式1:100MHz
create_clock -name fast_mode -period 10.0 [get_ports clk_in]
# 模式2:50MHz,使用 -add 选项
create_clock -name slow_mode -period 20.0 [get_ports clk_in] -add
**-add
:表示在同一物理端口上添加另一个时钟定义。 工具会分别针对这两种时钟频率进行时序分析**,并取最差(最紧)的结果作为报告。
除了同xdc语句的方法,我们也可以通过GUI界面操作来设置主时钟约束,当然也包括后续所有约束,以VIVADO为例:
GUI设置
首先打开综合界面下的Edit Timing Constraints
点开界面如下
双击约束创建和编辑区
设置完相应的参数后,会自动生成xdc命令,点击OK。
可以看到刚刚创建的时钟约束,记得保存。
写在最后
主时钟约束还是比较好理解的,一般来说这个时钟是多少频率都会知道,只不过之前可能只是约束时钟是哪个管脚以及电平。