FPGA を対象とした非同期式回路の設計 (4)

皆さん、こんにちは。前回までに、非同期式回路の合成について説明をしました。今回は、タイミング検証や遅延調整など残りの部分について説明したいと思います。前回を読んでいない方は、まずはそちらをご覧ください。

タイミング制約

設計フローの続きを解説する前に、タイミング制約を説明します。今回使用したモデルでは、セットアップ制約、ホールド制約、およびパルス幅制約の3種類のタイミング制約を満足する必要があります。

注意:今回の回路モデルは、直線的な処理をしているため、これらの制約を見るだけで十分ですが、分岐や繰り返しが入った場合は、それらが正しく動作するために新たな制約が必要となります。

セットアップ制約

レジスタにデータを書き込むより一定時間 (この時間をセットアップ時間と呼ぶ) 前に、そのデータは安定していなければいけないという制約です。この制約を図1で見ていきます。ソースレジスタに書き込みを行う lclk 信号からソースレジスタを通り、ディスティネーションレジスタの入力データピンまでのパスを sdp とします (図1では赤色のパス)。また、ソースレジスタに書き込みを行う lclk 信号から次の self-timed モジュールを通り、ディスティネーションレジスタのクロックピンまでのパスを scp とします (図1では青色のパス)。

図1 セットアップ制約のデータパスsdpと制御パスscp

sdp の最大遅延を max (sdp)scp の最小遅延を min (scp)、セットアップ時間を tsu とすると、セットアップ制約は以下の不等式で表すことができます。

min (scp) > max (sdp) + tsu

この不等式を違反する場合、遅延素子 sdNOTLCELL を追加することで、不等式を満足するようにします。なお、とはいえ min (scp) の値が大きすぎると性能が悪くなりますので、理想的にはギリギリのところで満足するのが望ましいです。この場合、sd から NOTLCELL を削除していきます。

ホールド制約

レジスタにデータを書き込み始めてから一定の時間 (この時間をホールド時間と呼ぶ)、レジスタの入力データは変化してはいけないという制約です。こちらは、セットアップ時間の時とは異なり、start 信号のところまで遡ってみていきます。この非同期式回路の場合、次のデータは、start の逆の遷移 (現在が立ち上がり遷移の場合、次は立ち下がり遷移) と共に入力されます (二相式と呼ぶ。詳しくは一回目を参照)。start が立ち上がったときのパス遅延と立ち下がったときのパス遅延が同じでないため、このように考えています。

ホールド制約を図2で見ていきます。start から、ディスティネーションレジスタに対する lclk を生成する self-timed モジュールを通り、ディスティネーションレジスタのクロックピンまでのパスを hcp とします (図2では赤色のパス)。また、start からソースレジスタに対する lclk を生成する self-timed モジュールとソースレジスタを通り、ディスティネーションレジスタの入力データピンまでのパスを hdp とします (図2では青色のパス)。

図2 ホールド制約の制御パスhcpとデータパスhdp

次のデータを入力するまでの時間をサイクルタイム (後述) cthcp の最大遅延を max (hcp)hdp の最小遅延を min (hdp)、ホールド時間を th とすると、ホールド制約は以下の不等式で表すことができます。

ct + min (hdp) > max (hcp) + th

この不等式を違反する場合、ct を増やすかソースレジスタに対する遅延素子 wdLCELLNOT を追加することで、不等式を満足するようにします。もちろん、セットアップ制約同様 min (hdp) の値が大きすぎると性能が悪くなりますので、ギリギリのところで満足するのが望ましいです。

注意:今回の回路は、start 信号が遷移する度に次のデータが入力されることを想定しています。仮に、startn回遷移する度に次のデータを入力する場合、ct の部分は n*ct とします。

パルス幅制約

lclk が1である時間は、ある一定の時間 (パルス幅と呼ぶ) より長くなければいけないという制約です。図3のように、self-timed モジュールの lclk から DFF を通り、lclk までのパスを pp とします (図3の赤線)。

図3 パルス幅制約のパスpp

pp の最小遅延を min (pp)、パルス幅を tpulseとすると、パルス幅制約は、以下の不等式で表すことができます。

min (pp) > tpulse

この不等式を違反する場合、pdNOTLCELL を追加することで、不等式を満足するようにします。min (pp) の値が大きすぎる場合は pd から NOTLCELL を削除することで調整します。

サイクルタイム

サイクルタイムは、非同期式回路の性能指標の1つです。ここでは、ローカルサイクルとグローバルサイクルタイムを説明します。

ローカルサイクルタイム lct は、パイプラインステージ毎に定義します。lct を図4を用いて説明します。図1同様、ソースレジスタに対する lclk からディスティネーションレジスタのクロックピンまでのパスを scp とします (図4の青色のパス)。また、ソースレジスタに対する lclk からソースレジスタのクロックピンまでのパスを lsp とします (図4の赤色のパス)。

図4 lctに関連したパスscpとlcp

scp に対する最大遅延を max (scp)lsp に対する最大遅延を max (lcp) とすると、あるデータパスに対するローカルサイクルタイムは、max (scp) – max (lcp) となります。パイプラインステージの中に、n 本のデータパスがある場合、lct は以下の式で求めることができます。

lct = max (max (scp0) – max (lcp0), …, max (scpn-1) – max (lcpn-1))

グローバルサイクルタイム ctは、各パイプラインステージの lct の中の最大のものとなります。パイプラインステージが m ステージあるとすると、ct は以下の式で求めることができます。

ct = max (lct0, …, lctm-1)

次のデータを入力するときは少なからず ct 時間分待ってから入れる必要があります。つまり、ct は入力データに対するインターバルを表します。なお、ホールド制約の不等式の ct はこの値です。

設計フローの続き

図5は、前回示した設計フローです。パス遅延解析コマンドの生成からタイミング制約の満足まで (違反がいいえまで) 確認していきます。機能検証のところは、次回の評価の際に説明したいと思います。

図5 設計フロー

パス遅延解析コマンドの生成

図1から図4まで示したタイミング制約、及びサイクルタイムの評価のために、パス遅延解析コマンドが必要です。パス遅延解析コマンドは、Quartus Prime に含まれる Timing Analyzer で静的タイミング解析を行うために用います。方針としては、回路上の全てのパスに対してコマンドを生成します。データパスに関しては、ソースレジスタからディスティネーションレジスタまでのパス毎にコマンドを生成します。一方、制御パスに関しては、図6のように制御パスを分けてコマンドを生成します。前の self-timed モジュールの nreq の出力から今の self-timed モジュールの XOR の出力まで (図6の①)、XOR の出力から nreq の出力まで (図6の②)、nreq の出力から nreq の入力まで (図6の③)、及び nreq の出力から XOR の出力まで (図6の④) です。一般的に、Static Timing Analyzer は、パスの途中でフリップフロップが含まれてしまうと、そこで遅延解析が分断されるためこのようにしています。

図6 制御パスの分割

レジスタのセットアップ時間やホールド時間を拾いたい場合は、report_timing コマンドを用い、そうでない場合は report_path コマンドを用います。他に、始点、終点の信号遷移の向きが決まっている場合は、-rise_from-rise_to、および -fall_from-fall_to を指定します。図7、8、9はそれぞれ、セットアップ、ホールド、および制御回路に対するタイミング解析コマンドの一部を表します。形式は TCL です。今回はコマンドを3つのファイルに分けていますが、これは1つのファイルにまとめてしまうと、最初の読み込みのところで時間が掛かってしまうための措置です。

図7 セットアップ制約向けパス遅延解析コマンドの一部
図8 ホールド制約向けパス遅延解析コマンドの一部
図9 制御パス向けパス遅延解析コマンドの一部

2つ注意点があります。1つ目ですが、今回生成したコマンドでは、各パスとも1つしか遅延解析を行いません。複数の信号からなるパスの場合、report_timing であれば、スラック値 (要求されるパス遅延から実際のパス遅延を引いた値) が最小となるパスが、report_path であれば、遅延が最大、あるいは最小となるパスのみがレポートされます。これは、こうした値を持つパスだけに着目して遅延調整を行うためです。2つ目ですが、create_clockset_input_delay を設定しないと (今回はレジスタから出力ピンまでのパスを考えていないので set_output_delay がないが、ある場合は含める必要がある)、タイミング解析が正しく行われません。タイミング検証は、後述の通り解析した実際の遅延を用いて行うため、これらは適当な値でも構いません。まずは設定するようにしてください。

以下は、タイミング解析コマンドを含んだTCLファイルです。

静的タイミング解析

Quartus Prime で静的タイミング解析を行う方法は、GUI で操作する方法と Consol から操作する方法があります。今回は、GUI で行う方法を説明します。Quartus Prime のメニューにある Tools の中から、Timing Analyzer を選ぶと、図10のような Window が出てきます。初めに、左側にある Tasks のなかで、Reset Design を実行します。次に、メニューにある Script の中から Run TCL Script を選び、タイミング解析コマンドが含まれた TCL ファイルを選べば、ツールが解析を行ってくれます。

図10 Timing Analyzerの画面

TCL ファイルでは、静的タイミング解析を行うと、各コマンドに対して、1つのレポートファイル (テキストファイル) を出力するようにしています。今回は、TimingReport というディレクトリを作り、その中にレポートファイルを生成するようにしています。

タイミング検証

非同期式回路を設計するに当たって、最も手間がかかるのはタイミング検証と遅延調整の部分です。そのため私たちは、この辺りをツール化しているのですが、現在コードの修正を行っているため、大変申し訳ないのですが提供することができません。そのため今回は、方針を中心に説明させていただきます。

タイミング検証ですが、Timing Analyzer の方で、スラック値を計算して違反があった、満足したというレポートを出してくれますが、それをそのまま使うことはしません。この非同期式回路において lclk 信号は、LCELLNOT を使って生成しています。そのため、create_clock で与えたサイクルタイムと遅延素子の実際の遅延値には差が出てしまいます。特に、遅延素子の min/max の差はそれなりにあります。そのため、パス遅延解析コマンドが生成した値を加工して、タイミング制約の不等式に代入し、検証を行います。

図11 (図1の再掲) を例に説明します。この例では、sdpctrl0XOR の出力から、x を通り add0_reg に至るパスです。scpctrl0XOR の出力から、ctrl1 を通り add0_reg に至るパスです。

図11 セットアップ制約の例

セットアップ制約の不等式は、min (scp) > max (sdp) + tsu です。この不等式の各値を見ていきます。max (sdp)tsu ですが、図12のパス遅延解析コマンドから得たレポートファイル (図13) より得ることができます。

図12 図11で表されたsdpのパス遅延解析コマンド
図13 sdpのSTAレポート

max (sdp) は、ctrl0XOR の出力から x までの最大遅延と x から add0_reg までの最大遅延の和です。これらは、図13の Data Arrival Path のうち、clock network delaydata path に該当します。従って、6.512ns です。また、tsu は、最後の uTsu に該当します。以上より、6.53ns となります。次に、min (scp) ですが、図14のパス遅延解析より得たレポートファイル (図15) と図13より求めます。

図14 図11で表されたscpのパス遅延解析コマンド
図15 scpのSTAレポート

min (scp) は、ctrl0XOR の出力から nreq までの最小遅延、nreq から ctrl1XOR の出力までの最小遅延、および ctrl1XOR の出力から add0_reg までの最小遅延の和です。これらは、図13の Data Arrival Path のうち、clock network delaydata path に該当します。最初の2つは、図15の data path に該当します。一方、最後の値は、図13の Data Required Pathclock network delay に該当します。これらの和は 13.753ns です。不等式の右辺が 6.53ns でしたが、これより大きな値です。従って、このセットアップ制約は満足しているということが言えます。

他のパス、およびホールド制約やパルス幅制約も同様な考え方でタイミング検証を行います。

最初の遅延調整と再合成

最初の遅延調整

タイミング検証が終わったら、違反があったパスに対して、遅延調整を行っていきます。調整の方法 (順番など) は色々とありますが、今回はできるだけ手間が少ないやり方を用いたいと思います。

最初の調整では、ホールド制約に対する調整は行わず、セットアップ制約とパルス幅制約に対してのみ行うこととします。図16 (図2の再掲) をみると、ホールド制約に関するパスは start まで遡っています。遅延が累積されるため、後のステージに行けば行くほど、min-max の差が広がり、違反の可能性が増えてしまいます。また、最初の合成前に生成した遅延素子の NOTLCELL の数は概算値を用いて計算しているため (第3回を参照 https://www.acri.c.titech.ac.jp/wordpress/archives/10436)、実際の遅延と乖離している可能性があります。こうしたことより、1回目は遅延素子 sdpd を調整し、sdpdNOTLCELL を適切な数に近づけつつ、ホールド違反を抑えるということにします。

図16 ホールド制約に関するパス(図2の再掲)

表1と表2は、セットアップ制約に関する scpsdp の遅延 (max (sdp)tsu も含んでいる) とその差、およびパルス幅制約に関する pp の遅延と tpulse とその差を表します。

表1 セットアップ制約に関するscpとsdpの遅延とその差

表2 パルス幅制約に関するppの遅延とtpulse、およびその差

差が負のところは (この表1と2にはない)、該当する遅延素子の LCELLNOT を増やし、差が正のところは、LCELLNOT を減らします。各パイプラインステージに負となる制約がある場合、その中の最小値 mindiff を基準とします。LCELLNOT の1つ当たりの遅延を 0.35ns とすると、追加する数は、以下の式で求めます。

addcell = ceil (|mindiff|/0.35)

ceil では、|mindiff|/0.35 の値が小数点の場合、繰り上げます。一方、各パイプラインステージの全てのセットアップ制約が正の場合、その中の最小値 mindiff に対して、scp に対するマージン margin を考慮し、削除する数を決めます。LCELLNOT の1つ当たりの遅延を同じ値 (0.35ns) と考えると、削除する数は、以下の式で求めます。

removecell = floor ((mindiff-margin)/0.35)

floor では、(mindiff-margin)/0.35 の値が小数点の場合、切り捨てます。今回 margin は、LCELL 2個分ということで0.7とします。margin の決め方は注意が必要です。大きな値にすると削除する LCELLNOT の数は減り、かつ遅延調整回数も抑えることができますが、性能が悪くなります。一方、小さな値にすると削除する LCELLNOT の数は増え、性能も良くなりますが、遅延調整回数が増える可能性があります (ぎりぎりで決めてしまうと、再合成後の実際の遅延で、違反となる可能性がある)。例えば、表1の ctrl1 を例にとると、mindiff3.159ns です。そのため、removecell = floor ((3.159-0.7)/0.35) = 7 となります。そのため、sd1 の出力側から LCELLNOT7個削除します (注意:この例では、前回説明した通り、セルの個数が偶数の場合最後は NOT、奇数の場合最後は LCELL とする)。

表3は、1回目の調整前後の遅延素子を構成する NOTLCELL の数を表します。調整が終わったら、これらの数に合うように、sdpd に対する Verilog ファイルを修正します。

表3 遅延素子を構成するNOTとLCELLの数

以下は、修正した遅延素子に対するVerilogファイルです。

再合成

再合成の前に、修正した遅延素子に対する Verilog ファイルを Quartus プロジェクトに反映させます。また、Design Partition (第3回を参照 https://www.acri.c.titech.ac.jp/wordpress/archives/10436) で遅延素子以外の配置配線を固定化するために POST_FIT とします。図17は Design PartitionPOST_FIT にするための TCL ファイルです。

図17 Design partitionの遅延素子以外をPOST_FITに変更したTCLファイルの一部

Quartus PrimeのメニューにあるToolsからTCL Scriptsを選び、以下のDesign PartitionのTCLファイルを実行します。実行すると、遅延素子以外のリソースがPOST_FITになります。

この他に設定した制約 (assignment とも呼ぶ) をバックアノテーションします。Quartus Prime のメニューより Assignments を選び、出てきたリストで Back- Annotate Assignments を選びます。図18の画面がでたら、Back annotation typeAdvanced にして、OK をクリックします。

図18 Back-Annotate Assignments

これで再合成の準備が整いましたので、Quartus Prime にある Compilationボタンをクリックし、再合成を行います。

2回目以降の遅延調整と再合成

ここから先は、タイミング制約が全て満足されるまで、遅延調整と再合成を繰り返します。

表4と5は、再合成後のタイミング解析の結果を表します。最初の行にある0は、前回のタイミング解析の結果、1は今回のタイミング解析の結果です。再合成の結果、遅延が多少変化したため (遅延素子のセル数を調整にて増減させているため、配置配線を固定していない)、遅延素子がマージン以上のところ (例えば ctrl1mindiff0.752で、margin である0.7よりわずかに大きい) や違反が生じたところがあります (パルス幅制約の ctrl2)。

表4 セットアップ制約に関するscpとsdpの遅延とその差

表5 パルス幅制約に関するppの遅延とtpulse、およびその差

そのため、表6のように、遅延素子 sdpd を調整し、再合成を行います。最初の行の0と1は、前回の調整と今回の調整を表します。

表6 遅延素子を構成するNOTとLCELLの数

以下は、調整後の遅延素子に対するVerilogファイルです。

遅延調整後のVerilogファイルをQuartus Primeのプロジェクトに反映します。再合成 (3回目の合成) の結果、セットアップ制約とパルス幅制約は満足するようになりました。一方、ホールド制約違反が3つ存在しています。今回の例では、遅延素子 wd を調整するのではなく、ct を調整することで対応します。3回目の合成結果より、ct は、10.3ns になりました。ct にホールド違反分の遅延 0.5ns を足せば、全てのホールド違反が無くなります。ct を増やすということは、ホールド制約の不等式の左辺の値を増やすことになり、不等式を満足しやすくします (その分、性能を犠牲にしています)。ct の変更によって全てのタイミング制約を満足したので、これで終了です。

今回はここまでです。これまで中で1番長かったので、最後まで読んでいただきありがとうございます。

次回は

次回は、合成した回路の機能検証と評価を説明したいと思います。

会津大学 齋藤 寛

タイトルとURLをコピーしました