電子趣味の部屋

電子系のガジェットやアプリ開発等の趣味の話題を書いてます

FPGAのこと

FPGAについて

FPGAはロジックICが論理的(仮想的)に作れちゃいます。
本気になればCPUどころか、マイコンみたいに周辺機器込みで作れちゃいます。
実際に知っている方もいると思いますが、1chip MSXFPGAで作られています。
他には主に機能チップを作る時の試作品を作るのに使われるようですが、最近ではそのまま製品に組み込んでるものもあるようです。

今回始めるにあたって、FPGAのチップを単体で買ってきて、自分で基板を作るのも考えましたが、面倒なので、スタータキットを買って始める事にしました。

いま日本で良く知られているメーカーが2社あります。
XILINXALTERAです。

この2つのメーカーで悩んだのですが、結局両方のスターターキットを購入してしまいました。
それも両メーカーとも2種類ずつ!久々の無駄な出費です。

購入したものを紹介します。
まずはXILINXから
Spartan-3E スタータ キット
一番基本のボードです。
50万ゲートのFPGAが乗ってます。
Spartan-3A スタータ キット
Spartan-3Eの上位にあたるSpartan-3Aが乗ってます。70万ゲートです。
他にはメモリがDDR2(Spartan-3EはDDR)になったことや、VGA出力が4096色(Spartan-3Eは8色)になっています。

Altera社DE1開発学習ボード
2万ロジックエレメントのFPGAが乗ってます。
XILINXと単位が違うのですが、勝手にSpartan-3E スタータ キットの50万ゲートと同等と思ってます。
ちなみに、1chip MSXでもALTERAのFPGAが使われてて、CPU,チップセット?,ビデオコントローラ他多数で1.2万ロジックエレメントで足りているようです。
メモリはSDRAMなので、初めは使いやすそうです。

以上、ここまで紹介したのは、すべてVGA出力、PS2入力、メモリ、サウンド関係の入出力が付いています。まるでPCをそのまま作れてしまいそうな構成ですが、実際に作れます。
PC-8001X1MZ-700を作っている人がいます。
ここで紹介したのはもっと古い基板を使っているので、もっとすごいものが作れるはずです!

あと1つおまけで練習にALTERAで良さそうなのがあったので、購入しました。
MAX IIマイクロキット
これは小さくて、2210ロジックエレメントです。上の3つにあるような色々な入出力のコネクタはありません。

ちなみに、XILINXの2つはマルツパーツ館で、ALTERAの2つはソリトンウェーブで購入しました。

FPGAでデザインする言語は主にVHDLとVerilogHDLがあります。
VerilogHDLが簡単そう?なので、こちらでやる事にしました。

ソフトのプログラムを経験すると、どうしても初めはわからなくなってしまう部分があります。
文法はPascalチックでIFやFOR等の制御文はあるのですが、基本的に全部同時に動作します。例えばものすごく簡略化しますが、
a = b;
c = d;
みたいな事を書いたとします。
ソフトなら、"a=b"が実行された後に、"c=d"が実行されるのですが、ハードは"a=bと"c=d"が同時に実行されます。
例えが悪いかもしれませんが、表現が難しいです。まあ、慣れが必要そうですね。

参考にした本。
文法がわかりやすく書かれてて良いと思います。本当は別の本を買ったのですが、わかりにくくて、この本を後から買いました。

手始めにMAX II Micro KItを使ってみる

まずは動かしてみたいと思います。

前回書いた通り、わかりやすそうなVerilogHDLを使っています。
FPGAはどのメーカーも共通ですが、論理合成(コンパイルに相当)はメーカー毎のツールを使います。
XILINXならWebISE、ALTERAならQuartusIIを使います。
フリー版は両方とも使えるデバイスに制限がありますが、スターターキットなら大丈夫です。

今回は一番小さいMAX II Micro Kit を使いました。
ALTERAのやつです。

まずはQuartusIIのIDEでピンの設定をします。
設定方法は省略しますが、初めから基板にあるタクトスイッチ4個とLED8個とクロックを割り振りました。

次はコードを書いていきます。

いきなりソースコードです。

module test(LED, KEY, CLOCK_50);

    input CLOCK_50;
    input [3:0] KEY;
    output [7:0] LED;

    reg [3:0] ledstatus;

    assign LED[3] = KEY[3];
    assign LED[2] = KEY[2];
    assign LED[1] = KEY[1];
    assign LED[0] = KEY[0];

    assign LED[7] = ledstatus[3];
    assign LED[6] = ledstatus[2];
    assign LED[5] = ledstatus[1];
    assign LED[4] = ledstatus[0];

    always @(posedge CLOCK_50) begin
        ledstatus[3] <= ~KEY[3];
        ledstatus[2] <= ~KEY[2];
        ledstatus[1] <= ~KEY[1];
        ledstatus[0] <= ~KEY[0];
    end

endmodule

順を追って説明すると、
今回のモジュール名は"test"です。
クロックに接続されているピン(CLOCK_50)と、タクトスイッチに接続されているピン(KEY)をインプットに設定。
LEDに接続されているピン(LED)をアウトプットに設定。
LED7〜LED4の状態を保持する4ビットのレジストリ(ledstatus)を定義します。
LED3〜LED0をそれぞれKEY3〜KEY0に接続します。
ここまでですと。タクトスイッチを押すと、それに接続されたLEDが光ります。
まあ、それではまだつまらないので、その次以降の処理です。
LED7〜LED4をそれぞれレジストリledstatusの各ビットに接続します。
ちょっとここで遊んでクロックのタイミングで動くようにしてみました。
alwaysの文でここに書いている意味は、クロックの立ち上がりでbeginとendの間の処理を実行します。
レジストリledstatusの各ビットへタクトスイッチのそれぞれの状態のNOT値を入れています。
ここで注意する点は、全部同時に実行される事です。
ソフトに慣れた方はつい"ledstatus[3] <= ~KEY[3];"の文が実行された後に"ledstatus[2] <= ~KEY[2];"が実行されるように考えてしまいがちですが、
実際は、1回のクロックでbeginからendの処理が同時に行われます。
ここで同じ事をソフトでやろうとすると、1命令に1クロックかかると仮定すると、4クロックです。
それがハードでは1クロックで完了してしまいます。
実際にはソフトでCPUだけでグラフィックやサウンドの機能は実現できますが、速度が遅いのであえて別にGPUやサウンドチップを使う意味が分かりますね。
ハードウエア的に処理する方が早いです。

以下は実際に動かしてみた写真です。

まずは初期状態

左の4つのLEDが光ってみます。

次に右から2番目のボタンを押してみました。

右から2番目のLEDが光り、左から3番目のLEDが消えています。

ちなみに、Spartan-3Eスターターキットでもピンの定義を変えるだけで、ソースコードはそのままで同じ動作をする事が出来ました。
これだけなのに、初めて電子工作をしてPICでLEDを光らせるのに成功した時と同じ位嬉しいです。

FPGA活用チュートリアル (デザインウェーブムック)

FPGA活用チュートリアル (デザインウェーブムック)

FPGAボードで学ぶVerilog HDL

FPGAボードで学ぶVerilog HDL