FPGAメモ

# 書く理由

仕事柄、AlteraのFPGAに関する知識が必要になったのでメモ

# FPGAって何

Field Programmable Gate Array の略。
直訳すると、現場でプログラム(書き換え)可能なゲートアレイ。

お、最後のは知らない言葉だ。
また別に知る必要がある。

話を戻すと、論理回路で構成された計算機の一種ということみたい。
特定の動作を行うと決まっている時には強そう...

[どうしていまFPGAなのか、そしてFPGAとは何か?](https://news.mynavi.jp/kikaku/software_fpga-1/)

## CPUとの違い

CPUの回路は決まっていて変更が不可能。
だけど、メモリやらにあるプログラムから計算することで汎用性に長けている。

一方、FPGAは書き換え専門=チップ自体の回路を書き換え可能
ということになる。

なにそれ、すごい。

[こちらの方の記事が参考になりました] (https://qiita.com/kazunori279/items/a9e97a4463cab7dda8b9#%E3%81%A7%E3%81%AFcpu%E4%BB%A5%E5%A4%96%E3%81%AE%E9%81%B8%E6%8A%9E%E8%82%A2%E3%81%AF)

# どういう時に役立つの

例えば僕みたいなやらかしマンあるあるで、**後になって発覚する取り返しのつかない場合**とか。

ある爆速なチップの設計を仮定
CPUでもGPUでも単純なLSIでもいい。

1. 量産化の前に試験用として製作
2. 試験期間で問題は無く、そのまま量産化
3. 量産化後にある問題が発覚
4. 大量の欠陥品を抱えて東尋坊へ飛び込む

と、まあこんな感じになり人生終了。
アタリ社のE.T.のような感じ。

FPGAならば書き換えるだけで済む。
人生を終わらせずにも済む。

## どうやって回路を構成するの

回路設計の言語はHDLと呼ばれる。
こいつをFPGAに書き込めば回路が構成される仕組み。（俗にいうアルテラ焼き）

HDLにも幾つか種類があって、代表的なのは以下の通り。

- AHDL: アルテラの設計したハードウェア言語。あんまり使われないらしい。
- VHDL: IEEEで標準化されている、主流その1。
- Verilog HDL: VHDLから派生したソフト寄りな言語。主流その2。

なんかいろいろあるんやね。
Wikipediaを読んでも情報量が多くてわかんない。

## まあとりあえず手を動かそう

勤務先では先人達のおかげで再設計をせずに済むようだが、今後また更なる開発を行うとなると知っておいて損はない。はず、ので

まずは自分のMacに環境を導入してみて、HDLに触れてみるところからはじめる。
言語はVerilogを使います。Lチカは出来ないから、波形を測定します。

以下を参考にさせていただきました。
[OSXでのVerilogHDL環境構築&4bitカウンターを作って波形を見る](https://qiita.com/Hiroki11x/items/ec8ce716d3117360313f)

- Icarus Verilog -> Verilogのシミュレータ
- GTKwave -> 波形描画ソフト

以下、ソースコードお借りします。
4bitカウンタの**ハードウェア部**になります。

```count.v
module COUNT(RESET, CLK, COUNT);
   input RESET, CLK;
   output [3:0] COUNT;
  
   reg [3:0] COUNT;
  
   always @(posedge CLK)
   begin
     if (!RESET)
        COUNT <= 4'h0;
     else
        COUNT <= COUNT + 4'h1;
   end
endmodule

```

。。。わからん

ので、調べてみた。
[Verilog入門](https://qiita.com/thtitech/items/8cc898dda7a10780f495)

1行目ではモジュールの名前（グローバル変数）的なやつか？を決めているようだ。
2行目で入力、3行目で出力と定めている。
3行目の謎カッコは出力時のビット数ということだな。（4bitだから3~0）

次にreg
こやつはレジスタ。Cでいうなら変数。（値を保持する）
ちなみにVerilogにはregの他に、wireと呼ばれるものが存在していて、**値の変化を認める変数**とでもいいますか。。。。値が流れるんだって。なにそれすごい（2回目）

あくまでもハードであることを忘れないように...
値を保持する入れ物=reg -> 不変
値が流れて変化する**線**=wire -> 変

で、regを使ってんならalwaysで動作タイミングを記述してね、、、ってのが以降の文。
wireは自由な奴だから、wireを接続（assign）すれば、記述通りに勝手に動くようだ。

`(posedge CLK)`の部分は流石に僕でも予想できた。
要は、CLKが立ち上がった時、以降のif文を実行するということ。この辺はラダー図みたい。（きゃつらも大まかには回路の一種）

```
if (RESET == 1'b0)
    COUNT <= 4'h0;
else
    COUNT <= COUNT + 4'h1;
```

肝心の中身は、
RESETが立ち下がっている -> 0 のとき、リセットをする。
そうでないとき（CLKとRESETがpositive）はカウントアップということか。
ううむ、謎。

上記回路を実行するベンチマークのソースは以下の通り。
お借りします。。。

```count_test.v
module top();
  reg CLK, RESET;
  wire [3:0] w_cnt;
  COUNT COUNT_instance(CLK, RESET, w_cnt); 
　↑先ほど作ったモジュールのインスタンスを生成してるのかな？

  initial begin
    CLK = 0;
    forever #10 CLK = ~CLK;
  end

  initial begin
    RESET = 0;
    #30 RESET = 1;
  end

  initial begin
    #500 $finish();
  end

  always @(posedge CLK) begin
    $write("[%t] COUNT: %b\n", $time, w_cnt);
  end

  initial begin
      $dumpfile("count_test.vcd");
      $dumpvars(0, COUNT_instance);
  end

endmodule
```

なるほど、わからん。（参考書欲しい）
もっと時間あるときにすればよかったな。。

```コンパイル.hoge
$ iverilog -o count_test.out count.v count_test.v
```

以下でシミュレーション。

```実行.hoge
$ vvp count_test.out
VCD info: dumpfile count_test.vcd opened for output.
[                  10] count: xxxx
[                  30] count: 0000
[                  50] count: 0001
[                  70] count: 0010
[                  90] count: 0011
[                 110] count: 0100
[                 130] count: 0101
[                 150] count: 0110
[                 170] count: 0111
[                 190] count: 1000
[                 210] count: 1001
[                 230] count: 1010
[                 250] count: 1011
[                 270] count: 1100
[                 290] count: 1101
[                 310] count: 1110
[                 330] count: 1111
[                 350] count: 0000
[                 370] count: 0001
[                 390] count: 0010
[                 410] count: 0011
[                 430] count: 0100
[                 450] count: 0101
[                 470] count: 0110
[                 490] count: 0111

```

5secまでカウントアップしてますね


### 波平

![てst.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265207/6b7188bd-e82f-73a9-0994-08f4c5b60a97.png)

# まとめ
スターターキットと入門書を買ってからですね。

あと気になるのは、FPGAを使ってCNN演算を実装してる強者がいるらしい。
もうこれわかんねぇな。

---

参考先
[Verilog入門](https://qiita.com/thtitech/items/8cc898dda7a10780f495)
[OSXでのVerilogHDL環境構築&4bitカウンターを作って波形を見る](https://qiita.com/Hiroki11x/items/ec8ce716d3117360313f)
[そろそろプログラマーもFPGAを触ってみよう！] (https://qiita.com/kazunori279/items/a9e97a4463cab7dda8b9#%E3%81%A7%E3%81%AFcpu%E4%BB%A5%E5%A4%96%E3%81%AE%E9%81%B8%E6%8A%9E%E8%82%A2%E3%81%AF)