こんにちは。とぷぅです !
今回は 1 年間を通して最も理解に苦しんだタイミング解析についてまとめたいと思います。
FPGA 初心者の方には必見の記事です。
遡ること約 1 年前、タイミング制約の研修を受け、タイミング制約の概念については知ることが出来ました。
しかし実際に回路を設計し、タイミング制約をかけるとなると何から手をつけていいか分からない。
この制約で正しいのか?などの疑問が生じ、タイミングアレルギーになっていました。
このタイミングアレルギーにかかっていた私に処方箋を出してくれたのはやはり先輩でした。
今回はタイミングの苦手意識を解消してくれた先輩からのアドバイス(制約の手順)についてご説明いたします。
まずはそのタイミング制約、解析のフローの確認です(図 1 )。
図 1. タイミング制約、解析のフロー
この中で最初の難関である SDC ファイルの作成について手順を説明します。
SDC の制約は回路内の全てのパスに対してかける必要があります。
全てのパスに制約をかけるのは難しそうに感じますが、制約をかける順番が決まっており、その順番に従って制約を行う事で難しくなくなります!
図 2 にその順番をまとめました。
図 2. SDCファイルの記述順
図 2 から制約に最低限必要なコマンドは大きく分けて 2 種類しかないことが分かります。
タイミング制約のコマンドについてはこちらにも記事がありますので、ご参照ください。
I/O の制約はクロックの周波数を基準に行うので、まずはクロックの制約を行います。
それでは早速回路例に対して制約をかけていきます。図 3 のような回路を想定して制約をかけます。
図 3. 回路図例
counter : U1 が 1 の位、counter : U10 が 10 の位のカウントアップ、ダウンを行います。
また MS は counter をカウントアップさせるかカウントダウンさせるかを選ぶための外部からの信号です。
今回の回路において「クロックの制約」をかけるパスは「入力クロック : CLK 」と「 PLL の出力クロック」の 2 つです。
まずは入力クロックの制約から行います。
こちらは create_clocks コマンドを用います。
SDC ファイルがない場合には新規作成します。
File → New → Synopsys Design Constraints File をクリックすることで SDC ファイルを新規作成することが出来ます。
今回は 50MHz のクロックを使用するので周波数が 50MHz のクロックを定義します。
GUI を用いることで簡単にコマンドを生成することができます。
SDC ファイルのコマンド入力したい箇所で右クリック → Insert Constraint → Create Clocks をクリックすることで GUI が出現します。(図 4 、図 5 )
図 4. SDC制約コマンド生成の GUI の出し方
図 5. GUI 使用画面
Clock name : 制約を与えるクロックの名前
デザイン上のクロック名と一致させる必要はないです。
※ここで指定するクロック名は SDC ファイル内でのみ有効(今回は分かりやすくデザインと同じ CLK にしています)
Period : クロックの周期の設定
50MHz のクロックなので、周期に 20ns を入力します。
Targets : 制約を与えるポートやピンを制定する
最後にターゲットを選択しますが、get_port というものを使用します。
これを使用してデザインの中からポート名を捜索させることができ、get_port {CLK} として CLK という名前のポートに create_clock という制約を適用します。
与えたい制約を設定し、最後に Insert をクリックするとコマンドが SDC ファイルに挿入されます。(図 6 )
図 6. コマンド挿入後の SDC
続いて PLL の出力クロックの制約を行います。
こちらは derive_pll_clocks コマンドを入力します。
このコマンドを入力することで PLL の出力クロックの制約が完了します。
これでクロックの制約が完成し、図 7 のようになります。
図 7. クロックの制約
以上の制約を行う事で回路例(図 8 )の赤線の部分に制約をかけたことになります。
図 8 . 制約をかけた後の回路図
クロックの制約をかけるとそのクロックによって駆動される回路領域(クロック・ドメイン)のパスに対して制約をかけたことになります。
私は全てのパス 1 本 1 本に制約をかけなければならないと思っていたので、これを知った時に自分の中のタイミング制約に対する壁が低くなりました。(イメージが図 9 です)
図 9 . クロックの制約がかかるパスのイメージ図
この調子で I/O 部分とフォルス・パスについてもタイミング制約のコマンドを入力し、制約をかけていくことで苦手意識を持っていた頃に比べてスムーズに制約をかけることができたように感じました。
I/O の制約についてはこちらの記事をご覧ください !
おまけ
今回 PLL の出力クロックの定義を derive_pll_clocks コマンドで行いましたが、
PLL 出力クロックが複数ある場合 1 つずつ制約を与えるコマンドがあります。
それはcreate_generated_clock コマンドです。
図 10 を例にcreate_generated_clock コマンドと derive_pll_clocks コマンドをそれぞれ使って同じ制約をかけました。
derive_pll_clocks コマンドの方が簡単に記述できますね !
create_generated_clock コマンドは出力クロック 1 つ 1 つに制約をかけることが出来るので、クロックのシフト量などを変更してタイミング検証したい場合などに有効になります。
( derive_pll_clocks だとデザインの修正からやり直しが必要になってしまう)