皆さんこんにちは。今回は、設計の対象となる回路モデルを紹介していきたいと思います。今回は、前回紹介したFPGA を対象とした非同期式回路の設計 (1)で取り上げた制御回路モデルを用いますので、まだ読んでない方はそちらを先に読んでいただければと思います。
対象モデル (同期式回路)
最終的に設計した後、どのくらいの性能になるのかを確認するために、今回は同期式回路の設計から始めていきます。図1は、対象となる回路モデルです。算術演算を5段パイプラインで実現しています。
青色のレジスタは、clock 信号、reset 信号、及び enable 信号を持ったものを想定しています。制御は、タイミングを取るだけですが、start 信号が1の時にデータが投入され、comp 信号が1の時に処理が完了したことを表します。次のデータが投入されるタイミングを表す入力データインターバルは、1サイクルです。
同期式回路の Verilog モデル
図2は、同期式回路の Verilog Hardware Description Language (HDL) モデルです (トップレベル階層の一部)。今回は、階層化した記述を用いてます。
階層化している理由ですが、1. 非同期式回路の設計でリソースレベルで設計制約を与えたいものがある (詳しくは次回説明する予定です)、2. 同期式回路と非同期式回路とで Verilog の違いを少なくしたいためです(非同期式回路の配置制約を想定したモデリングに合わせた)。比較の上ではフェアとは言い切れないでしょうし、階層化の方法も様々あるのですが、ご理解いただければと思います。
以下は、同期式回路の Verilog HDL です。展開すると src と sim が現れますが、src にソースコードが、sim にテストベンチがあります。
非同期式回路モデル
図3は、self-timed モジュールを利用した非同期式回路モデルを表します。パイプラインステージ毎に1つの self-timed モジュールを割り当てています (この self-timed モジュールは、Finite State Machine であれば各状態に、パイプラインであれば各ステージに割り当てることで制御回路を実現することを想定しています)。
stage、ctrl、sd、pd、および wd はそれぞれ、パイプラインステージ、self-timed モジュール、3つの遅延素子を表します。sd はセットアップ制約のための遅延素子、pd はパルス幅制約のための遅延素子、wd はホールド制約のための遅延素子です。また、lclk はローカルなクロック信号を表します。lclk で制御とデータパスのレジスタにデータを書き込みます。
非同期式回路の Verilog モデル
図4 (a) は非同期式回路の Verilog HDL モデルの一部を表します。ここでは、stage 毎にリソースをまとめて、モジュールとしています。(b) はstage0 の Verilog HDL モデルを表します。(c) は self-timed モジュールを表し、(d) は遅延素子 sd と pd のシミュレーションモデル、(e) は sd の合成モデルを表します。なお、wd は最初は assign out = in; としたダミーモジュールとして準備しており、調整が必要になったときに部品を追加します。(c)と(e)にsynthesis keepというディレクティブが入っていますが、これはrenameしない、最適化を行わないようにといった意味があります。
遅延素子に対してシミュレーションモデルと合成モデルを準備した理由は、遅延素子をプリミティブで実現するためです。遅延素子は NOT と LCELL (バッファーと同じ扱い) というプリミティブで実現します。しかし、プリミティブを使う場合、Register Transfer Level (RTL) シミュレーションができません。そのため、シミュレーションモデルでは遅延を数値で表すことで RTL シミュレーションを実現します。
プリミティブセルによる遅延素子の実現
初期的に、遅延素子sd、pd、wdのうち、sdとpdをLCELLとNOTで実現します。ちなみに、sdはレジスタに対するデータの書き込みを保証する遅延素子で、束データ方式による非同期式回路の場合、データパス遅延の最悪値より大きな遅延にする必要があります。別な言い方をすれば、レジスタのセットアップ制約のために必要となる遅延素子です。pdは、ローカルクロック信号lclkのパルス幅を保証するために必要となる遅延素子です。また、self-timedモジュールの内部にあるDFFのホールド制約を保証します。以上の理由から、これら2つは最初から作っておきます。一方、wdはデータパスレジスタでホールド違反が生じたときに調整する遅延素子です。違反がない限り遅延は不要なため、ダミーモジュールのままとします。
今回は、sdとpdに含めるLCELLとNOTの個数を以下のようにして決めます。目標サイクルタイムctと、1LCELL当たりの遅延tlcellより、sdに必要となるプリミティブセルの個数numsdを決めます。
numsd = floor(ct/tlcell)
例えば、ctが9ns、tlcellが0.35nsの場合、numsdは25となります。なお、floor演算では、小数点が現れたときに切り捨てます。tlcellの厳密な値は分かりません。実際にLCELLをおいて合成し、Static Timing Analyerなどで図った値を用いると良いでしょう。numsdの個数が奇数の場合、1つ引いた個数までをNOTで実現し、最後をLCELLとします。偶数の場合、全てNOTで実現します。図4(e)は、この例の場合のsdのVerilog HDLモデルを表します。pdですが、ctの部分をパルス幅tpulseに置き換えるだけです。
今回のようなパイプライン回路の場合、初期的に全てのself-timedモジュールのプリミティブセル数は同一にしておきます。これは、パイプライン回路の場合、性能は最も遅いパイプラインステージに縛られるからです(同期式回路のクロックサイクルタイムの決め方と同じ)。後々、合成によって実際に論理遅延や配線遅延が含まれるようになった場合、タイミング検証後に調整を行います。
ところで、NOTを使用している理由ですが、この非同期式回路はstartの立ち上がり遷移と立ち下がり遷移の両方で動作する2相式プロトコルを採用しています。立ち上がり遷移の時と立ち上がり遷移の時とで遅延の差を抑えるためにNOTを積極的に使用しています。
以下は非同期式回路の Verilog HDL です。simの方はテストベンチとRTLシミュレーション用の遅延素子が含まれます。srcの方にはプリミティブを使った遅延素子が含まれます。
RTL シミュレーション
次に、RTL シミュレーションを行います。ここでは、Quartus Prime がインストールされていることを前提としていますので、Quartus Prime をインストールしていない方は、以下を参考にインストールしてください。
始めに、プロジェクトの作成を行います。ここでは、同期式回路のプロジェクトと非同期式回路のプロジェクトを分けて作成します。デバイスは使用するデバイスに合わせてください。ここでは Cyclone IV (EP4CE115F29C7) としています。図5は Quartus Prime を起動した後の画面です。
注意:今回 Cyclone IV を選んだことには理由があります。後々、ゲートレベルシミュレーションを行い、電力解析を行いたいのですが、ゲートレベルシミュレーションでは遅延がアノテートされた状態で行います。Quartus Prime では、遅延情報ファイルを生成したタイミングシミュレーションは Cyclone IV と Stratix IV までしかサポートしていません。そのため Cyclone IV を利用している次第です。Cyclone V や Stratix10 のような最近のデバイスで非同期式回路を設計し、評価するのは今後の研究の課題です。
非同期式回路のプロジェクトを exaとし、Project→Add/Remove Files in Projectから上記に置いた zip ファイル (asynchdl.zip) の src と sim にあるVerilogファイルを追加します。なお、このシミュレーションでは sim にあるシミュレーション用の遅延素子ファイル sd_sim.v と pd_sim.v を追加します。srcにある sd.vと pd.vは追加しないでください。テストベンチモジュールは、exa_tb.vというファイルです。
今回のシミュレーションでは、テストパターンをランダムに100個生成したものを用います。図6はファイルをプロジェクト exa に追加した後の画面です。左上にある Project Navigator は、プロジェクトに追加したファイルを表します。
次に、シミュレーションの設定を行います。Assignments→Settings よりシミュレータの設定をします。EDA Tool Settings の画面で、Simulation は ModelSim-Altera を選び、Format は Verilog HDL を選びます (図7)。
次に、EDA Tools Settings の Simulation より、シミュレーションの時間の単位やテストベンチモジュールの設定を図8のように行います。特に、Generate Value Change Dump (VCD) file script にチェックを入れ、Design instance name に設計の対象となる回路のインスタンス名を入れてください (この例ではuut)。これは、ゲートレベルシミュレーションの結果を使って電力解析をするためです。
テストベンチモジュールの設定は、Compile test bench で行います。図8は既に設定を終えていますが、右にある Test Benches… を押すと図9右の画面がでます。初めての場合、New を押して、テストベンチモジュール名などを指定していきます。New の場合も、図9左のような画面が出ますので、そこで設定していきます。ファイルの追加は、Test bench and simulation files で行います。最後にOKを押していき、シミュレーションのための設定を完了します。
最後に、Quartus Prime で Analysis & Synthesis を行います。Analysis & Synthesisを行えば、Tools→Run Simulation Tool→RTL Simulation より RTL シミュレーションができるようになります。同期式回路のプロジェクト ex もここまでの手順は一緒です。
ところで、ModelSim のところで、シミュレータが起動できないといったエラーメッセージが出た場合、テストベンチモジュールの構文エラーを含む、ここまでの設定で何かミスがあるかもしれません。あるいは、最初の場合、シミュレータの実行ファイルの設定が、Qaurtus Prime のインストールのところで完了していない可能性もあります。前者の場合、ミスがないかマニュアルを参考に確認する必要があります。後者の場合、Tools→Options を実行した後に出た画面で、General→EDA Tool Options の ModelSim-Altera のところで、ModelSim Intel Starter Edition の実行ファイルが指定されていない可能性がありますので、図10のように設定します。
図11は、同期式回路のRTLシミュレーションに対する波形を表します。
一方、図12は、非同期式回路のRTLシミュレーションに対する波形を表します。
出力信号が同じ値を出しているということで、機能的には問題ないということを確認することができました。1つだけ注意点があります。今回用いた self-timed モジュールは2相式で動きます。そのため、start が1の時も0の時も新しい入力データを投入しています。同期式回路の場合、clock が1の時に新しい入力データを投入しています。
今回はここまでです。
次回は
次回は、Quartus Prime を使った非同期式回路の合成の説明をしていきたいと思います。
会津大学 齋藤 寛