Vivadoでクロックの名前を付けなおしてset_false_pathを設定する
インタフェースが絡んでくると複数のクロックを使う必要が出てきて、Vivadoはクロック間のタイミングでエラーを出してきます。
タイミングエラーはCritical Warningであるだけではなく、routingにかかる時間が激増するので、早めに解決しておきたいものです。
これを防ぐにはset_falth_pathといって「この信号はタイミング解析しない=エラーがあっても構わない」という指示を出すのですが、set_falth_pathの指定には正式なクロック名を使って-from -toで設定しなければなりません。
しかしながら、タイミングレポートを見てもクロック信号名は論理合成中にいろいろとリネームされているので、どのクロックがどんな名前なのか一見してさっぱりわからなくなっています。
そこで、クロックの名前をリネームしてset_false_path設定するスマートなやり方を考えたので紹介します。
上の図のタイミングレポートを見てみてください。Timingがエラーを起こしてしまっていて、clk_out1_clk_wiz_0とclk_out1_design_1_clk_wiz_0_0という2つのクロック間でのタイミングが満たされていないようです。
set_falth_pathの書式は、
set_false_path -from [get_pins 生成元クロック] -to [get_ports 宛先クロック]
ですから、エラーを出しているクロック名を調べて、互いに
set_false_path -from [get_clocks clk_out1_clk_wiz_0] -to [get_clocks clk_out1_design_1_clk_wiz_0_0]
set_false_path -from [get_clocks clk_out1_design_1_clk_wiz_0_0] -to [get_clocks clk_out1_clk_wiz_0]
とすれば解決です。
おしまい!志低くしていくならこれで十分です。
ただ、これだと何のことかわからないし、本当に無視していいクロックの関係なのかも怪しくなってきます。
ユーザがHDLで書いたクロック名から変わってしまっているので、名前を見ただけではどういうクロックなのかわかりません。まずはリネームすることを考えましょう。
クロックをリネームするには、tclのcreate_generated_clock コマンドを使うのですが、書式を見ると
create_generated_clock -name new_name [-source source_pin] [-master_clock master_clk] source_object
となっていて、source_pinやmaster_clkに何を指定してよいのか一層わからなくなります。おまけに、アンサーだかフォーラムによればMMCMで作ったクロックはタイミング解析が伝搬するからcreate_generated_clockを使う必要はないよ、とまで書かれています。いや、そうじゃない。MMCMのクロックをリネームしたいんだよ。
やりたいことは、論理合成中にぐちゃぐちゃな名前になったクロックを、ユーザがわかりやすいクロック名に変更してset_falth_pathを設定することです。
それでは順番に解決していきましょう。
まずは、tclコンソールに get_clocks と入力します。
get_clocks
usb_clkout_ip clkfbout_clk_wiz_0 clk_out1_clk_wiz_0 xtalclk_ip clkfbout_design_1_clk_wiz_0_0 clk_out1_design_1_clk_wiz_0_0
このデザインで使われているクロックのリストが出てきました。
ここで、list_property [get_clocks クロック名] とするとクロックの持っているプロパティの一覧が得られるので、やってみましょう。
list_property [get_clocks clk_out1_clk_wiz_0]
CLASS DIVIDE_BY DUTY_CYCLE EDGES EDGE_SHIFT FILE_NAME INPUT_JITTER IS_GENERATED IS_INVERTED IS_PROPAGATED IS_RENAMED IS_USER_GENERATED IS_VIRTUAL LINE_NUMBER MASTER_CLOCK MULTIPLY_BY NAME PERIOD SOURCE SOURCE_PINS SYSTEM_JITTER WAVEFORM
いろいろなプロパティがあるのがわかります。NahiVivaに含まれている便利マクロ _NahiShowAllProperty を使って調べてみると、
_NahiShowAllProperty [get_clocks clk_out1_clk_wiz_0]
CLASS <= clock
DIVIDE_BY <=
DUTY_CYCLE <=
EDGES <=
EDGE_SHIFT <=
FILE_NAME <=
INPUT_JITTER <= 0.000
IS_GENERATED <= 1
IS_INVERTED <= 0
IS_PROPAGATED <= 1
IS_RENAMED <= 0
IS_USER_GENERATED <= 0
IS_VIRTUAL <= 0
LINE_NUMBER <=
MASTER_CLOCK <= usb_clkout_ip
MULTIPLY_BY <= 1
NAME <= clk_out1_clk_wiz_0
PERIOD <= 16.670
SOURCE <= design_1_i/axi_ftsyncfifo_0/U0/INST_CLK_WIZ/inst/plle2_adv_inst/CLKIN1
SOURCE_PINS <= design_1_i/axi_ftsyncfifo_0/U0/INST_CLK_WIZ/inst/plle2_adv_inst/CLKOUT0
SYSTEM_JITTER <= 0.050
WAVEFORM <= 0.000 8.335
いろいろな情報が出てきました。このクロックを生成しているプリミティブのソースがSOURCEで、出力がSOURCE_PINSであることが想像できます。だから、クロックのピンを得るtclコマンドは
[get_pin [get_property SOURCE_PINS [get_clocks clk_out1_clk_wiz_0]]]
でよいことがわかります。
clk_out1_clk_wiz_0をusbclkに、clk_out1_design_1_clk_wiz_0_0をadcclkにそれぞれリネームしてあげましょう。
create_generated_clock -name usbclk [get_pins [get_property SOURCE_PINS [get_clocks clk_out1_clk_wiz_0]]]
create_generated_clock -name adcclk [get_pins [get_property SOURCE_PINS [get_clocks clk_out1_design_1_clk_wiz_0_0]]]
これで名前が付きました。
あとは、お互いにset_false_pathを設定すればOKです。
set_false_path -from [get_clocks usbclk] -to [get_clocks adcclk]
set_false_path -from [get_clocks adcclk] -to [get_clocks usbclk]
まとめると、
① まずは、デザインを開く(Open Implemented DesignまたはOpen Synthesized Designを行う)
② get_clocksでどのようなクロックがあるか調べる
③ 調べたクロックを
create_generated_clock -name 新しい名前 [get_pins [get_property SOURCE_PINS [get_clocks クロック名]]]
でリネームする(xdcに記述)
④ set_falth_path -from [get_clocks ソース] -to [get_clocks 宛先]
でタイミング解析から除外する(xdcに記述)
です。
これでクロックに名前が付くのでわかりやすくなり、タイミング解析されなくなるのでCritical Warningを消すことができます。
| 固定リンク
コメント
set_clock_groups -asynchronous
を使うとclk_a→clk_b、clk_b→clk_aの2つ書かなくてよくなるのでこちらも有用ですよ
投稿: | 2021.02.09 13:49
とても参考になりました。
非同期のクロックドメインは"set_clock_groups -asynchronous ..."の構文で書くとより楽かと思います。(AR# 44651)
https://support.xilinx.com/s/article/44651?language=ja
投稿: | 2023.01.24 15:55