3. SDC语法入门

SDC,全称Synopsys Design Constraints。

说白了,就是告诉工具你的芯片想怎么跑。

我刚开始接触SDC时,觉得它不就是个文本文件嘛。后来被坑了几次才明白——SDC写不好,时序分析全是白搭。

3.1 SDC文件结构

一个标准的SDC文件,通常长这样:

# ============================================
# 时钟定义
# ============================================
create_clock -name sys_clk -period 10 [get_ports clk]

# ============================================
# 输入延迟约束
# ============================================
set_input_delay -clock sys_clk -max 5 [get_ports data_in]

# ============================================
# 输出延迟约束
# ============================================
set_output_delay -clock sys_clk -max 6 [get_ports data_out]

# ============================================
# 时序例外
# ============================================
set_false_path -from [get_clocks rst_clk] -to [get_clocks sys_clk]

结构其实很清晰:先定义时钟,再约束IO,最后处理例外路径。

我个人习惯把SDC分成三大块:时钟约束、IO约束、例外约束。每块之间用注释隔开,方便后期维护。

小技巧: 我建议每个SDC文件开头都加一个版本号和修改日期。项目大了你就知道这有多重要了。

3.2 常用命令概览

3.2.1 create_clock

这是最基础的命令。没有时钟,时序分析无从谈起。

create_clock -name clk_50m -period 20 [get_ports clk_in]

参数说明:

参数 含义 示例
-name 时钟名称 clk_50m
-period 时钟周期(ns) 20(对应50MHz)
-waveform 上升沿/下降沿位置 {0 10}

嗯,这里要注意:-waveform默认是{0 period/2},也就是50%占空比。如果你的时钟不是50%占空比,记得手动指定。

我在项目中遇到过一个问题:某芯片的时钟是40%占空比,我没写-waveform,结果时序分析全偏了。后来查了半天才发现是这里的问题。

3.2.2 set_input_delay

这个命令告诉工具:数据从外部芯片过来,到底花了多长时间。

set_input_delay -clock clk_50m -max 5 [get_ports data_in]
set_input_delay -clock clk_50m -min 2 [get_ports data_in]

为什么要分-max和-min?

你想想看,外部芯片的延迟不是固定的。温度变了、电压变了,延迟都会变。-max对应最坏情况(setup检查),-min对应最好情况(hold检查)。

避坑指南: 我曾经只写了-max没写-min,结果hold时序全没检查。流片回来芯片在低温下直接罢工。从那以后,我每次写input_delay都会把-max和-min都写上。

3.2.3 set_output_delay

和input_delay相反,这个约束的是数据从FPGA出去的时间。

set_output_delay -clock clk_50m -max 6 [get_ports data_out]
set_output_delay -clock clk_50m -min 3 [get_ports data_out]

说白了,就是告诉工具:下游芯片需要数据提前多久准备好,以及保持多久。

3.2.4 其他常用命令

  • set_false_path:告诉工具这条路径不用检查。比如跨时钟域的同步器路径。
  • set_multicycle_path:告诉工具这条路径需要多个时钟周期才能稳定。比如一些慢速外设接口。
  • set_clock_groups:把时钟分组,不同组之间默认不检查。

3.3 注释规范

SDC文件里的注释,很多人不重视。但我觉得,注释写得好不好,直接决定了这个SDC文件能不能复用。

我个人的注释规范:

  1. 文件头注释:写明项目名、模块名、作者、日期、版本。
  2. 分区注释:用# ====== 分隔不同功能块。
  3. 行内注释:复杂命令后面加注释,说明为什么这么设。
# ============================================
# 时钟定义 - 主时钟50MHz
# 来源:板级晶振,经过PLL倍频
# ============================================
create_clock -name clk_50m -period 20 [get_ports clk_in]

# 输入延迟:外部ADC的tco为5ns,PCB走线延迟约1ns
set_input_delay -clock clk_50m -max 6 [get_ports adc_data]
小技巧: 我建议注释里写上数值的来源。比如"这个5ns是从datasheet第12页查到的"。半年后你再看这个文件,会感谢自己写了这些注释。

3.4 知识体系总览

下面这张图,是我整理的本章节核心逻辑。你可以把它当成SDC学习的路线图:

SDC语法知识体系 SDC文件结构 时钟约束 IO约束 例外约束 create_clock create_generated_clock set_clock_groups set_input_delay set_output_delay set_load / set_drive set_false_path set_multicycle_path set_max_delay 注释规范:文件头 + 分区 + 行内

这张图把SDC的核心脉络理清楚了。从上到下,先有文件结构,再分三大块,每块对应具体命令,最后用注释把一切串起来。

核心要点: SDC不是写出来就完事了。它是你和时序分析工具之间的沟通语言。写得好,工具能准确理解你的设计意图;写得差,工具就会给你一堆假violation或者漏掉真问题。

好了,这一章的内容就到这里。记住:SDC语法不难,难的是理解每条命令背后的时序含义。下一章我们会深入讲解时钟约束的细节,到时候见。


可可精品资料库