チートシート

XDCとSDC制約チートシート

VivadoのXDCとQuartusのSDCで毎週書くタイミング制約とピン制約を、Latticeの対応表記、実践パターン、よくある間違いの表とともにまとめます。

AMDAltera最終確認 2026年11月13日· Vivado 2026.1, Quartus Prime Pro 26.3, Radiant 2026.1

このシートは、制約(constraint)の目的は知っていて、正確な構文が必要なエンジニアのためのものです。VivadoはXDCを読みます。XDCはSDCにset_propertyを加えたものです。Quartus PrimeはタイミングにSDCを、ピンには別のQSFファイルを読みます。Lattice RadiantはSDCに似たタイミング記述を.pdcファイルから読み、Diamondは.lpfを使います。オプションの一覧は末尾にリンクしたベンダーのマニュアルを参照してください。

クロック

作業 XDC(Vivado) SDC(Quartus Prime)
ピン上のプライマリクロック create_clock -period 10.000 -name clk_in [get_ports clk_in] create_clock -period 10.0 -name clk_in [get_ports clk_in]
デューティ比25%のクロック -waveform {0 2.5}を追加 同じ
PLLまたはMMCMからのクロック 自動的に導出される derive_pll_clocks(Standard)または自動(Pro)
手動の生成クロック create_generated_clock -name clk_div2 -source [get_pins u_div/clk] -divide_by 2 [get_pins u_div/q_reg/Q] 同じ構文
リカバリクロックや外部ソース上のクロック create_clock -period 8.000 [get_pins u_gt/RXOUTCLK] 同じ
ツールが見つけたクロックの報告 report_clocks report_clocks
ジッタと不確かさ set_clock_uncertainty -setup 0.100 [get_clocks clk_in] derive_clock_uncertainty(必ず一度実行する)
# Vivado: a 100 MHz board clock and a clock-enable style divided clock
create_clock -period 10.000 -name sys_clk [get_ports sys_clk_p]
create_generated_clock -name clk_div4 -source [get_pins u_div/clk_i] \
    -divide_by 4 [get_pins u_div/div_reg[1]/Q]

生成クロックを定義するのは、ロジック(トグルするフリップフロップ)で作ったクロックだけにしてください。PLL、MMCM、クロックバッファから出るクロックはツールが導出します。そもそも分周クロックよりクロックイネーブルを優先してください。

I/O遅延

外部遅延はクロックを基準に指定します。ツールはその上で、ピンから最初のレジスタまで(入力)、または最後のレジスタからピンまで(出力)のパスを検査します。

作業 XDCとSDC(同じ構文)
入力、システム同期 set_input_delay -clock sys_clk -max 2.5 [get_ports data_in[*]]と-min 0.5
入力、DDR、両エッジ 立ち下がりエッジ側に-clock_fall -add_delayを追加
出力 set_output_delay -clock sys_clk -max 1.0 [get_ports data_out[*]]と-min -0.5
ソース同期入力 転送されたクロックピンにcreate_clock、その後set_input_delay -clock fwd_clk
ソース同期出力 転送クロックのポートにcreate_generated_clock、その後set_output_delay -clock fwd_clk_out
# Source-synchronous ADC interface, data centred on the forwarded clock
create_clock -period 8.000 -name adc_clk [get_ports adc_clk]
set_input_delay -clock adc_clk -max 1.200 [get_ports adc_d[*]]
set_input_delay -clock adc_clk -min 0.300 [get_ports adc_d[*]]
set_input_delay -clock adc_clk -max 1.200 -clock_fall -add_delay [get_ports adc_d[*]]
set_input_delay -clock adc_clk -min 0.300 -clock_fall -add_delay [get_ports adc_d[*]]

-maxの値はクロックエッジの後にデータが到着しうる最も遅い時刻(セットアップ側)、-minはデータが変化しうる最も早い時刻(ホールド側)です。出力では-maxが外部のセットアップ要件、-minが外部のホールド要件にマイナスを付けたものです。計算は/reference/timing-formulae/を参照してください。

例外

作業 コマンド 使う場面
無関係なクロック領域 set_clock_groups -asynchronous -group [get_clocks clk_a] -group [get_clocks clk_b] 両領域の間が適切な同期化回路で渡されている
1本のパスのタイミングを無視 set_false_path -from [get_cells u_a/cfg_reg*] -to [get_cells u_b/sync_reg[0]] 安定してからずっと後にサンプルされる静的な設定ビット
リセット解除 set_false_path -from [get_ports rst_n] リセット同期化回路に入る非同期入力
遅いパス、Nサイクル set_multicycle_path -setup 2 -from [get_cells a_reg*] -to [get_cells b_reg*]とset_multicycle_path -hold 1 ... クロックイネーブルのためデータがNサイクルに1回しか使われない
乗り換えの遅延を制限 set_max_delay -datapath_only 5.000 -from [get_cells src_reg*] -to [get_cells dst_reg*](Vivado) ビット間スキューが問題になるバスの乗り換え
バススキュー set_bus_skew -from [get_cells gray_reg*] -to [get_cells sync_reg*] 2.000(Vivado 2018.1以降) 非同期FIFOのグレイポインタの乗り換え
# Vivado: a two-cycle path driven by a clock enable
set_multicycle_path -setup 2 -from [get_cells u_dsp/acc_reg*] -to [get_cells u_dsp/out_reg*]
set_multicycle_path -hold  1 -from [get_cells u_dsp/acc_reg*] -to [get_cells u_dsp/out_reg*]

Quartus Primeは-datapath_onlyなしのset_max_delayを受け付けます。クロックスキューは依然として計算に入るので、set_false_path -holdと組み合わせるか、同じ効果を得るためにset_net_delayを使ってください。Quartusではホールド側のマルチサイクル値の数え方がVivadoと異なり、ここでの-hold 1は「終端マイナス1」を意味します。これは通常、-setup 2の後に望む値と一致します。

ピンとI/O規格

作業 Vivado XDC Quartus QSF
ピン位置 set_property PACKAGE_PIN W5 [get_ports clk] set_location_assignment PIN_AF14 -to clk
I/O規格 set_property IOSTANDARD LVCMOS33 [get_ports clk] set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to clk
両方を一度に set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports clk] 2行で書く
差動ペア _pポートにIOSTANDARD LVDS_25、_nピンは追従する 両ピンを割り当て、規格はLVDS
プルアップ set_property PULLUP true [get_ports btn] set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to btn
駆動能力とスルーレート set_property DRIVE 8 ...とset_property SLEW FAST ... -name CURRENT_STRENGTH_NEW 8MAと-name SLEW_RATE 1
未使用ピン set_property BITSTREAM.CONFIG.UNUSEDPIN PULLDOWN [current_design] set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED WITH WEAK PULL-UP"
コンフィギュレーション電圧 set_property CFGBVS VCCO [current_design]とCONFIG_VOLTAGE 3.3 不要
# Vivado: a bus of eight LEDs, one line per pin
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]

Latticeの対応表記

作業 Radiant PDC Diamond LPF
クロック create_clock -period 12.0 -name clk [get_ports clk] FREQUENCY PORT "clk" 83.33 MHz ;
ピン ldc_set_location -site {A9} [get_ports clk] LOCATE COMP "clk" SITE "A9" ;
I/Oタイプ ldc_set_port -iobuf {IO_TYPE=LVCMOS33} [get_ports clk] IOBUF PORT "clk" IO_TYPE=LVCMOS33 ;
フォルスパス set_false_path -from [get_clocks a] -to [get_clocks b] BLOCK PATH FROM CLKNET "a" TO CLKNET "b" ;
マルチサイクル set_multicycle_path 2 -from ... MULTICYCLE FROM CELL "a*" TO CELL "b*" 2 X ;

オープンソースフローでは、iCE40に.pcfファイル(set_io led A5)、nextpnrを使うECP5に.lpfを使い、クロック目標はコマンドラインか、プリパックスクリプト内のset_frequencyで与えます。

間違いと対処

症状 考えられる原因 対処
タイミングパスがまったく報告されず、すべて合格する create_clockがなく、何も制約されていない まずクロックを追加し、check_timing(Vivado)を実行するか「unconstrained paths」レポートを見る
無関係と考えている2つのクロック間で数千のパスが失敗する set_clock_groupsがない すべての乗り換えに同期化回路があることを確認してから、グループを宣言する
セットアップが通った後にI/Oでホールド違反が出る -maxの遅延しか与えていない 出力の負の値も含め、必ず-minも与える
2サイクルに1回しか意味を持たないパスでセットアップ違反 マルチサイクルがない -setup Nと-hold N-1を一緒に追加し、クロックではなくセルで範囲を指定する
タイミングは通るがボードの動作が不安定 I/O遅延をデータシートからではなく推測で与えた データシートの値とボードの配線長からバジェットを組み直す
制約が黙って無視される 合成でリネームされた後のオブジェクト名が違う get_cells -hierarchical -filterを使い、report_propertyで確認し、ネットリストができてから制約を保つ
生成クロックが未制約と報告される -sourceが間違ったピンを指している -sourceは分周レジスタのクロック入力ピンに、ターゲットはその出力に向ける
Vivadoがset_max_delayは効果がないと警告する パスがすでにフォルスパスかクロックグループでカバーされている 広い方の例外を外す。最も具体的な例外が優先されるのは同じ種類の中だけ
バンク電圧の衝突でピン割り当てが失敗する 1つのバンクに複数のI/O規格が混在 規格をバンクごとにまとめ、回路図でVCCOを確認する
QuartusがSDC例外に対して「no paths」と報告する Proは完全な階層名を使い、Standardはワイルドカードの扱いが異なる Proではget_registersにフルパスを与える

出典

誤りやバージョン変更に気づいたら 訂正の手順をご覧ください。