create_clock 和 create_generated_clock 有什么区别?
更新时间:2026-09-21。问题驱动短答页。约束写法见 SDC 约束,FPGA 约束见 XDC 怎么写,跨时钟域见 CDC 处理。
一句话回答
create_clock 在时钟源头(输入端口或 PLL 参考脚)定义一个具有周期和波形的“主时钟”;create_generated_clock 用来定义由主时钟经分频、倍频、PLL/MMCM 或时钟门控派生出来的时钟,并通过 -source、-divide_by/-multiply_by/-edges 显式说明它与源时钟的相位和频率关系,STA 工具就能沿时钟树自动追踪延迟、正确做分频/倍频路径分析。关键是派生时钟不要重新用 create_clock 定义,否则会切断它和源时钟的关联,工具无法判定同步/相位关系,可能漏分析或误判跨时钟域路径。
基本写法
tcl
# 主时钟:100MHz,周期 10ns,定义在输入端口
create_clock -name clk100 -period 10 [get_ports clk_in]
# 二分频派生时钟,源是 clk100 到达该逻辑的点
create_generated_clock -name clk50 \
-source [get_pins u_div/Q] -divide_by 2 \
[get_pins u_div/q_div]
# 倍频(PLL 输出)
create_generated_clock -name clk400 \
-source [get_pins pll/clkin] -multiply_by 4 \
[get_pins pll/clkout]为什么不能再 create_clock
create_generated_clock建立了血缘关系:工具知道 clk50 边沿来自 clk100,能推出公共周期、自动分析二者之间的同步路径和分频器路径。- 若在派生点重新
create_clock,STA 视其为无关新时钟,分频寄存器那条路径可能被当成普通数据/时钟路径误处理,也无法正确设多周期/相位关系。
相关约束
- virtual clock:不带
-name之外没有真实端口源的时钟(不指定对象),用于约束来自片外、与某时钟同源的 IO 路径。 - 异步时钟:没有固定相位关系的两个时钟,用
set_clock_groups -asynchronous或对具体路径设set_false_path,让工具不按同步时序硬算,见 false path vs multicycle。 - 时钟网络延迟由 CTS/工具传播,不要用
set_clock_latency掩盖真实生成关系。
常见坑
- 对 PLL/分频器输出再写
create_clock,丢失源时钟关系。 - 漏约束某个派生时钟,该时钟域路径不被分析(unclocked/unconstrained)。
-source指错引脚,相位算错。- 明明是异步时钟却不设 clock group,工具按理想同步报一堆假违例或放过真问题。
总结
create_clock 定义时钟根上的主时钟周期与波形,create_generated_clock 用 -source 加 -divide_by/-multiply_by/-edges 定义 PLL、分频或门控派生时钟与源时钟的频率相位关系,让 STA 能沿时钟树自动追踪;派生时钟切忌再用 create_clock 重新定义以免切断血缘关系,片外同源 IO 用虚拟时钟、无固定相位关系的时钟用 set_clock_groups -asynchronous 正确声明异步。