FPGAプログラミング大全Xilinx編第2版 実機テスト #3

FPGAに再入門しようと思いたち[FPGAプログラミング大全Xilinx編第2版](https://www.amazon.co.jp/FPGA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8-Xilinx%E7%B7%A8-%E7%AC%AC2%E7%89%88-%E5%B0%8F%E6%9E%97-%E5%84%AA/dp/4798063266/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1S5G3UKPB55O9&keywords=FPGA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8Xilinx%E7%B7%A8%E7%AC%AC2%E7%89%88&qid=1669893715&qu=eyJxc2MiOiIwLjc2IiwicXNhIjoiMC4wMCIsInFzcCI6IjAuMDAifQ%3D%3D&sprefix=fpga%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8xilinx%E7%B7%A8%E7%AC%AC2%E7%89%88%2Caps%2C151&sr=8-1)を頭からやっていく3日目

時期的にも良いので一人Advent Calendarで25日続ける

今日は[Digilent Artix-7 35T Arty FPGA 評価キット](https://japan.xilinx.com/products/boards-and-kits/arty.html#resources)で実際に動かす

### 目標
4004等の実CPUの実装

### 目次
| # | タイトル |
|:-:|:-:|
|   01|  [ツール導入](https://qiita.com/Gazyu/items/8f3797abf4ddc88ecacd) |
|  02 |  [実機テスト下準備](https://qiita.com/Gazyu/items/b59e0a1e023005bc02d5) |
|  03 |  実機テスト |
|04|未定|


### 環境
【実装ボード】 [Digilent Artix-7 35T Arty FPGA 評価キット](https://japan.xilinx.com/products/boards-and-kits/arty.html#resources)
【OS】 Windows10
【IDE】 Vivado 2022.2

### 今日のゴール
ボードのLEDを光らせる

### 今日の学び
FPGAプログラミング大全Xilinx編第2版はHDL(Verilog)は知ってる前提で話してくるのでそこは別の入門書を必要とする


今日は写経が多め

## 1. 制約ファイルの設定
1. 前回設定したXDC(制約ファイル)の書き換え
```xdc:.xdc
## This file is a general .xdc for the Arty A7-35 Rev. D and Rev. E
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project

## Clock signal
set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { CLK100MHZ }];

## Switches
#set_property -dict { PACKAGE_PIN A8    IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L12N_T1_MRCC_16 Sch=sw[0]
#set_property -dict { PACKAGE_PIN C11   IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L13P_T2_MRCC_16 Sch=sw[1]
#set_property -dict { PACKAGE_PIN C10   IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L13N_T2_MRCC_16 Sch=sw[2]
#set_property -dict { PACKAGE_PIN A10   IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L14P_T2_SRCC_16 Sch=sw[3]

## RGB LEDs
#set_property -dict { PACKAGE_PIN E1    IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L18N_T2_35 Sch=led0_b
#set_property -dict { PACKAGE_PIN F6    IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L19N_T3_VREF_35 Sch=led0_g
#set_property -dict { PACKAGE_PIN G6    IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L19P_T3_35 Sch=led0_r
#set_property -dict { PACKAGE_PIN G4    IOSTANDARD LVCMOS33 } [get_ports { led1_b }]; #IO_L20P_T3_35 Sch=led1_b
#set_property -dict { PACKAGE_PIN J4    IOSTANDARD LVCMOS33 } [get_ports { led1_g }]; #IO_L21P_T3_DQS_35 Sch=led1_g
#set_property -dict { PACKAGE_PIN G3    IOSTANDARD LVCMOS33 } [get_ports { led1_r }]; #IO_L20N_T3_35 Sch=led1_r
#set_property -dict { PACKAGE_PIN H4    IOSTANDARD LVCMOS33 } [get_ports { led2_b }]; #IO_L21N_T3_DQS_35 Sch=led2_b
#set_property -dict { PACKAGE_PIN J2    IOSTANDARD LVCMOS33 } [get_ports { led2_g }]; #IO_L22N_T3_35 Sch=led2_g
#set_property -dict { PACKAGE_PIN J3    IOSTANDARD LVCMOS33 } [get_ports { led2_r }]; #IO_L22P_T3_35 Sch=led2_r
#set_property -dict { PACKAGE_PIN K2    IOSTANDARD LVCMOS33 } [get_ports { led3_b }]; #IO_L23P_T3_35 Sch=led3_b
#set_property -dict { PACKAGE_PIN H6    IOSTANDARD LVCMOS33 } [get_ports { led3_g }]; #IO_L24P_T3_35 Sch=led3_g
#set_property -dict { PACKAGE_PIN K1    IOSTANDARD LVCMOS33 } [get_ports { led3_r }]; #IO_L23N_T3_35 Sch=led3_r

## LEDs
set_property -dict { PACKAGE_PIN H5    IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L24N_T3_35 Sch=led[4]
set_property -dict { PACKAGE_PIN J5    IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_25_35 Sch=led[5]
set_property -dict { PACKAGE_PIN T9    IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L24P_T3_A01_D17_14 Sch=led[6]
set_property -dict { PACKAGE_PIN T10   IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]
~~~~~以下略~~~~~
```
とりあえず、LEDを光らせたいだけなので単発LED周りのコメントを外す
今後のためにクロック周りも外す
行後半の *[get_ports { led[0] }];* の *led* 部分がHDLでの指定ワードとなるのでちゃんと覚えておく

**前回コピーで取り込まなかったのでこのファイルは前回展開して置いたファイルそのものなので後々注意すること**

## 2. HDLの記述
とりあえず左端から2番目のLEDを光らせるHDLを書く
これは全灯とか一番端だけみたいなのをすると偶然のなにかになる可能性を考慮して
本もDigilentもサンプルがVerilogなのでVerilogで
```HDL:LED_Test.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/12/02 22:34:10
// Design Name: 
// Module Name: LED_Test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module LED_Test(
    input   CLK100MHZ,
    output  reg [3:0]   led
    );
always @* begin
    led = 4'b0100;
end
endmodule

```
moduleの()内には1.で覚えてたワードを入れる

## 3. コンパイル
1. Vivadoの左側リストのGenarate Bitstreamをクリック
![スクリーンショット 2022-12-03 185009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/df56cc38-5e26-8665-fff0-f981e5495954.png)
1. Generate Config設定して実行
コンパイル時の設定ダイアログが出てくるのでとりあえずLaunch runs on local host:の数をCPUと同数にする
コンパイルのパラで走る数らしいのでCPUと同数が一番効率がいいらしい
![スクリーンショット 2022-12-03 185928.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/d2e25fb7-1112-4783-4f8a-8b6db9a6784a.png)
1. しばらくコンパイルを待つ
Intel(R) Core(TM) i9-9980HKで上記設定で2,3分ほど

1. コンパイル完了
コンパイル完了で次アクションダイアログが出てくるがとりあえずクローズする
![スクリーンショット 2022-12-03 190528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/e269d1f0-b67e-236a-d316-5f8adec61811.png)

1. ボード接続
![PXL_20221203_102459554_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/3f7e042a-06d5-88af-31a3-37686a0e96dc.jpeg)
PCとボードをUSBケーブルで接続
:::note warn
今回の作業中でここが一番苦労した
ボード側の端子がMicroUSBなのだが相性なのかなんなのか最初に用意したUSBケーブルだと次の手順で一瞬Vivadoから認識するのだがすぐに外れたことになってしまう
使用したUSBケーブルが他のデバイスでは問題なかったのでボードの初期不良を疑い色々と調べる羽目になってしまった
しかもボード上の電源LEDなどはつきっぱなしなので物理的な接続自体は問題なさそうに見えるという
最終的には手持ちの中で一番短く(30cm)品質もしっかりしてそうなケーブルを使用することでクリアした
:::

1. Vivadoでのボード認識
画面左のPROGURAM AND DEBUG -> Open Hardware Manager -> Open Targetをクリック
![スクリーンショット 2022-12-03 185009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/c8081a3f-9d46-f303-6fd0-226c4729e3ad.png)
Auto Connectで大体の場合には自動認識してもらえるはず
![スクリーンショット 2022-12-03 193613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/5846d0ad-e981-ed66-ad2d-9f2aa737c30c.png)
認識するとVivadoの表示が切り替わりHARDWARE MANAGER表示になる
![スクリーンショット 2022-12-03 195328.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/52d90746-2b1c-4065-2622-ca09aa82b8df.png)

1. FPGAへのプログラム
画面上部の *Program Device* をクリックするとプログラムダイアログが出るのでBitstream fileがそれっぽいことを確認してProgramボタンを押す
![スクリーンショット 2022-12-03 195542.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/70e6a619-bdd5-211d-24e0-89ac7238f62f.png)

1. 結果
before
![PXL_20221203_105805567_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/77e222b3-3583-38f0-4e83-237d537d88f9.jpeg)
after
![PXL_20221203_105822896_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/8f5bbf3a-5185-544e-5583-62dc922b2e31.jpeg)
左下の左から2番目のLEDが光ればOK

今日はここまで