今回からは打って変わって、FPGA を用いたロジック設計にチャレンジしてみようと思います。
モチベ
会社の研修で FPGA を用いたロジック設計を行いました(学生時代に Verilog は多少触れてきた)。これまではソフトしか書いていなかったのでこれが難しい。同じソースコードを書くと言っても、その記述によって出来上がるハードを想像しながら設計しなければならないため、非常に低レイヤ寄りで楽しいです。
そこで、食わず嫌いだったハードウェアロジック設計もこれからやっていこうと思います。何事にもチャレンジ。ソフトより有利な点って考えてみればいくつもあると思うの(多分)。
そもそも Digilent の PYNQ-Z1 を持っていながら、
- Vivado がよくわからない
- Synthesis とか Implimentation とか Bitstream とかわからん
- そもそも L チカごときで合成まで時間かかりすぎ
という感じで放り投げていました。積み FPGA ボード、ですよ。もったいない...
そこで、上に書いたように会社で FPGA にふれる機会があったので、ぜひこれも趣味にしてみようと思ったわけです。
環境づくり
Windows でやりました。Linux が良かったんですが、普段遣いするいい感じのマシンに Linux が入ってないんですよね~。まず思ったのが、マイコンと違って IDE の規模がでかい。余裕で 10GB 超えてきて、心理的に負担が大きいような気がしますw 新居でまだネット回線が満足に用意できていないので、ダウンロードだけでも相当時間がかりました。
Vivadoのセットアップ
Xilinx のページから Vivado をダウンロードするのですが、見慣れた構成ではなくなり、Vivado ML Edition というものになっています。よくわからんのでこの最新版はインストールせずに Vivado Design Suite - HLx Edition - 2020.2 を入れました。インストーラ内で Webpack Edition を指定。また、DocNav は謎にファイル容量でかいし、ドキュメントなんて自分で探してくるよ!!と思ったのでインストールしませんでした。
その後のボード設定ファイルの配置、大まかなフローは以下の Qiita の記事通りでいいです。
Verilogシミュレーション環境の構築 on WSL
そもそも Vivado は重いので、シミュレーションは別環境でやりくないですか(唐突)。そこで WSL を用いましょう。ターミナルソフトは Microsoft 謹製、ストアからダウンロードできる Windows Terminal を使っています。これめちゃ使いやすいのよ。
WSL には Ubuntu が入っていて、以下で Verilog シミュレーション環境は手に入りますよ~。お手軽ね。
実際のところ Vivado 上でシミュレーション可能ですが、如何せん重く、また自作モジュールのみの評価で満足しているため以下のような方法を取ることにします。
$ sudo apt update
$ sudo apt install iverilog fonts-ipafont gtkwave
iverilog
は Verilog のコンパイラ(Icarus Verilog)で、gtkwave
はフリーの論理波形ビューアです。ついでに IPA フォントもインストールしてます。
ただ、このままだと GUI が使えないので、X server 環境が必要になります。ここから Xming を導入して起動。その後以下を WSL 内で実行することで WSL が Xming と繋がり、GUI 開発環境ができようになる...はずです。
$ export DISPLAY=localhost:0.0
試しにWSL上でロジックシミュレーション
WSL にできたシミュレーション環境でちょっと遊んでみましょう。ここでは 16進カウンタを作ります。
16進カウンタとは、0から1つずつインクリメントしていき15になったら次のクロックで0にリセットされる回路です。一般に 2^n 進カウンタ以外ではゼロリセット処理の記述が必要なのですが、2^n 進では勝手にオーバーフローしてくれるので手軽です。まさにロジック界の L チカ(しらんけど)。
以下がその実装内容。ただのカウンタです本当に。拡張性があるといいなあってことで、カウントがいっぱいになったとき用に FULL
という信号線を1クロック幅だけ立ち上げています。
// counter16.v
module counter16(
input wire nRST,
input wire CLK,
output reg [3:0] OUTP,
output reg FULL
);
always @(posedge CLK or negedge nRST) begin
if( ~nRST ) begin
OUTP <= 4'd0;
FULL <= 0;
end
else begin
OUTP <= OUTP + 4'd1;
FULL <= (OUTP == 4'd15) ? 1 : 0;
end
end
endmodule
これで回路はできたんですけど、テストする必要があります。そのためのテストベンチを用意しましょう。
// test.v
module test_counter16;
reg nRST, CLK;
wire [3:0] OUTP;
wire FULL;
counter16 u_cnt16(
.nRST(nRST),
.CLK(CLK),
.OUTP(OUTP),
.FULL(FULL)
);
initial begin
nRST = 0;
CLK = 0;
end
always begin
#1;
CLK = ~CLK;
end
initial begin
#1;
nRST = 1;
#50;
$finish;
end
initial begin
$dumpfile("counter16.vcd");
$dumpvars(0, test_counter16);
end
endmodule
テストベンチはイメージで言うと、買ってきた IC に信号を入れる回路っていうイメージだと思ってます。あくまでもハードウェア設計なので、できるのは回路ですよと。
最後にコンパイルをして、できた実行ファイルを実行しましょう。counter16.vcd
という波形データが生成されているはずです。
$ iverilog counter16.v test.v
$ ./a.out
VCD info: dumpfile counter16.vcd opened for output.
$ ls
a.out* counter16.v counter16.vcd test.v
これを GTKwave に読ませればいいわけです。
$ gtkwave counter16.vcd &
すると以下のような画像が出てきます。いい感じに動いているみたいですね。
これを必要に応じて Vivado のプロジェクト内にコピーし、最終的には FPGA 内に焼き込むというわけです。
〆
Vivado は全く動かしていませんが、ひとまず環境はできました。
つまり、これからは WSL で RTL 作成して、波形を見た上で Vivado にインポートというやり方をすれば、スマートに開発が進められますね!純粋に嬉しいです!!