PYNQ で遊ぶ : 2. Verilog HDL を使ってみる

# これは何か

PYNQ-Z1 を使って遊んでみます。

今回は、下記ができるようになる事を目指します。

- Verilog HDL のコードを書いてみる
- Verilog HDL でモジュールを作って IP に接続する


##### 関連記事：

- [PYNQ で遊ぶ : 1. LED を点滅させる
](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8)


# する事

- CLK を数えるカウンタを verilog HDL で書く
    - カウンタを使って分周して、LED を点滅させる


# 役に立ちそうなリンク
...


# 2-1. プロジェクトの作成

- PYNQ や Vivado のセットアップがまだな場合
    - [手順 1-2. 開発の準備](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-2-%E9%96%8B%E7%99%BA%E3%81%AE%E6%BA%96%E5%82%99) を参考に済ませておきます

- [手順 1-3. プロジェクトの作成](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-3-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90) を参考に、新規プロジェクトを作成します
    - Project name : asobu02
    - Project location : ~/vivado/asobu
    - にしました。

- [手順 1-4-1. ZYNQ の IP を配置する](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-4-1-zynq-%E3%81%AE-ip-%E3%82%92%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B) を参考に、Block Design を作ります
    - 名前は design_1 のままにしました

# 2-2. Verilog HDL でモジュールを作る

## 2-2-1. Verilog HDL のファイルを追加します。

Sources の Design Sources を右クリックし、Add Sources をクリック

<img width="250" alt="スクリーンショット 2020-08-04 18.10.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/3f112b47-782f-1e24-30e0-5bdbd81e86a1.png">

design sources が選択されている事を確認して Next

<img width="300" alt="スクリーンショット 2020-08-04 19.05.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/29e78733-df9f-bc50-2147-50cd2e0d8821.png">

Create file をクリックし、File name を指定。led_blink にしました。

<img width="400" alt="スクリーンショット 2020-08-04 19.07.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/85056df6-be78-fe70-2fc7-00578e5948a3.png">

Finish をクリックして完了

<img width="400" alt="スクリーンショット 2020-08-04 19.08.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/bcf4fab5-2678-5d45-9404-67a15683911c.png">

I/O Port は後で設定するので、とりあえず OK します。警告が出ますが yes

<img width="350" alt="スクリーンショット 2020-08-04 19.10.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/2fe62cbf-cc5a-0e60-598f-0733ab3f6d78.png">

## 2-2-2. Verilog HDL のファイルを編集します

- 新しくできた led_blink をダブルクリック
- 右に、エディタが開きます

<img width="550" alt="スクリーンショット 2020-08-04 19.11.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/2f74c6b3-152e-4af8-efe9-f28615c4cc7c.png">

- 100 MHz でクロックが来ます
- そのクロックを 26 bit カウントします
- LED への出力を、カウンタの 26 bit 目と同期させて点滅させてみましょう
- 0.335 秒くらいで ON/OFF が切り替わるはずです

```verilog:led_blink.v
module led_blink
  (
    input CLK,   // 入力 CLK を定義します
    output led   // 出力 led を定義します
  );             // 最後の行には , がいらないので注意
  
  reg [25:0] counter;    // 26 bit のカウンタを定義します
  
  always @(posedge CLK)  // CLK が立ち上がるたびに、この中が実行されます
    begin
      counter <= counter +1; 
    end                // counter を 1 追加するだけです。 +=, ++ は使えません
                       // 桁が溢れると、0 に戻ります
    
  assign led = counter[25];  // counter の 26 bit 目を led に接続します
    
endmodule
```

エディタの編集が終わったら、Ctrl+S を押すか save ボタンを押して保存しておきます。

<img width="500" alt="スクリーンショット 2020-08-04 19.22.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/11c4afd5-f5d8-4060-5994-4bbdf7310e75.png">



# 2-3. IP Integrator で IP を配置する

大まかな手順は下記です：

- led_blink.v を配置する
- ZYNQ (CPU) の IP を配置する
- 配線する

## 2-3-1. 自作モジュールを配置する

- Diagram をクリックしておきます
- led_blink.v を右クリックし、Add Module to Block Design をクリック

<img width="500" alt="スクリーンショット 2020-08-04 19.23.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/e31f09d5-bdaa-93cf-3c0e-04499d691355.png">

led_blink.v モジュールが設置されます

<img width="500" alt="スクリーンショット 2020-08-04 19.25.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/a033b4f2-ac15-57cc-683c-e3d0a7fc1703.png">

## 2-3-2. ZYNQ を配置する

[手順 1-4-1. ZYNQ の IP を配置する](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-4-1-zynq-%E3%81%AE-ip-%E3%82%92%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B) を参考に、ZYNQ の IP を設置します。

<img width="500" alt="スクリーンショット 2020-08-04 19.27.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/9d8a581a-36bc-332f-272c-bcb8f4d6b8e2.png">


## 2-3-3. 配線する

led_blink_0 の led 端子を右クリックし、Make External をクリックします

<img width="300" alt="スクリーンショット 2020-08-04 19.28.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/ae4cdf0d-3278-1a97-d94f-747a08b63df7.png">

生成された led_0 ポートをクリックし、External Port Properties ボックス内の Name: を LED に変更します

<img width="700" alt="スクリーンショット 2020-08-04 19.30.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/03dedc33-2e06-4969-7c8f-f39ae52b762d.png">

- Run Connection Automation と Run Block Automation をクリックして実行します
- ZYNQ7 Processing System の FCLK_CLK0 と M_AXI_GP0_ACLK が自動で配線されなかったので、手動でつなげます
- デザインはこうなりました

<img width="500" alt="スクリーンショット 2020-08-04 19.36.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/ab0e3155-6639-ff5e-d627-5e1eaecae152.png">



# 2-4. 後仕上げ
## 2-4-1. HDL Wrapper を生成する
[手順 1-5. HDL Wrapper を生成する](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-5-hdl-wrapper-%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B) と同様の手順です

## 2-4-2. 制約ファイルを設定する
[手順 1-6. 制約ファイルを設定する](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-6-%E5%88%B6%E7%B4%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B) と同様の手順です

## 2-4-3. 生成する
[手順 1-7. 生成する](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-7-%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B) と同様の手順です

こんな実装になりました。AXI を使ってないので、とてもシンプルですね。

<img width="700" alt="スクリーンショット 2020-08-04 19.40.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/4f4209df-97e1-c23b-7b03-7fec9f0b6d5c.png">


# 2-5. PYNQ で実行する
## 2-5-1. ファイルのアップロード

- [手順 1-8-1. ファイルのアップロード](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-8-1-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89) を参考に PYNQ へアップロードします
- 例えばこんなコマンドになります

```sh
scp ~/vivado/asobu/asobu02/asobu02.runs/impl_1/design_1_wrapper.bit xilinx@192.168.2.99:pynq/overlays/asobu02/asobu02.bit
scp ~/vivado/asobu/asobu02/asobu02.srcs/sources_1/bd/design_1/hw_handoff/design_1.hwh xilinx@192.168.2.99:pynq/overlays/asobu02/asobu02.hwh
```

## 2-5-2. jupyter で実行

- [手順 1-8-2. jupyter で実行](https://qiita.com/nishimuraatsushi/items/3e5f161eca4b2a0f06c8#1-8-2-jupyter-%E3%81%A7%E5%AE%9F%E8%A1%8C) を参考に実行します

<img width="500" alt="スクリーンショット 2020-08-04 19.43.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107797/91bb65ac-dd6c-8f36-1594-144bd113af9d.png">

```python:asobu02.ipynb
import pynq
fpga = pynq.Overlay('asobu02.bit')
# コンフィグレーション完了後、LED が点滅し始めるはずです
```