クロックの定義

[] [] []


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固有

最初に、これを使ってタイミング解析まで実行した後にTimingAnalyzerSDCファイルを書き出すと、自動抽出された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_rb_r共にclkin1またはclkin2で駆動されているパスだけ解析したいが、この他にa_rclkin1b_rclkin2で駆動されているバスもデフォルトでは解析されてしまうので、clkin1clkin2は排他的と指定する必要がある。

set_clock_groups -logically_exclusive -group clkin1 -group clkin2

◇◇◇◇

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

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

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

derive_clock_uncertainty  ←Quartus固有


[] [] []