【初心者】モジュールを作ってみよう〜【FPGA入門】
普段は YouTube で機械学習について発信しています。お時間ある方は覗いていただけると喜びます。
YouTubeのvideoIDが不正です
Created by NekoAllergy
はじめに
FPGA を使うことで、自分だけの IC を作ることができます。今回は、FPGA で回路設計をする際に使う、VerilogHDL という言語 を使って、もっとも基本的な要素である「モジュール」を作ってみます。
「厳密さ」よりも、「分かりやすさ」を重視しています。ご了承ください。
分かること
- 回路内の部品(モジュール)はどうやって作る?
- 入出力ポートって?
今回のゴール
今回のゴールは、VerilogHDL を使って、「モジュール」が作れるようになることです。
スイッチを ON/OFF すると、LED が点灯するコードを紹介します。
誰に向けて?
FPGA についてあまり詳しくない方を想定して書きました。
今回の内容は、下記の記事を見てからの方が、理解が深まります。ぜひ。
(おさらい)HDL とは?
FPGA 内の電子回路(ハードウェア)の構成は、ハードウェア記述言語を使って書くことができます。ハードウェア記述言語は、Hardware Description Language の頭文字をとって、HDL(エイチ ディー エル)と略されます。
初めはプログラミング言語と思ったら OK ですが、プログラミング言語とハードウェア記述言語は全く違うものなので、注意してください。
(おさらい)HDL は 2 種類ある。2 種類しかない。
HDL は、VHDL と VerilogHDL の 2 種類が使えます。Python とか Javascript など、プログラミング言語に種類があるのと同じです。ハードウェア既述言語(HDL)では、基本的にこの 2 つしかありません。
- VHDL :ブイ エイチ ディー エル
- VerilogHDL :ヴェリログ エイチ ディー エル
どちらを使っても、FPGA 上にハードウェアを作ることができます。この 2 つに優劣はあまりないので、どちらを使うかは好みです。
今回は、Verilog の基本的なコードの書き方を解説します。ハードウェア記述言語(HDL)のイメージをつかむことが目的です。
モジュールってなに?
モジュールとは、回路を作るための 1 つ 1 つの部品のことです。
HDL の最終的な目標は、想像通りの動きをしてくれる電子回路(IC)を作ることです。そして、その IC はいくつかの部品から構成されています。 部品のことをモジュールと呼びます。
HDL で行うことは、必要なモジュールを作り、モジュール同士を配線でつなげていくことです。
部品を組み立てるぞ
1 つのモジュールは、1 つの役割を持っています。
たとえば、「カウンタ」と呼ばれるモジュールは、「数を数える」という役割をもっているモジュールです。「シフトレジスタ」と呼ばれるモジュールは、「1つずつ値をズラす」という役割をもっているモジュールです。
部品単体でみると、できる動きはめっちゃ単純で、シンプルなものばかりです。しかし、それらを組み合わせていくことで、複雑な動作をする IC を作ることができます。すごい。
突き詰めれば、FPGA を使って CPU を作ることもできます。GPU を作ることもできます。FPGA は、何にでも化けることができる、可能性を持った IC なんです。すごい。
たとえばこんな感じ ↓ で組み立てていきます。
module main();
input SW;
output LED;
assign LED = SW;
endmodule
上記のコードは、「スイッチの ON/OFF に合わせて、LED を点灯させる」というモジュールです。書き方は、プログライング言語の関数みたいですね。簡単な英単語だけなので、なんとなく伝わるはずです。
これは、いっちばん簡単なモジュールなので、もっと細かい動作をつけることもできます。
順番に解説していきます。
STEP01 モジュールを作ってみよう
1 からモジュールを作ってみます。わりと簡単です。
module and();
//この中がモジュールの内部
endmodule
上記のコードでは、モジュールの枠組みだけ書きました。module から始まり、endmodule で終わります。これで 1 個のモジュール完成です。うれしい。
and();
の部分にモジュールの名前を書きます。モジュール名はプログラマが自由に決めることができます。今回は、and って名前にしてみました。
このコードでは、形だけ定義した状態なので、特に動作も何も起こりません。ただ、エラーも発生しないので、FPGA に書き込むこともできます。(何も起こらないけどね)
STEP02 入出力ポートを追加しよう
次に、モジュールに「ポート」を追加します。モジュールという体から、足をはやすイメージです。
module and(signal_a ,signal_b, signal_out);
input signal_a; //入力信号
input signal_b; //入力信号
output signal_out; //出力信号
//ココに処理を書いていく
endmodule
and()の、(かっこの中)にポートの名前を並べて書き足します。ここでは、signal_a
, signal_b
, signal_out
という 3 つのポートを定義しました。
また、各ポートに対して、入力信号なのか、出力信号なのかを決める必要があります。今回の場合、signal_a
と signal_b
が、モジュールに入力されて、signal_out
が、モジュールから出力されることにしたいです。
これにより、モジュールが別のモジュールと通信できるようになりました。ポートって出入口みたいな意味です。ポートの書き方とか考え方は、普通のプログラミング言語でいう、引数と返り値みたいな感じですね。
この状態でも FPGA に書き込めますが、まだ何も動きません。
STEP03 処理を記述するぞ
さて、モジュールの中に処理を追加していきます。
module and(signal_a ,signal_b, signal_out);
input signal_a;
input signal_b;
output signal_out;
assign signal_out = signal_a & signal_b; //ここ追加した
endmodule
内部の処理を記述しました。今回は、signal_a と signal_b の、AND(論理積)をとり、その結果を signal_out に繋げてみました。
assign 文を使うことで、信号を繋げることができます。(詳しくは割愛)
それぞれの信号は、1bit 分の 2 進数という点に注意してください。普通のプログラミイング言語みたいな、整数とか文字列は出てきません。(ちょっと出てくる場合もあるけどね)
モジュールを呼び出すぞ
改めて言いますが、モジュールはただの部品です。そのままでは、ただ定義しただけです。なので、作ったモジュールを、実際に使ってみましょう。
module main();
input SW_A;
input SW_B;
input SW_C;
output LED_01;
output LED_02;
and a01(SW_A, SW_B, LED_01) //ここでモジュールを使っている
and a02(SW_B, SW_C, LED_02) //ここでモジュールを使っている
endmodule
新しく、main()というモジュールを作りました。このモジュールには、3 つのスイッチと、2 つの LED をポートして定義しました。
詳しくはまた紹介しますが、main モジュール のポートは、実際の FPGA ボード についているボタンとか LED に繋がっています。(コードとは別の設定が必要です。今回は割愛。)(別に main って名前じゃなくても OK だよ)
さて、この main モジュールに、さっき作った and()モジュールを追加しています。プログラミング言語の関数のように使うことができます。
and a01(SW_A, SW_B, LED_01)
の部分で追加しています。and
はモジュール名です。a01
の部分は、個別に付けることができる名前です。無くても動作しますが、モジュールをたくさん使う場合、それぞれに名前があった方が便利です。
さて、これにより、こんな回路を作ることができました。↓
💡SW_A と SW_B を同時に押すと、LED_01 が光る。
💡SW_B と SW_C を同時に押すと、LED_02 が光る。
とってもシンプルです。
FPGA に書き込めば、回路を動作させることができます。
今回のまとめ
今回は以上です。興味を持たれた方は、ぜひもっと調べて見てください 🐱
全コード
//ここからメインのモジュール
module main();
input SW_A;
input SW_B;
input SW_C;
output LED_01;
output LED_02;
and a01(SW_A, SW_B, LED_01)
and a02(SW_B, SW_C, LED_02)
endmodule
//ここからAND回路のモジュール
module and(signal_a ,signal_b, signal_out);
input signal_a;
input signal_b;
output signal_out;
assign signal_out = signal_a & signal_b;
endmodule
機械学習をもっと詳しく
ねこアレルギーの AI
普段は YouTube で機械学習について発信しています。お時間ある方は覗いていただけると喜びます。
YouTubeのvideoIDが不正です
Created by NekoAllergy
Discussion