クロックの定義

[] [] []


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

クロック

説明

基本クロック

他とは独立なクロック

例)外部から入力したクロック,内部SerDesの出力クロック

派生クロック

他クロックから生成したクロック

例)内部のPLLで生成したクロック,FFで分周したクロック

仮想クロック

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

 

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

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

create_clock

-name clockName        仮想クロックのオブジェクト名

-period periodValue      周期(ns単位)

[-waveform {rise fall}] エッジの位相(ns単位)。省略するとrise=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の場合

◇◇◇

内部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のクロック名が勝手に付与されてわかりにくいので、次のようにクロック名だけ指定し直すとよい。このときピン名は、合成後のネットリストをopenしてTCLコマンド report_clocksで調べられる。

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

◇◇◇◇

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

set_clock_groups

-asynchronous             グループ間は非同期

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

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

例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_exclusiveというオプションも用意されているが、-asynchronousとタイミング解析上は同じ意味になる。

◇◇◇◇

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

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

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

derive_clock_uncertainty       ←Quartus固有


[] [] []