高云 FPGA 添加时序约束笔记
-
- 一、打开时序约束编辑器
- 二、创建时钟约束
- 三、选择时钟目标引脚
- 四、完成时钟约束配置
- [五、查看生成的 SDC 约束文件](#五、查看生成的 SDC 约束文件)
- [六、SDC 时钟约束语法扩展](#六、SDC 时钟约束语法扩展)
-
- [6.1 基本语法](#6.1 基本语法)
- [6.2 主时钟约束(引脚输入)](#6.2 主时钟约束(引脚输入))
- [6.3 衍生时钟约束(PLL/MMCM 生成)](#6.3 衍生时钟约束(PLL/MMCM 生成))
- [6.4 多时钟组约束](#6.4 多时钟组约束)
- [6.5 常见约束命令速查](#6.5 常见约束命令速查)
- 七、时序约束最佳实践
-
- [7.1 约束原则](#7.1 约束原则)
- [7.2 管脚约束配合](#7.2 管脚约束配合)
- [7.3 验证时序收敛](#7.3 验证时序收敛)
一、打开时序约束编辑器
在 Gowin IDE 的 Process 界面中,找到 Timing Constraints Editor 并双击打开。

首次打开时,如果当前工程尚未创建约束文件,软件会弹出提示框,询问是否创建约束文件,点击 OK 即可。

说明: 时序约束文件通常以
.sdc(Synopsys Design Constraints)为后缀,遵循 SDC 标准格式。高云 IDE 会自动生成该文件,后续也可以直接用文本编辑器手动编辑。
二、创建时钟约束
在左侧的 Timing Constraints 树下,选中 Clocks ,在右侧空白区域右键单击 ,选择 Create Clock。

此时弹出 Create Clock 配置界面,各项参数说明如下:
| 参数 | 含义 | 说明 |
|---|---|---|
| Clock Name | 时钟名称 | 支持字母或下划线开头的标识符 |
| Period | 时钟周期 | 默认 10,浮点型,精确到千分位,单位 ns |
| Frequency | 时钟频率 | 默认 100,浮点型,精确到千分位,单位 MHz |
| Rising | 上升沿时刻 | 浮点型,精确到千分位,单位 ns |
| Falling | 下降沿时刻 | 浮点型,精确到千分位,单位 ns |
| Objects | 作用目标 | 通过 Search 选择具体引脚/网络进行自动填充 |
| Add | 多时钟添加 | 在同一源上添加多个时钟时需勾选 |
Period 与 Frequency 的关系: 两者互为倒数,
Frequency = 1 / Period × 1000。例如周期为 20ns 时,频率自动显示为 50MHz。修改其中一个,另一个会自动更新。
三、选择时钟目标引脚
点击 Objects 旁边的 ... 按钮(浏览信号),进入信号选择界面。

在本例中,需要约束的时钟是从外部管脚输入的 50MHz 系统时钟 。依次点击 Search → clk →右移 → OK 完成选择。

经验提示: 时钟信号应尽量分配到全局时钟管脚 (Global Clock Pin),高云芯片的全局时钟管脚通常带有特殊标注(如
GCLK前缀),这类管脚具有专用的时钟布线资源,延迟远小于普通 IO 管脚。
四、完成时钟约束配置
回到 Create Clock 界面,填写以下参数:
- Clock Name:
clk - Period:
20(对应 50MHz) - Frequency:
50(自动计算) - Rising:
0 - Falling:
10(50% 占空比,即周期的一半)
点击 Create 完成时钟约束。

五、查看生成的 SDC 约束文件
通过上述操作,50MHz 时钟的时序约束已成功添加。关闭 Gowin Timing Constraints Editor 界面,回到 Design 界面,可以看到工程中自动生成了 bin_counter.sdc 约束文件。

双击打开该文件,可以看到图形化界面自动生成的 SDC 语法内容:

文件中的约束语句等价于以下 SDC 命令:
create_clock -name clk -period 20 -waveform {0 10} [get_ports clk]
这条语句的含义是:定义一个名为 clk 的时钟,周期为 20ns(即 50MHz),上升沿在 0ns,下降沿在 10ns(50% 占空比),作用在名为 clk 的输入端口上。
六、SDC 时钟约束语法扩展
6.1 基本语法
SDC(Synopsys Design Constraints)是 FPGA/ASIC 设计中标准的时序约束格式。高云 IDE 的图形化界面本质上就是自动生成 SDC 命令。掌握 SDC 语法的好处是:可以直接用文本编辑器修改约束,无需依赖图形界面,在脚本化流程中也非常有用。
| 参数 | 含义 | 示例 |
|---|---|---|
-name |
时钟名称 | -name clk50 |
-period |
周期(ns) | -period 20 |
-waveform |
上升沿/下降沿时间 | -waveform {0 10} |
get_ports |
指定物理引脚 | [get_ports clk] |
6.2 主时钟约束(引脚输入)
对于从外部晶振通过输入端口进入 FPGA 的主时钟:
create_clock -name clk50 -period 20 -waveform {0 10} [get_ports clk]
-waveform {0 10}表示上升沿在 0ns,下降沿在 10ns,即 50% 占空比- 如果不指定
-waveform,工具默认占空比为 50%(即{0 period/2})
6.3 衍生时钟约束(PLL/MMCM 生成)
对于通过 PLL 或分频器生成的内部时钟,使用 create_generated_clock:
create_generated_clock -name clk25 -source [get_pins pll_inst/clkout0] -divide_by 2 [get_pins pll_inst/clkout1]
注意: 衍生时钟必须指定源时钟(
-source),工具会根据源时钟和分频/倍频关系自动推导衍生时钟的时序。
6.4 多时钟组约束
当设计中存在多个独立时钟域时,需要告诉工具哪些时钟之间是异步的,避免进行不必要的跨时钟域时序分析:
set_clock_groups -asynchronous -group {clk50} -group {clk25}
6.5 常见约束命令速查
| 命令 | 用途 |
|---|---|
create_clock |
定义主时钟 |
create_generated_clock |
定义 PLL/分频器生成的时钟 |
set_clock_groups |
定义时钟间关系(异步/互斥) |
set_clock_jitter |
设置时钟抖动 |
set_clock_latency |
设置时钟网络延迟 |
set_input_delay |
设置输入端口延迟约束 |
set_output_delay |
设置输出端口延迟约束 |
set_max_delay / set_min_delay |
设置路径最大/最小延迟 |
七、时序约束最佳实践
7.1 约束原则
- 精准: 时钟周期、占空比等参数必须与实际硬件完全一致,错误的约束会导致工具做出错误的优化决策
- 完整: 覆盖所有时钟域,不要遗漏任何时钟源
- 一致: 约束文件中的端口名称必须与 Verilog 设计文件中的端口名完全匹配
7.2 管脚约束配合
时序约束通常需要配合管脚约束(.cst 文件)一起使用。管脚约束指定每个信号对应的物理引脚位置和 IO 电平标准:
IO_LOC "clk" 10;
IO_PORT "clk" IO_TYPE=LVCMOS33;
7.3 验证时序收敛
完成约束后,运行 Timing Analysis (时序分析),查看 Timing Report 确认所有路径的时序是否收敛。重点关注:
- Slack(裕量): 正值表示时序收敛,负值表示时序违例
- 关键路径: Slack 最小(最接近违例)的路径,通常是优化的重点