FPGA未経験者がDE0-Nanoを初めて動かす際にハマりそうなポイント


# 前書き

先日まとまった時間をとってFPGAを動かしてみたところ、いくつか予期せぬトラブルに見舞われましたので、初心者が遭遇し得るトラブル例を挙げてみます。

本稿では Quartus II や HDL の扱い方について言及しません。回路の実装までの具体的な作業手順などについては他の情報源に譲ります。
たとえば参考文献[\[2\]][ref2]が、プロジェクトの新規作成からピンアサイン、書き込みまでの手順を画面付きで一通り掲載していてとても良いです。


## 検証環境

- OS
	Windows8.1 / Antergos Linux(Arch Linux Based)

- FPGA ボード
	DE0-Nano (Cyclone IV EP4CE22F17C6N)

- HDL
	VHDL

# 本題

まず VHDL のコードを以下に記載します。

```vhdl:LED_blink.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity LED_blink is
	port(
		clk : in std_logic := 'X';
		LED : out std_logic_vector(7 downto 0) := (others => 'X')
	);
end entity;

architecture IMP of LED_blink is

signal LED_reg : std_logic_vector(31 downto 0) := (others => '0');

begin 
	process(clk)
	begin
		if rising_edge(clk) then
			LED_reg <= std_logic_vector(unsigned(LED_reg) + 1);
		end if;
	end process;
	
	LED <= LED_reg(31 downto 24);
	
end architecture;
```

これはレジスタ`LED_reg`をカウントアップし `LED` にこのビットパターンを出力する回路です。作成したら、なにも考えず Quartus II で論理合成します。

## 1. HDLの文法エラー

考えられる原因: **Top-level entity**[^2] の名前が VHDL の `entity` 名と一致しない

Quartus II では、新規プロジェクトの作成時に Top-level entity という属性を設定しています。この名前と VHDL コードの `entity` 名が一致しないとエラーを引き起こします。

### 解決方法 1. プロジェクトの設定を変える

[Assignments]→[Settings]→[General]から "Top-level entity" を直接編集します。

![top_setting.png](https://qiita-image-store.s3.amazonaws.com/0/63874/476cf239-d3a3-41d0-96d8-97655522ba6d.png)

ここで設定されている `top_level` を `LED_blink` に、つまりコード側に合わせて変えると良いでしょう。

### 解決方法 2. 別の回路から呼び出す

先の方法とは逆に、プロジェクトの設定に合うように修正します。もっとも簡単なのは VHDL 側の修正ですが、ここでは別ファイルから呼び出すようにしてみます。

まず新規に VHDL コードを作成し、ここで作成する `entity` 名を `top_level` とします。
この回路で `component` として `LED_blink` を呼び出すことで、先と同様の挙動をする回路が論理合成できます。

```vhdl:top_level.vhd
library IEEE;
library work; -- local library ; 省略可能
use IEEE.std_logic_1164.all;
use work.LED_blink; -- 省略可能。ただし work.all ではこれ自身を含む可能性がある

entity top_level is
    port (CLK : in  std_logic;
          LED : out std_logic_vector(7 downto 0));
end top_level;


architecture IMP of top_level is

-- begin の前に component を登録しておく

component LED_blink is
    port (CLK : in  std_logic;
          LED : out std_logic_vector(7 downto 0));
end component;

-- 


begin

    p1 : entity work.LED_blink(IMP)
    -- 省略して単に次のように記述してもOK
    -- p1 : LED_blink
    port map(CLK => CLK, 
             LED => LED);

end IMP;
```

注: Quartus II に依存した記述かもしれません。未検証です。

## 2. USB Blasterを認識しない

考えられる原因: ドライバが登録されていない可能性

### Windows の場合

デバイスマネージャから[ほかのデバイス]→[USB-Blaster]→[プロパティ]→[ドライバーの更新]を選択。

![dev_win1.png](https://qiita-image-store.s3.amazonaws.com/0/63874/2f85d7f7-879e-f794-0ed8-ecbd8e60efdf.png)

[コンピュータを参照してドライバーソフトウェアを検索します]を選択。

![dev_win2.png](https://qiita-image-store.s3.amazonaws.com/0/63874/e02897c0-3bc9-627b-9dad-fda2bd0713c4.png)

黒塗りしてる箇所に `<Quartus II のインストール場所>\drivers` を指定してください。[次へ]を押すとインストールが完了します。

### Linux の場合

以下の記事にしたがって `/etc/udev/` の下に手動でルールを追加します。

[Altera Design Software - ArchWiki](https://wiki.archlinux.org/index.php/Altera_Design_Software#USB-Blaster_Download_Cable_Driver)

## 3. 論理合成は成功したがLEDが光らない

考えられる原因: ピンアサインの設定ができていない可能性がある。

[Assignments]→[Pin Planer]からピンアサインが下表のようになっているか確認してください。

|Node Name|Location|
|---------|--------|
|CLK|PIN_R8|
|LED[7]|PIN_L3|
|LED[6]|PIN_B1|
|LED[5]|PIN_F3|
|LED[4]|PIN_D1|
|LED[3]|PIN_A11|
|LED[2]|PIN_B13|
|LED[1]|PIN_A13|
|LED[0]|PIN_A15|

表は参考文献[\[1\]][ref1]から引用しました。

ピンアサインを設定する際は Quartus のプロジェクトのあるディレクトリに `[プロジェクト名].qsf` が配置されているので、このスクリプトを編集することをお勧めします。
先の表に対応したコードを下記に記載します。

```tcl:project.qsf
(略)
...
set_location_assignment PIN_L3 -to LED[7]
set_location_assignment PIN_B1 -to LED[6]
set_location_assignment PIN_F3 -to LED[5]
set_location_assignment PIN_D1 -to LED[4]
set_location_assignment PIN_A11 -to LED[3]
set_location_assignment PIN_B13 -to LED[2]
set_location_assignment PIN_A13 -to LED[1]
set_location_assignment PIN_A15 -to LED[0]
set_location_assignment PIN_R8 -to clk
...
(略)
```

終わりに
--------

以上、FPGAで初めて開発する際に引っ掛かりそうなトラブルを三例ほど挙げました。


 次回は Nios II プロセッサに関する内容を予定しています。 


参考文献
--------

1. [DE0-Nano User Manual][ref1]
2. [DE0-Nanoの覚え書き | なんでも独り言][ref2]

[ref1]:http://www.altera.com/literature/ug/DE0_Nano_User_Manual_v1.9.pdf
[ref2]:http://ehbtj.com/electronics/memorandum-de0-nano/

脚注
--------
[^2]: ここではプログラムにおけるエントリポイント。なお entity は Verilog における module