← 返回 Skills
Intermediate时序约束

SDC Writer

Generate complete SDC timing constraint files from design specifications. Covers clock definitions, generated clocks, I/O delays, clock groups, false paths, multi-cycle paths, and operating conditions.

💡 将此 Skill 描述复制到 AI Agent(如 Cursor、Claude Code、Copilot)的系统提示中,然后输入你的设计需求,Agent 将按照本 Skill 中定义的规则生成代码。页面底部可下载完整 .md 文件。


name: sdc-writer description: > Generate a complete, correct, and well-commented SDC (Synopsys Design Constraints) file from a natural language description of timing requirements. Covers clock definitions, generated clocks, I/O delays, clock groups, false paths, multi-cycle paths, clock uncertainty, input/output transition constraints, and operating conditions. Every constraint includes explanatory comments. category: timing-constraints level: intermediate

Purpose

Transform a timing specification into a complete SDC file that can be directly fed to synthesis (Design Compiler / Genus) and place & route (Innovus / ICC2). The SDC must be syntactically correct, logically complete, and include explanatory comments for every constraint section.

Input Specification

The user provides:

Required

  • Primary clock(s): Name, port, period, duty cycle (default 50%)
  • Or a text description: "I have a 100MHz system clock on port sys_clk, a 50MHz SPI clock, and a divided-by-2 clock from the system clock"

Optional

  • Generated clock definitions (source, divide ratio)
  • I/O delay budgets (or target technology and external chip specs)
  • Clock groups (physically exclusive, logically exclusive, asynchronous)
  • False path specifications
  • Multi-cycle path specifications
  • Clock uncertainty budget
  • Input transition / output load constraints
  • Operating conditions (PVT corner)
  • Wire load model
  • Max fanout / max transition / max capacitance limits

Core Design Rules

Rule 1: Clock Definition Order Matters

Define clocks in dependency order:

  1. Primary clocks (from ports/PLLs)
  2. Generated clocks (derived from primary)
  3. Virtual clocks (for I/O constraint reference)

Rule 2: Every Primary Input/Output Needs a Delay

For chip-level SDC, every input port needs set_input_delay and every output port needs set_output_delay. If not specified, add conservative defaults:

tcl
# Default conservative I/O constraints (60% of clock period)
set_input_delay -clock [get_clocks clk] -max [expr {$period * 0.6}] [all_inputs]
set_output_delay -clock [get_clocks clk] -max [expr {$period * 0.6}] [all_outputs]

Rule 3: Clock Groups Prevent False Paths

Any two clocks that are not synchronized must be declared as asynchronous or physically exclusive. Failure to do so causes tools to analyze all cross-clock paths — wasting runtime and potentially masking real violations.

tcl
# Async clocks: independent, no phase relationship
set_clock_groups -asynchronous \
  -group [get_clocks clk_sys] \
  -group [get_clocks clk_spi]

# Physically exclusive: only one active at a time (muxed clocks)
set_clock_groups -physically_exclusive \
  -group [get_clocks clk_100m] \
  -group [get_clocks clk_50m]

Rule 4: No Path Should Be Unconstrained

After writing SDC, run check_timing in the target tool. Any unconstrained endpoints (inputs without input delay, outputs without output delay) are blind spots in timing analysis.

Rule 5: Use Meaningful Constraint Names

tcl
# BAD
set_clock_uncertainty 0.1 [get_clocks clk]

# GOOD — what kind of uncertainty? Why?
set_clock_uncertainty -setup 0.1 -hold 0.05 \
  [get_clocks clk] \
  -comment "PLL jitter: 50ps RMS, clock tree skew budget: 50ps"

Output Specification

The generated SDC file must follow this structure:

tcl
# =============================================================================
# SDC Constraints File
# Design: [design_name]
# Generated by: ICHDL Agent (sdc-writer)
# Date: [date]
# =============================================================================

# ---- Operating Conditions ----
set_operating_conditions [condition_name]
set_wire_load_model -name [model_name]

# ---- Clock Definitions ----
# Primary clock: [name], period [value]ns, duty [value]%
create_clock -name [name] -period [value] -waveform [wave] [port]
# Generated clock: [name], derived from [source], divide by [N]
create_generated_clock -name [name] -source [source] -divide_by [N] [pin]

# ---- Clock Uncertainty ----
set_clock_uncertainty -setup [value] [clocks]
set_clock_uncertainty -hold [value] [clocks]

# ---- I/O Delays ----
# Input delays
set_input_delay -clock [clock] -max [value] [ports]
set_input_delay -clock [clock] -min [value] [ports]
# Output delays
set_output_delay -clock [clock] -max [value] [ports]
set_output_delay -clock [clock] -min [value] [ports]

# ---- Clock Groups ----
set_clock_groups -asynchronous -group [clk1] -group [clk2]

# ---- Timing Exceptions ----
# False paths
set_false_path -from [from] -to [to]
# Multi-cycle paths
set_multicycle_path [N] -from [from] -to [to]

# ---- Design Rules ----
set_max_fanout [value] [current_design]
set_max_transition [value] [current_design]

# ---- End of SDC ----

Examples

Example 1: Simple Single-Clock Design

Input: "100MHz clock on port clk, 60% I/O budget, max fanout 32."

tcl
create_clock -name clk -period 10.0 -waveform {0 5} [get_ports clk]
set_clock_uncertainty -setup 0.1 [get_clocks clk]
set_clock_uncertainty -hold 0.05 [get_clocks clk]
set_input_delay -clock clk -max 6.0 [all_inputs]
set_input_delay -clock clk -min 1.0 [all_inputs]
set_output_delay -clock clk -max 6.0 [all_outputs]
set_output_delay -clock clk -min 1.0 [all_outputs]
set_max_fanout 32 [current_design]
set_max_transition 0.5 [current_design]

Example 2: Multi-Clock SoC

Input: "200MHz system clock, 50MHz peripheral clock (async to system), 20MHz external memory clock, divided-by-2 clock from system clock."

tcl
# Primary clocks
create_clock -name clk_sys  -period 5.0  -waveform {0 2.5}  [get_ports clk_sys]
create_clock -name clk_peri -period 20.0 -waveform {0 10.0} [get_ports clk_peri]
create_clock -name clk_mem  -period 50.0 -waveform {0 25.0} [get_ports clk_mem]

# Generated clock
create_generated_clock -name clk_sys_div2 -source [get_ports clk_sys] \
  -divide_by 2 [get_pins clk_div_reg/Q]

# Clock groups — all are independent
set_clock_groups -asynchronous \
  -group [get_clocks clk_sys clk_sys_div2] \
  -group [get_clocks clk_peri] \
  -group [get_clocks clk_mem]

# I/O constraints per clock domain
set_input_delay  -clock clk_sys  -max 3.0 [get_ports sys_*]
set_output_delay -clock clk_sys  -max 3.0 [get_ports sys_*]
set_input_delay  -clock clk_peri -max 12.0 [get_ports peri_*]
set_output_delay -clock clk_peri -max 12.0 [get_ports peri_*]
set_input_delay  -clock clk_mem  -max 30.0 [get_ports mem_*]
set_output_delay -clock clk_mem  -max 30.0 [get_ports mem_*]

Interaction with Other Skills

  • verilog-module: The module this SDC constrains
  • cdc-synchronizer: Cross-clock paths that need false_path or max_delay
  • rtl-reviewer: Verify SDC-to-design consistency

Disclaimer

This skill is provided "as is" for reference and educational purposes only. Code generated using this skill should be independently reviewed and verified before use in any production design, tape-out, or safety-critical application. The author(s) and ICHDL assume no liability for any errors, omissions, or damages arising from the use of this skill or any code generated with it.

Usage Rights

You are free to use, modify, and distribute this skill for personal or commercial purposes. Attribution to ICHDL (ichdl.com) is appreciated but not required. Redistribution of this skill in substantially unmodified form must retain this notice.

Download this Skill as .md file

Copy into your AI Agent's system prompt to activate this Skill.