⏱️ SDC 클럭 제약조건(create_clock, create_generated_clock) - 기초편

SDC 클럭 제약조건 완벽 가이드: create_clock과 create_generated_clock

⏱️ SDC 클럭 제약조건 완벽 가이드

create_clock과 create_generated_clock 마스터하기

디지털 설계에서 정확한 타이밍은 성공의 핵심입니다. SDC(Synopsys Design Constraints)는 합성 및 STA 툴에 타이밍 정보를 전달하는 표준 언어입니다. 이 가이드에서는 클럭 정의의 핵심인 create_clockcreate_generated_clock을 상세히 다룹니다.

📚 1. SDC 개요

SDC (Synopsys Design Constraints)는 타이밍 제약조건을 기술하는 업계 표준 포맷입니다. Tcl 문법을 기반으로 합니다.

RTL Design
SDC 제약조건
Synthesis
STA
📌 SDC의 역할

• 클럭 정의: 클럭 주파수, 파형, 지터 등 명시
• 입출력 타이밍: I/O delay, transition time 설정
• 경로 예외: False path, multicycle path 지정
• 환경 설정: 동작 조건, 부하 모델링

SDC 파일 기본 구조

📄 example.sdc
# ============================================ # Clock Definitions # ============================================ create_clock -period 10 [get_ports clk] # ============================================ # Generated Clocks # ============================================ create_generated_clock -name clk_div2 \ -source [get_ports clk] \ -divide_by 2 [get_pins div_reg/Q] # ============================================ # I/O Constraints # ============================================ set_input_delay -clock clk 2.0 [get_ports data_in] set_output_delay -clock clk 1.5 [get_ports data_out] # ============================================ # Timing Exceptions # ============================================ set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]

⏰ 2. create_clock

create_clock은 설계의 기본 클럭(Master Clock)을 정의하는 명령어입니다.

📄 기본 문법
create_clock -period <period_ns> # 필수: 주기 (ns) [-waveform {rise fall}] # 선택: 파형 정의 [-name <clock_name>] # 선택: 클럭 이름 [-add] # 선택: 추가 클럭 정의 [<source>] # 클럭 소스 (port/pin)

주요 파라미터

-period필수
클럭 주기를 ns 단위로 지정
-period 10 → 100MHz
-period 5 → 200MHz
-waveform선택
{상승엣지 하강엣지} 시점 지정
기본값: {0 period/2} (50% duty)
-waveform {0 3}
-name선택
클럭에 이름 부여
Virtual clock 정의 시 필수
-name sys_clk
-add선택
동일 소스에 추가 클럭 정의
MUX 출력 등에서 사용
여러 클럭 공존 시 필요

예제

📄 create_clock 예제
# 기본: 10ns 주기 (100MHz) 클럭 create_clock -period 10 [get_ports CLK_IN] # 이름 지정: SYS_CLK create_clock -period 10 -name SYS_CLK [get_ports CLK_IN] # 6ns 주기, 30% duty cycle (상승 0ns, 하강 1.8ns) create_clock -period 6 -waveform {0 1.8} [get_ports FAST_CLK] # 동일 포트에 두 개의 클럭 정의 (MUX 출력) create_clock -period 10 -name CLK_A [get_ports MUX_CLK] create_clock -period 20 -name CLK_B -add [get_ports MUX_CLK]

📊 3. Waveform 이해

-waveform 옵션은 클럭의 정확한 엣지 타이밍을 정의합니다.

📊 Waveform 예시: -period 10 -waveform {0 5} (기본 50% duty) Time(ns) 0 2 4 6 8 10 12 14 16 18 20 | | | | | | | | | | | CLK ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ │ │ ───┘ └─────┘ └─────┘ └─────┘ └─────┘ └─── Rise@0 Rise@10 Rise@20 Rise@30 Rise@40 📊 Waveform 예시: -period 10 -waveform {0 3} (30% duty) Time(ns) 0 2 4 6 8 10 12 14 16 18 20 | | | | | | | | | | | CLK ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │ │ │ │ │ │ │ │ ───┘ └────────┘ └────────┘ └────────┘ └────────┘ └─── ↑ ↑ ↑ ↑ 0ns 3ns 10ns 13ns
💡 Waveform 계산법

Duty Cycle 계산:
duty = (fall - rise) / period × 100%

예시: -period 10 -waveform {2 7}
→ 상승: 2ns, 하강: 7ns
→ High 구간: 5ns, duty = 50%
위상 시프트: 2ns 지연된 클럭

🌐 4. Virtual Clock

Virtual Clock은 설계 내부에 물리적으로 존재하지 않지만, 외부 인터페이스 타이밍을 위해 정의하는 가상 클럭입니다.

📄 Virtual Clock 예제
# Virtual Clock 정의 (소스 없이 -name만 사용) create_clock -period 8 -name EXT_CLK # 외부 인터페이스의 입력 지연 설정 set_input_delay -clock EXT_CLK 2.0 [get_ports data_in] # 외부 인터페이스의 출력 지연 설정 set_output_delay -clock EXT_CLK 1.5 [get_ports data_out]
📌 Virtual Clock 사용 시점

• 외부 소스 동기 클럭: 칩 외부에서 생성되는 클럭 기준
• 시스템 레벨 타이밍: 보드 레벨 인터페이스 제약
• I/O 분리: 내부 클럭과 다른 타이밍 요구사항

🔄 5. create_generated_clock

create_generated_clockMaster Clock에서 파생된 클럭을 정의합니다. PLL, 분주기, MUX 출력 등에 사용됩니다.

📄 기본 문법
create_generated_clock -name <clock_name> # 생성 클럭 이름 -source <master_pin> # 마스터 클럭 소스 [-master_clock <clk>] # 멀티 클럭 시 마스터 지정 [-divide_by <factor>] # 분주 비율 [-multiply_by <factor>] # 체배 비율 [-duty_cycle <percent>] # Duty cycle 지정 [-edges {e1 e2 e3}] # 엣지 매핑 [-add] # 추가 클럭 정의 <target_pin> # 생성 클럭 출력 핀

주요 파라미터

파라미터 설명 예시
-source 마스터 클럭이 인가되는 핀 [get_pins pll/CLK_IN]
-master_clock 소스에 여러 클럭 시 마스터 지정 -master_clock CLK_A
-divide_by 분주 비율 (주파수 ÷ N) -divide_by 2 → 절반 속도
-multiply_by 체배 비율 (주파수 × N) -multiply_by 3 → 3배 속도
-duty_cycle Duty cycle 백분율 -duty_cycle 25 → 25%
-edges 마스터 엣지 매핑 -edges {1 3 5}

🔢 6. 분주/체배 클럭

분주 클럭 (-divide_by)

📊 2분주 클럭: -divide_by 2 (마스터 10ns → 생성 20ns) Time(ns) 0 5 10 15 20 25 30 35 40 | | | | | | | | | Master ┌────┐ ┌────┐ ┌────┐ ┌────┐ (10ns) │ │ │ │ │ │ │ │ ───┘ └────┘ └────┘ └────┘ └─── Generated ┌─────────┐ ┌─────────┐ (20ns) │ │ │ │ ───┘ └─────────┘ └─────────
📄 분주 클럭 예제
# 마스터 클럭 정의 create_clock -period 10 -name CLK_MASTER [get_ports clk_in] # 2분주 클럭 (100MHz → 50MHz) create_generated_clock -name CLK_DIV2 \ -source [get_ports clk_in] \ -divide_by 2 \ [get_pins div2_reg/Q] # 4분주 클럭 (100MHz → 25MHz) create_generated_clock -name CLK_DIV4 \ -source [get_ports clk_in] \ -divide_by 4 \ [get_pins div4_reg/Q]

체배 클럭 (-multiply_by)

📊 2체배 클럭: -multiply_by 2 (마스터 10ns → 생성 5ns) Time(ns) 0 2.5 5 7.5 10 12.5 15 17.5 20 | | | | | | | | | Master ┌─────────┐ ┌─────────┐ (10ns) │ │ │ │ ───┘ └─────────┘ └───────── Generated ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ (5ns) │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ───┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──
📄 체배 클럭 예제 (PLL)
# 마스터 클럭 정의 create_clock -period 10 -name CLK_REF [get_ports clk_in] # 2체배 클럭 (100MHz → 200MHz) create_generated_clock -name CLK_MUL2 \ -source [get_pins pll_inst/CLKIN] \ -multiply_by 2 \ [get_pins pll_inst/CLKOUT] # 분수비 클럭 (100MHz × 4/3 = 133.33MHz) create_generated_clock -name CLK_FRAC \ -source [get_pins mmcm/CLKIN] \ -multiply_by 4 \ -divide_by 3 \ [get_pins mmcm/CLKOUT]

🔲 7. -edges 옵션

-edges는 마스터 클럭의 특정 엣지를 생성 클럭의 엣지에 직접 매핑합니다.

📌 엣지 번호 규칙

마스터 클럭의 엣지는 순차적으로 번호가 매겨집니다:
1 = 첫 번째 상승엣지 (0ns)
2 = 첫 번째 하강엣지 (period/2)
3 = 두 번째 상승엣지 (period)
4 = 두 번째 하강엣지 ...

-edges {a b c}
a = 생성 클럭 상승, b = 생성 클럭 하강, c = 다음 상승

📊 -edges 예시: -edges {1 3 5} (2분주와 동일) Master Edge# 1 2 3 4 5 6 7 8 9 Time 0ns 5ns 10ns 15ns 20ns 25ns 30ns 35ns 40ns Master ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ───┘ └────┘ └────┘ └────┘ └────┘ └─── 1 3 5 7 9 Generated ┌─────────┐ ┌─────────┐ ┌──── ───┘ └─────────┘ └─────────┘ Rise Fall Rise (edge1) (edge3) (edge5)
📄 -edges 예제
# 마스터 클럭: 10ns 주기 create_clock -period 10 -name CLK [get_ports clk] # 2분주 (edges 방식) create_generated_clock -name CLK_DIV2_EDGE \ -source [get_ports clk] \ -edges {1 3 5} \ [get_pins div2_ff/Q] # 비대칭 Duty (상승@edge1, 하강@edge2, 다음상승@edge5) # → High: edge1~edge2 (5ns), Low: edge2~edge5 (15ns) create_generated_clock -name CLK_ASYM \ -source [get_ports clk] \ -edges {1 2 5} \ [get_pins asym_ff/Q]
⚠️ -edges 사용 시 주의

-edges-divide_by, -multiply_by동시 사용 불가합니다.
엣지 번호는 반드시 오름차순이어야 합니다.

클럭 정의 후 추가적인 타이밍 속성을 설정하는 명령어들입니다.

📄 클럭 관련 추가 명령어
# ============================================ # Clock Uncertainty (지터, 스큐 등) # ============================================ set_clock_uncertainty -setup 0.2 [get_clocks CLK] set_clock_uncertainty -hold 0.1 [get_clocks CLK] # Inter-clock uncertainty (CDC) set_clock_uncertainty -from [get_clocks CLK_A] \ -to [get_clocks CLK_B] 0.3 # ============================================ # Clock Latency (소스/네트워크 지연) # ============================================ # Source latency: 클럭 소스에서 포트까지 set_clock_latency -source 1.5 [get_clocks CLK] # Network latency: 포트에서 레지스터까지 set_clock_latency 0.8 [get_clocks CLK] # ============================================ # Clock Transition (상승/하강 시간) # ============================================ set_clock_transition 0.15 [get_clocks CLK] # ============================================ # Clock Groups (비동기 클럭 관계) # ============================================ set_clock_groups -asynchronous \ -group [get_clocks CLK_A] \ -group [get_clocks CLK_B]
명령어 용도
set_clock_uncertainty 지터, PVT 변동, 스큐 마진 설정
set_clock_latency 클럭 네트워크 지연 설정
set_clock_transition 클럭 엣지 슬루율 설정
set_clock_groups 클럭 간 관계 정의 (동기/비동기)

🔀 9. Clock Domain Crossing (CDC)

서로 다른 클럭 도메인 간의 데이터 전송에는 특별한 처리가 필요합니다.

📌 CDC SDC 설정

동기 클럭: 동일 소스에서 파생, 위상 관계 예측 가능
비동기 클럭: 독립 소스, 위상 관계 불확정

비동기 CDC 경로는 STA에서 false path로 설정해야 합니다.

📄 CDC 관련 SDC 설정
# 비동기 클럭 그룹 설정 set_clock_groups -asynchronous \ -group [get_clocks {CLK_A CLK_A_DIV2}] \ -group [get_clocks {CLK_B CLK_B_DIV4}] # 또는 개별 false path 설정 set_false_path -from [get_clocks CLK_A] -to [get_clocks CLK_B] set_false_path -from [get_clocks CLK_B] -to [get_clocks CLK_A] # 동기 클럭 (같은 소스 파생) - max_delay 설정 set_max_delay 2.0 -from [get_clocks CLK] -to [get_clocks CLK_DIV2]

✅ 동기 클럭

• 같은 PLL/소스에서 파생
• 위상 관계 고정
• STA 분석 가능
set_clock_groups -logically_exclusive

⚠️ 비동기 클럭

• 독립 클럭 소스
• 위상 관계 불확정
• Synchronizer 필요
set_clock_groups -asynchronous

💡 10. 실전 팁

✅ 모범 사례

1. 모든 클럭에 명시적 -name 부여
2. Generated clock은 항상 올바른 -source 지정
3. PLL 출력은 각각 별도의 generated clock 정의
4. 비동기 클럭은 명시적으로 set_clock_groups 설정
5. report_clocks로 정의된 클럭 확인

❌ 흔한 실수

1. -source에 마스터 클럭 핀 대신 출력 핀 지정
2. MUX 출력에 -add 누락
3. -edges-divide_by 동시 사용
4. 비동기 CDC 경로에 false path 미설정
5. Virtual clock으로 internal path 분석

디버깅 명령어

📄 클럭 확인 명령어
# 정의된 모든 클럭 확인 report_clocks # 특정 클럭 상세 정보 report_clocks [get_clocks CLK_DIV2] # 클럭 네트워크 확인 report_clock_networks # 클럭 그룹 확인 report_clock_groups # Generated clock 소스 추적 get_attribute [get_clocks CLK_DIV2] sources

툴별 차이점

특이사항
Synopsys DC SDC 표준 원조, 완벽 지원
Cadence Genus/Innovus SDC 호환, 일부 확장 명령 존재
Xilinx Vivado XDC 포맷 (SDC 기반), -of_objects 확장
Intel Quartus SDC 호환, TimeQuest Analyzer

📌 핵심 요약

명령어 용도 핵심 옵션
create_clock Master Clock 정의 -period, -waveform
create_generated_clock 파생 Clock 정의 -source, -divide_by, -edges
set_clock_uncertainty 지터/스큐 마진 -setup, -hold
set_clock_groups 클럭 관계 설정 -asynchronous

기억하세요:
create_clock은 물리적/가상 기본 클럭 정의
create_generated_clock은 PLL/분주기 출력 정의
✓ 비동기 CDC는 반드시 set_clock_groups 또는 set_false_path 설정

📚 참고 자료

IEEE 1801: SDC 표준 문서
Synopsys: Design Compiler User Guide
AMD/Xilinx: Vivado Design Suite User Guide (UG903)
Intel: Quartus Prime Timing Analyzer

댓글

이 블로그의 인기 게시물

📚 SDC 마스터 클래스 시리즈 | Chapter 1

📚 SDC 마스터 클래스 시리즈 | Chapter 2

📚 SDC 마스터 클래스 시리즈 | Chapter 3