電気回路/FPGA入門

(67d) 更新


公開メモ

論理回路初心者に FPGA を教えるとしたら

興味を持つ学生に、 どういう順番で説明するのが良いか、考えてみました。

後でちゃんとした文章にするかもしれませんが、とりあえずは個人的なメモになります。

目次

1. デジタル信号

  • true or false の2値とするのが基本? 1 or 0 で表すこともある。
  • 負論理なんかもあるけれど、説明するのは実際に使うときで良い気がする。

2. (理想的な)組み合わせ論理回路

論理回路は、「組み合わせ論理回路」と「クロック同期回路」とに分類できる。

まずは(理想的な)組み合わせ論理回路について:

  • 一般にはデジタル入力線とデジタル出力線とを複数持つ
  • 入力が決まると出力が決まる (入力が同じなら同じ出力を出す)
    • 簡単な例としては NOT や AND、OR など
    • 少し複雑になると 全加算器 とか
    • 入力に依らず 1 や 0 を出す定数とかもあっていい
  • そういうのを組み合わせたもっとずっと複雑なものでもいい
    • 多数の全加算器その他を組み合わせて整数の四則演算とか
    • 比較器とセレクタなんかを組み合わせて3項演算子や if 文みたいのとか

3. デジタル信号の実際

  • 実際の回路においては 1 or 0 は導線に掛かる電圧に対応する。例えば 3.3V なら 1、0V なら 0 とか。
  • 例えば、組み合わせ論理回路の入力線に印加する電圧を決めると、出力される電圧が決まる
  • でも、入力を変えてから出力が決まるまでには時間がかかる → 伝達遅延
  • 遅延は、回路に含まれる複数の素子を通る際の遅延と、それらの素子の間の配線を通るための遅延と、の和になる。
  • だから1つの回路の中でも、複数あるうちの1つの入力線から1つの出力線への伝達遅延は、別の入力線から別の出力線への伝達遅延と値が異なるのが普通
  • 一斉に入力を決めても、出力が決まる時間は出力線によってバラバラになる
  • では、いつ出力を読めば良いのか?
    → もっとも長い伝達遅延を持つ出力が変化するまで待ってから読む
    → それまでは入力を変えずにじっと待たなくてはいけない

4. クロック同期回路

クロック同期回路の基本

  • 最も単純なのは組み合わせ論理回路の入力と出力とにそれぞれ1つずつ Dフリップフロップ回路 を繋ぎ、サンドイッチのように挟んだ形
  • Dフリップフロップ回路 は一種の「記憶素子」で、データ入力線とクロック入力線、データ出力線を持つ。
    • クロックの立ち上がりの時点でデータ入力線の値を読み記憶する
    • データ出力線へは記憶したデータを出し続ける
    • つまり、Dフリップフロップはクロックの立ち上がりの瞬間以外で値を変えない
  • Dフリップフロップに挟まれた組み合わせ論理回路の伝達遅延がクロック周期よりも小さければ、 このクロック同期回路はクロック立ち上がりで入力を読み、次のクロック立ち上がりで、 それに応じた出力を出すことになる
  • クロックごとに入力の値を変えることで、1クロックごとに計算結果が得られることになる

クロック同期回路の連結

  • 組み合わせ論理回路の伝達遅延がクロック周期よりも長かったらどうするか
  • 組み合わせ回路を前半と後半に分け、その間にもう1つDフリップフロップを入れる
  • 前半部分、後半部分の伝達遅延がそれぞれクロック周期よりも短ければ、2クロック後に正しい出力が得られる
  • Dフリップフロップを入れることで、各部への入力が必ずクロック周期だけ変化せずに保たれるので、 全体の入力から全体の出力までの遅延を見積もりやすくなる
  • Dフリップフロップの挿入により伝達遅延自体はむしろ長くなるが、1クロックごとに異なる値に対する計算を行えるという意味では先ほどと変わらないから、クロック同期にする前と比べるとスループットが向上したことになる

クロック同期回路に挿入する組み合わせ論理回路の時間余裕

  • 単純には組み合わせ論理回路の伝達遅延がクロック周期よりも短ければいいのであるが、 細かい話をし出すともう少しいろいろ考えなければならない
  • Dフリップフロップはクロックエッジで入力信号を取り込むが、エッジの直前や直後に入力が変化してしまうと、値が正しく読み取れないばかりか出力が振動してしまうようなことが起きる
    電気回路/HDL/非同期信号を扱うための危ういVerilogライブラリ
  • そこで、エッジの直前・直後にはDフリップフロップへの入力が変化してはならない時間領域として、 セットアップ時間(直前)、ホールド時間(直後)が定められる
  • そこまで考慮すると、伝達遅延は(クロック周期 - セットアップ時間)よりも短くなければいけないことになる
  • さらに、クロック同期回路では入力側と出力側のDフリップフロップに同じクロック信号を入力するのだが、 実際にはこの間にも伝達遅延がありうる。この遅延は、どちらがどのくらい早い、と考えるのではなくて、 最大でどれだけの差が生じうるか、を表すクロックスキューという値で評価される
  • そこまで考慮すると、伝達遅延は(クロック周期 - セットアップ時間 - クロックスキュー)よりも短くなければいけないことになる

クロック非同期部分との接続

  • 同じクロックを共有するクロック同期回路の設計は、慣れてしまえば比較的簡単なのだけれど、 クロック同期回路を、外部のクロック非同期回路と接続したり、 クロック同期ではあっても異なるクロックに同期している部分と接続する場合には、 特別な配慮が必要になる
    電気回路/HDL/非同期信号を扱うための危ういVerilogライブラリ

5. Verilog / VHDL などのハードウェア記述言語

  • 回路を記述するためのプログラム言語のようなもの
  • 回路は各部分が同時に動作するので、並列実行を強力にサポートする仕様になっている
  • 言語自体は通常のプログラム言語と同様に、非常に自由度の高い記述ができる
  • 自由すぎるので、あまりに自由に書いたコードは回路に翻訳ができなくなる
  • 回路に翻訳可能なようにコードを書くには、そして、できあがった回路の性能(伝達遅延やスループット)を高いものとするには、組み合わせ論理回路やクロック同期回路をどのようにコードで表すかをちゃんと理解していなければならない
  • ハードウェア記述言語では、コードの一言一句が「実在の回路」に翻訳されるので、ソフト開発とは違って、気軽に「サブルーチンを呼び出す」などというようなことはできない。
  • コード中に記述された回数ときっちり同じ数の「実在の回路」が生成されるのである。
  • このあたり、初学者にはソフト開発と回路設計との違いを理解できないままになっている人も多いので、注意が必要
  • 私自身、このあたりの感覚を得るまでにはかなり時間がかかった
  • 個人的には HDL による VLSI 設計 - VerilogHDL と VHDL による CPU 設計 の後半部、CPU をどう HDL で記述するかを読んでようやく理解できた ー CPU の基本動作も分かるので、お勧めな本の1つだ
  • Verilog や VHDL の最新の規格には対応していないこともあるので、どのレベルの記述までが許されるかについては回路合成ソフトのマニュアルをちゃんと調べる

6. 回路合成ソフトの使い方

  • Verilog や VHDL で書かれたコードから、実際に FPGA なりに焼き込める回路を合成してくれるソフトのこと
  • Verilog や VHDL で同じように書いても、どのように回路を作り、どのように配置して、どのように配線するかによって、回路の伝達遅延は大きく異なるものになる
  • 回路合成ソフトは目的とする回路構成(どういう型番の FPGA に焼き込むのか、入力・出力は物理的にはどのピンに割り当てるのか)を指定すれば、合成結果の回路に対して正確に伝達遅延を評価できるようになっている
  • そればかりでなく、クロックを何MHzで駆動するかを指示してやれば、その時間制約を満たすよう回路を合成 ・配置してくれる(あるいは、頑張ってはみたものの、このコードで指定の駆動周波数を達成するのは無理でしたなどと報告してくれる)
  • 実際に回路を動作させるには、Verilog や VHDL で回路の動作をコード化するだけでなく、回路合成ソフトが必要とする情報を漏れなく与え、最終的に得られる回路が目的の動作周波数、入出力規約で正しく動作することをソフトに保証してもらう方法を知らなければならない
  • これがまた、Verilog / VHDL を学ぶのと同じくらい大変だったりする
    電気回路/HDL/VivadoのXDC制約文法

7. テストベンチ

  • 設計した回路が思った通りの動作をするかどうか、実機へ書き込まないとテストできないのだとなかなか大変 (始めから思った通りに動くことなんて滅多にないし)
  • そこで、回路を「シミュレータソフト」上で動かし、適当な入力を入れて、出力が正しく変わるかを調べることが行われる
  • そういうテスト環境のことをテストベンチと呼ぶ
  • テストベンチ上の回路へテスト入力を与えたり、出力が正しいかどうかを検証するためのコードも多くの場合Verilog や VHDL で書かれる
  • 入力信号を作ったり、出力を検証する部分のコードは回路として合成できなければならないという制約がないため、Verilog や VHDL が本来持つすべての機能を使って書いて構わない ー うまくテストベンチを作れば、近年ソフトウェア開発でもてはやされているテスト駆動型の開発も行えるはず
  • Verilog や VHDL の最新の規格には対応していないこともあるので、どのレベルの記述までが許されるかについてはシミュレータのマニュアルをちゃんと調べる

8. FPGA 内蔵 CPU、FPGA 内バス規格、OS

  • FPGA チップによっては始めから中に CPU を含んでいて、FPGA の内部メモリあるいは外部に繋いだメモリ上のソフトウェアを実行できるものがある
  • あるいは、そのような CPU があらかじめ実装されていない FPGA に、CPU として動作する論理回路を Verilog / VHDL で記述して、CPU を作り込むこともできる
  • この場合、なにも自分で1から書かなくても、Xilinx や Altera (Intel)、あるいはサードバーティーが提供する CPU ライブラリを組み込んで使っても良い
  • 自作ではなく既成品の CPU を用いる利点は、CPU 自体を作らずに済むというだけではなくて、そのような CPU にはソフト開発用のアセンブラやコンパイラ等が一緒に提供されるというところにもある
  • FPGA 内 CPU のうち規模の小さいものではマイコンと同様に IOポート が直接外部へ信号線として 出ているものもあり、そのような場合には FPGA 内部に作成した自作回路の入力と、 CPU からの出力を直接繋ぐことで自作回路をソフトウェアから制御可能になる
  • 一方、ARM や MicroBlaze のような大きな CPU では、より多くの周辺機器 (FPGA 内部に実装されるモジュールを含む)を CPU の動作クロックを落とすことなく 接続できるように、IO ポートが直接信号線として出ているのではなく、 CPU からは AXI4 のような汎用のバスラインが(複数)出ており、 自作回路はこのバスラインへぶら下げる形で接続することになる
  • この場合、自作回路を例えば AXI バスに接続するための知識が別途必要になる
    電気回路/HDL/VivadoでAXIバスを利用

ソフトの動作環境:

  • 内部に 2コアの高性能 ARM を内蔵した Xilinx の Zynq などでは、 内蔵 CPU で Linux を走らせたりもできる
  • この場合、Linux を起動可能な Rom データの作成方法や、 Linux 上のソフトから FPGA 内に実装したハードウェアへどのようにアクセスすべきか、 などの知識が別途必要になる
    電気回路/zynq
  • Linux のかわりにリアルタイム OS (割り込みに対する動作遅延が最小化されている) を用いる場合もある
  • そのような特定の OS を利用しない場合のことをベアメタルのソフトウェア開発と言ったりする

FPGA 外部信号

  • FPGA の入出力ピンには、電圧レベル、差動かシングルエンドか、最大電流、インピーダンス、遅延量 などの物理的な規格を設定可能
  • 通信方法としては UART, SPI, I2C などいろいろな規格がある

内蔵 PLL

  • FPGA には PLL が複数内蔵されている
  • 源となるクロックから、周波数変換して異なる周波数のクロックを作れる(整数倍、整数分の一、それらの組み合わせ)

動作周波数

  • 例えば Xilinx の Artix 以上の FPGA だったら、 あまりに複雑な計算でない限り、100 MHz くらいのクロック同期回路を作るのは難しくない
  • 200 MHz も狙えるけど、Artix で 400 MHz はキビシイとか、そんな感じ。

コメント・質問





Counter: 688 (from 2010/06/03), today: 2, yesterday: 0