クロックの定義

[] [] []


SDCフォーマットで決められているわけではないが、クロックは次の3種類に分けて考えるとよい。

クロック

説明

基本クロック

他とは独立なクロック(例:外部から入力したクロック,内部SerDesの出力クロック)

派生クロック

他のクロックから生成した(例:内部のPLLで生成したクロック,FFで分周したクロック)

仮想クロック

入出力タイミングの制約に使う、仮想的な外部FFのクロック

 

基本クロックは、周期とエッジの位相を次の構文で指定する

ここで立上がりエッジの位相を指定するということは、複数のクロック同士は独立ではなく同期していると見なされるということである。

create_clock

[-name clockName]                     基本クロックのオブジェクト名、省略するとclockPortNameと同じになる

-period periodValue                  周期(ns単位)

[-waveform {riseValue fallValue}]  立上がりと立下がりエッジの位相(ns単位)、省略すると立上がりが0ns,Duty=50%になる

clockPortName                         クロック入力ポート、クロック出力ピン、またはネットのオブジェクト名

例1)入力ポートclkin1100MHz,Duty=50%のクロック波形が入力されている。入力ポートclkin22ns遅れたクロック波形が入力されている。

create_clock -name clkin1 -period 10 [get_ports {clkin1}]

create_clock -name clkin2 -period 10 -waveform {2 7} [get_ports {clkin2}]

◇◇

FFで分周したクロックは自動抽出されないので、派生クロックとして分周比を指定する。派生クロックの位相は自動抽出されるので指定しなくてよい。

create_generated_clock

[-name clockName]                      派生クロックのオブジェクト名。省略するとclockPinNameと同じになる。

-source clockPortName              派生元のクロック入力ポート、または分周FFCLKピンのオブジェクト名

-divide_by value                        分周比(整数)

clockPinName                                分周FFQピン、またはネットのオブジェクト名。

例1)FF2分周している

create_generated_clock -name clkdiv -source [get_ports {clkin}] -divide_by 2 [get_nets {clkdiv}]

RTL記述で分周クロックのネット名をkeep指定しておくと、ネットリスト中のネット名も同じになるので便利。

(* syn_keep=1 *) wire clkdiv;           // Quartusの場合

(* dont_touch="true" *) wire clkdiv;    // Vivadoの場合

2DDRレジスタでクロックを出力している(ソース・シンクロナス・クロック)

create_generated_clock -name clkout -source [get_pins {oddr_inst/C}] -divide_by 1 [get_ports {clkout}]

◇◇◇

PLLで生成したクロックは自動抽出され、派生クロックとして定義される。ただし自動抽出するとクロック名が勝手に付与されてわかりにくいので、ユーザが指定し直した方がよい。

Quartusでは、次のderiveコマンドでPLLの出力クロックを自動抽出できる。

create_clock -name clkin -period 10 [get_ports {clkin}]

derive_pll_clocks        Quartus固有

最初に、これを使ってタイミング解析まで実行した後にTimeQuestSDCファイルを書き出すと、自動抽出されたcreate_generated_clockコマンドが書かれている。これでderiveコマンドを置き換えて、クロック名を直せばよい。

create_generated_clock -name clk0 -source [get_ports {clkin}] -duty_cycle 50 -multiply_by 3

                          [get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[0]}]

Vivadoでは何も指定しなくても自動抽出される。またPLLIP生成時にIP用の制約ファイルができ、その中に入力クロックと入力ジッタが書かれているので、ユーザは指定しなくてよい。

create_clock -name clkin -period 10 [get_ports {clk_in1}]

set_input_jitter clkin 0.1       Vivado固有

しかしPLLのクロック名が勝手に付与されてわかりにくいので、次のようにクロック名だけ指定し直せばよい。このとき、BUFGの出力ピンではなくPLLの出力ピンを指定しなければならないことに注意。

create_generated_clock -name clk0 [get_pins {pll_inst/inst/plle2_adv_inst/CLKOUT0}]         Vivado固有

◇◇◇◇

すべてのクロック同士はデフォルトでは同期していると見なされるので、非同期関係を指定する。

set_clock_groups

-asynchronous                              グループ間は非同期

-group {clockNames}                  グループ内のクロックのオブジェクト名

[-group {clockNames} ...]      グループ内のクロックのオブジェクト名

例1)clkin1clkin2が同期で、clkin3はそれらとは非同期

set_clock_groups -asynchronous -group {clkin1 clkin2} -group {clkin3}

例2)clkin1clkin2MUXで選択したclkを使っている

通常はa_regb_reg共にclkin1またはclkin2で駆動されているパスだけ解析したいが、この他にa_regclkin1b_regclkin2で駆動されているバスもデフォルトでは解析されてしまうので、clkin1clkin2非同期であると指定する必要がある。

set_clock_groups -asynchronous -group clkin1 -group clkin2

お、Quartus,Vivadoには-logically_exxlusiveというオプションも用意されているが、-asynchronousとタイミング解析上は同じ意味になる。

◇◇◇◇

クロックのジッタはClock Uncertaintyという量で表される。

Vivadoでは、ジッタは自動抽出されるので指定しなくてよい。

Quartusでは、ジッタが自動抽出されるように次のコマンドを書いておくと、タイミングネットリスト更新時に自動抽出される。(書く位置はどこでもよいということ)

derive_clock_uncertainty        Quartus固有


[] [] []