FPGAを用いた論理回路設計(その1)

FPGAとディジタル回路

近年、身の回りに急速に増えてきた、携帯電話、パソコン、 携帯オーディオ機器などのいわゆる情報機器の中では、 かなり多くの部分で、「ディジタル」な信号処理が行われています。 この「ディジタル」な信号処理は、「ディジタル回路」で行われる わけですが、それは、「論理回路」の講義でみなさんが習ったような、 いわゆる「論理回路」として実装されています。

論理回路は、インバータ、ANDゲートなどの論理ゲートを基本とし、 フリップフロップなどの記憶素子を組み合わせて設計します。 その設計手法としては、カルノー図による論理関数の簡略化、 順序回路の設計のための状態遷移図、など、多くの手法がありました。

それらの設計の結果を実際の回路として動作をさせるためには、 「回路図」を描き、「論理ゲート」が入っている部品(論理IC)を プリント基板の上に実装し、配線を行って回路を製作することになります。 しかしこの手法は、回路の「デバッグ」、つまり回路が期待した動作を しないときの間違い探しや、それに伴う回路の修正が大変面倒である、 という問題があります。 近年、情報機器がますます複雑化・高機能化してきて、この傾向は ますます顕著になりつつあります。

ところが近年、このような「古典的」な論理回路の設計手法とは別の、 全く新しいタイプの回路設計手法が現れ、ここ数年で急速に一般的に なってきました。 それは、「回路を自由にプログラムできる」論理素子、を 使うものです。 それは、インバータ、ANDゲート、フリップフロップのように、 機能が決まっている部品(論理IC)ではなく、あたかも白紙の設計図のように、 最初は機能が全く決まっていなくて、あとから「プログラムを書く」ように 機能を決められる論理ICです。 このタイプの論理ICを、総称してPLD (Programmable Logic Device)と 呼びます。 このPLDには、進化の歴史的経緯から、大きく分けて次の2つに 分類されます。

その両者の詳細については、別の講義(「集積回路設計及び演習」(4年前期)など)に ゆずりますが、この実験では、後者のFPGAと呼ばれる論理ICを用いて 実験を進めることにします。 この実験では、Altera社の CycloneIIという名称のFPGAを用い、このFPGAのほかに、 LEDやスイッチなどが載っているボードを用いることにします。

FPGAによるディジタル回路設計

FPGAを用いて論理回路を作るするためには、 FPGAに書き込む(プログラムする)論理回路を設計する必要があります。 この論理回路の設計のための方法は、大きく分けて次の2つがあります。 まずは、みなさんが慣れ親しんでいる「回路図」を用いる方法で、 早速実験を始めることにしましょう。
※論理回路などの復習のため、教科書・参考書などを持参するとよいでしょう

回路設計の開始

※プログラムの作成に先立って、まず実験用のフォルダを作成しておくと よいでしょう。 マイコンピュータ→Zドライブの中、または、「マイ ドキュメント」の中に、 実験第3用のフォルダを作成します。 今後の作業はすべてこの中で行うことにします。 なお、「Zドライブ」または「マイ ドキュメント」に置いたファイルはどの PCでも共有されます。

サンプルのファイル一式(sample_sch.zip)を ここから取得し、展開します。 すると sample.bdf, sample.qpf, sample.qsf の3つのファイルが 現れますので、それを作業用フォルダを作成してそこにコピーをします。 なお今後、いろいろな回路を作っていくことになりますが、その都度、 新しいフォルダを作り、この3つのファイルをコピーしてから 作業を開始します。 新しい回路を作り始めるとき、 回路図のファイル名を変更して保存するだけではいけません。 必ず、別のフォルダで作業を開始しましょう。

その後、sample.qpfをダブルクリックすると、Altera社の FPGA設計用(CAD: Computer Aided Design)ソフトウエアQuartusIIが 起動します。 (あるいはデスクトップ上のQuartusIIのアイコンをダブルクリックし、 メニューのFile → Open Projectで、sample.qpfを選択します)
※下図のsample.qpfのアイコンを選択すること。別のアイコンに注意。
sample.qpfのアイコン

回路図の入力

早速回路図を見てみましょう。 このサンプルでは、スイッチとLEDをインバータで接続しただけの 回路が入力されています。 QuartusIIの画面の左上の Project Navigator部に表示されている "sample"をダブルクリックすると、この回路図が表示されます。 (この回路図は、sample.bdfという名称のファイルとして保存されています)

この回路図中の左側は "SW[0]"という名称がついた端子があります。 これは、実際にはFPGAボード上のSW0と書いてあるスイッチに接続されている 端子(入力)です。 同様に右側の"LED[0]"という名称の端子は、FPGAボード上の LED0と書いてあるLEDに接続されている端子(出力)です。 つまりこの回路は、SW[0]の値(押すと0、離していると1; 普通と逆(負論理)なので注意)を反転して LED[0]に出力(1で点灯、0で消灯)する、という回路です。

ではこれにもう1つ回路を追加してみましょう。 回路図の左側に並んでいるツールボタンの中から、 "Symbol tool"(ANDゲートのマーク)を選びます。

すると入力するべき論理素子などを選択する画面が現れます。

この左側のLibrariesの中のツリー構造を 開いていくと、入力することができる回路要素が現れます。 まずはこの中から、primitives → logic と選び、その中の not(インバータ)を選択してOKを押しましょう。 するとインバータが回路図上に現れ、適当な場所でクリックすると 回路図上に配置されます。 同様に、入力端子(primitives → pin のinput)と 出力端子(primitives → pin のoutput)も配置しておきます。 そして入力端子、出力端子をそれぞれダブルクリックし、 Pin nameを、それぞれSW[1]、LED[1]に変更しておきます。

なお回路図中の配置済みの回路要素は、ドラッグして選択後、 コピー&ペーストも可能ですので活用すると便利でしょう。 まずは今回は、これで回路図入力を終わりにすることにします。

なお使用可能な回路要素は、これ以外にも論理ゲート、 フリップフロップや、論理IC(いわゆる74シリーズ)の機能ブロックなど 多数があります。 これらの名称と機能は、Help→Contentsの、「目次」の中の下のほうに あるPrimitivesの項にまとめられていますので、参考にしてください。 (英文ですが、要点だけであればそれほど苦労はしないはず)

ちなみに、いわゆる74シリーズの機能ブロックは、 回路要素を配置するときに、others → maxplus2の中から選べます。 74シリーズの型番と機能との対応は、 Google先生に聞くか、 Wikipediaを参考にするとよいでしょう。 例えば、4ビットの2進数(10進数で0〜9)を、7セグメントLEDの 点灯パターンに変換する機能を持つ論理IC(デコーダ)として、 7447というものがあります。

なお74シリーズの各論理ICの機能の詳細は、 それぞれのデータシート(仕様書)を読むことになります。 それらは、Web上(例えばTexas Instruments社のWebページ(英文)中の検索("Enter Part Number"))で 見つけられるでしょう。

コンパイル(インプリメンテーション)

入力した回路図を、FPGA上で実際に動作する論理回路とするためには、 まずは入力した回路をFPGAの設定情報に「コンパイル(compile)」 (または「インプリメンテーション(implementation)」と呼ぶ)し、 その後、それをFPGAに書き込むする必要があります。

まずは、コンパイルを行いましょう。

QuartusIIの画面の上のほうに並んでいるボタンの中から、 "Start Compilation"ボタンを押します。 すると、入力した回路をFPGAの設定情報に変換する作業が始まります。 右側中央の"Status"画面に、この作業の進捗状況が表示されますので、 すべてが"100%"になるまで、待つことにします。 すべての作業が無事終わると、"Full compilation was successful"の ダイアログが現れます。 もし入力した回路図に、変換作業が不可能な間違いがある場合は エラーが表示されて変換作業が中断しますので、適宜修正を加えます。 Warningが多く表示されますが、その多くは無視してかまいません。 なお当然ですが、回路図自体の間違い(論理機能の間違い)は、 この変換作業ではエラーとなりませんので、設計者が十分注意をして 設計をする必要があります。

回路の書き込みと動作

続いて、変換が済んだFPGA設定情報をFPGAに書き込みます。 まずはFPGAボードとPCをUSBケーブルで接続します。 その後、書き込みプログラムBBCを、メニューバーの アイコンから起動します。 その後、「Device」欄で、"EDA-003/EDX-005"を選んでおきます。

続いて、「File Open」コマンドを選び、FPGA設定情報(拡張子が *.rbfのファイル; sample.rbfなど)を選びます。 そして「Download」ボタンを押すと、書き込みが行われます。

書き込みが終了すると、FPGAは、直ちに動作を開始します。 すなわち、入力した回路図どおりの動作をするはずです。 スイッチSW[0], SW[1]を押し、LED[0], LED[1]の点灯の様子を確認しましょう。

このようにFPGAを用いた論理回路設計は、次の手順で行うことになります。

  1. 回路の入力
  2. コンパイル(インプリメンテーション)
  3. プログラム(書き込み)
したがって、回路の動作が予期したものと異なる場合や、 回路の仕様を変更したい場合でも、回路図を書き換えてこの手順を ふむだけで、すぐに新しい論理回路を動作させることができるわけです。

FPGAによる組合せ論理回路の設計と動作

演習1-1

FPGAボード上のスイッチ(SW[0]〜SW[3])とLED(LED[0]〜LED[7])を用いて、 適当な組み合わせ論理回路を設計し、その動作を確認してみましょう。 なおFPGAボード上のスイッチは、押すと0、離していると1、 またLEDは1で点灯、0で消灯となります。

※スイッチ・LEDは、0〜3を、0から順に使う数の分だけ番号をつけないと、 うまくいかないようです(仕様)。 つまり、例えばSW[0], SW[2]の2個を使い、SW[1]を使わない、という 回路は避け、2個のスイッチを使うのであればSW[0], SW[1]を使うのが 無難です。

FPGAによる順序回路の設計と動作

演習1-2

FPGAボード上のスイッチ(SW[0]〜SW[3])とLED(LED[0]〜LED[7])を用いて、 適当な順序回路を設計し、その動作を確認してみましょう。 例えば4桁のカウンタなどを設計するとよいでしょう。 (順序回路で用いるフリップフロップにはいくつかの種類があります。 また同じ名称でも、流儀によって微妙に表記方法と機能が異なる こともあります。 こちら を参考にするとよいでしょう) ちなみに、ある信号を常に"1"や"0"に設定したいときは、 primitives → others の中の、vcc("1")やgnd("0")を 使うことができます。

なおカウンタの入力(いわゆるクロック信号)に、スイッチを用いる場合、 スイッチの「チャタリング」という現象に留意する必要があります。 これは、スイッチを1回押したつもりでも、機械接点の動作上、 複数回のON/OFFが続いてしまう現象です。 このチャタリング現象の解消のためには、S-Rフリップフロップを用いた 回路を利用するのが効果的です。 余裕がある場合は、ぜひ試してみましょう。

演習1-3

※以下の内容のうち、後半の「ダイナミック駆動」の部分は、 やや発展的な内容ですので、余裕がない人は、 1桁分の7セグメントLEDで数字を表示する回路の設計だけでよいでしょう。

FPGAボード上には、4個の7セグメントLED(数値表示LED)があります。 これは、回路図としては次のように接続されています。

SG[0]〜SG[7]は、すべての7セグメントLEDの8つの表示素子に 並列に接続されていて、それぞれが次の表示素子に対応しています。 (実際の回路の設計では、SG[0]などの名称の出力端子(output)を作成すればよい)
つまりSG[0]を"1"にすると、「8の字」の上の表示素子が点灯するわけです。 なお実際の点灯のためには、該当する7セグメントLEDの下にある SA[0]〜SA[3]のいずれかを"1"にする必要があります。 つまり、例えばSA[3]="1"、SA[0]〜SA[2]="0"としてSG[0]="1"とすると、 一番左の桁の7セグメントLEDの「8の字」の上の表示素子のみが 点灯することになります。 この1桁分の7セグメントLEDに、先ほど作成したカウンタの出力を 「数字」として表示させて見ましょう。 (7セグメントLEDの点灯パターンの生成は、地道に真理値表から論理回路を つくるか、あるいは既存の74シリーズなどの機能ブロックを回路要素として 配置するとよいでしょう)

(以下、発展的な内容)
またFPGAボード上には、CLK6、CLK30という信号名で、それぞれ 6MHzと30MHzのクロック信号が与えられています。 変更することもできますが、通常は変更しなくてもよい) これを利用し、適当な周期で、SA[0]〜SA[3]を順に"0"として 1桁ずつ点灯させることにし、そのタイミングで、その桁に表示するべき 表示素子の点灯パターンをSG[0]〜SG[7]に与えることで、 すべての桁に所望の数字(などのパターン)を表示することができるわけです。 この方法では、ある瞬間に点灯しているのは1つの桁のみであるわけですが、 この切り替えを高速に行うことで、人間の目には、すべての桁が 点灯しているように見せることができます。 このような点灯方式を「ダイナミック駆動」と呼びます。

このダイナミック駆動方式で、4桁の7セグメントLEDを点灯させてみましょう。 なお4桁すべての駆動は、4進カウンタを作る必要があります。 まずは回路設計が容易な2桁の駆動を試みるのがよいでしょう。 また駆動周波数が高すぎる場合は、適当なビット数のカウンタの出力を クロック信号として用いることで周波数を落とし(この操作を「分周」と呼びます)、 所望の周波数を得るのがよいでしょう。 例えば1ビットの2進カウンタの出力は、クロック信号の1/2の周波数になります。


戻る