2016-07-23 ZYBO / IP > Clock Counter + LED表示 > IP作成したClock Divider + Clock Counterを使ってカウントアップのLED表示してみた

```txt:動作環境
Vivado 2015.4 on Windows 8.1 pro (64bit)
DIGILENT ZYBO
```

## 概要

やろうとしていること

Clock DividerとClock Counterを使って、カウントアップしていく値をLEDで表示する。

Clock Counterには以下の2つの入力が必要

- Clock
- Reset

ZYBOのPLから操作できるLEDは4つある。4ビットのカウンタの表示として使える。

Clockにはある特定のクロックを入れ、Resetにはその16倍の周期のクロックを入れることで、4bitのLEDカウンタができると思われる。
(追記: 16倍でなく32倍が必要だと後でわかった。)

## 使用IP

### Clock Divider IP

http://qiita.com/7of9/items/0687d2cffc470b83d38c
にて作成したIP

### Clock Counter IP

http://qiita.com/7of9/items/b669e37d52721273c923
をベースにIPを作成する。

プロジェクト名は以下とし、C:\ZyboDev以下で作成した。

- 160723_ipCounter

```
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter is
port(   Clk : in std_logic;
        Reset : in std_logic;
        OUT_D : out std_logic_vector (3 downto 0)
        );
end counter;

architecture Behavior of counter is
signal DFF_4 : std_logic_vector (3 downto 0);

begin

process(Clk, Reset)
begin
    OUT_D <= DFF_4;
    if (Reset = '1') then
        DFF_4 <= (others => '0');
    elsif ( clk'event and clk = '1') then    
        if (DFF_4 = "1111") then
            DFF_4 <= (others => '0');
        end if;
        DFF_4 <= DFF_4 + 1;
    end if;
end process;
end Behavior;
```


#### IPの作成

上記のVHDL実装からIPを作成する。

- Tool > Create and Package IP ...
  - Create and Package New IPウィンドウが表示される
- Nextを押す
- Package your current projectを選択し、Nextを押す
- IP locationはそのまま、Include .xci filesを選択し、Nextを押す
  - 再作成時は上書きするか聞かれるので、Overwriteを選択する
- Finishを押す
  - Package IP _ counterというタブが表示される
- 以下の部分を変更する (名前は任意)
  - Name: myIP_clockCounter
  - Version: 1.0
  - Display name: myIP_clockCounter_v1_0
  - Descriptoin: myIP_clockCounter_v1_0
- Review and PackageにてPackage IPを押す

以上でIPが作成され、関連ファイルが以下のフォルダに用意される。

- c:/ZyboDev/160723_ipCounter/160723_ipCounter.srcs


## IPの使用

### on Vivado


- プロジェクトを作成する。名前は 160723_useClockCounter とした
- RTL Project
  - Do not specify sources at this time
- Board: ZYBOで作成
- Create Block Design
  - Design name: design_1
- Add IP: ZYNQ7 Processing System
- Run Block Automation
  - デフォルトのままOKを押す
- FCLK_CLK0のピンをM_AXI_GP0_ACLKのピンへ左クリックで接続
- Tool > Project Settings > IPメニュー > Repository Managerタグ
  - ＋マークを押して、前述で作成したIPの場所 ( C:\ZyboDev\160716_ClockDivider\160716_ClockDivider.srcs )を選択して追加
  - Add Repositoryウィンドウが表示される
  - Applyを押して、OKを押す
  - ＋マークを押して、前述で作成したIPの場所 ( C:/ZyboDev/160723_ipCounter/160723_ipCounter.srcs )を選択して追加
  - Add Repositoryウィンドウが表示される
  - Applyを押して、OKを押す
- ClockCounter入力用のClkのため以下をする
  - Add IPでmyをキーワードとして検索する。myIP_clockDiv_v1_0が見つかるのでaddする
  - Add IPでConstantを追加する (xlconstant_0になる)
- ClockCounter入力用のResetのため以下をする
  - Add IPでmyをキーワードとして検索する。myIP_clockDiv_v1_0が見つかるのでaddする
  - Add IPでConstantを追加する (xlconstant_1になる)
- xlconstant_0をダブルクリックして以下の設定とする
  - Const Width: 29 (clockDividerのVHDL実装に合わせる)
  - Const Val: 10000000
- xlconstant_1をダブルクリックして以下の設定とする
  - Const Width: 29 (clockDividerのVHDL実装に合わせる)
  - Const Val: 320000000 (<font color=red>160000000 では失敗した</font>)
- 以下のように接続する
  - myIP_clockDiv_0のClk <--> ZYNQのFCLK_CLK0
  - myIP_clockDiv_0のdivide_value[28:0] <--> xlconstant_0のdout[28:0]
  - myIP_clockDiv_1のClk <--> ZYNQのFCLK_CLK0
  - myIP_clockDiv_1のdivide_value[28:0] <--> xlconstant_1のdout[28:0]
- ClockCounterを追加するため以下をする
  - Add IPでmyをキーワードとして検索する。myIP_clockCounter_v1_0が見つかるのでaddする
- 以下の接続をする
  - myIP_clockDiv_0のClk_mod <--> myIP_clockCounter_0のClk
  - myIP_clockDiv_1のClk_mod <--> myIP_clockCounter_0のReset

- myIP_clockCounter_0のOUT_D[3:0]上にて右クリック、Make External選択

以上で以下のブロック図ができている。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/9121ae13-5fc1-3fdf-02a6-8e2712603fa9.png)

- Sourcesタブ > design_1.bd上で右クリック、Create HDL Wrappterを選択
  - Let Vivado manager wrapper and auto-update
- Sourcesタブ > Constraints > constrs_1上で右クリック、Add Sources > Add or create constraitsを選択、Nextを押す
  - Create File
  - File name: useClockCounter.xdc
  - Finish
- Run Implementation
 - Save Proejct: Saveを押す
- Open Implementation Design
 - I/O Portsタブを選択し、OUT_D(4) を展開表示する

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/1734a983-97b1-09f8-ef24-875f9cb35f7e.png)

OUT_D(4)に表示したいLEDを指定する。
http://qiita.com/7of9/items/9f35a6b14f4898690237
を参考に以下のようにした

- OUT_D[3] > Site:D18 / Fxied: チェック / I/O Std:LVCMOS33
- OUT_D[2] > Site:G14 / Fxied: チェック / I/O Std:LVCMOS33
- OUT_D[1] > Site:M15 / Fxied: チェック / I/O Std:LVCMOS33
- OUT_D[0] > Site:M14 / Fxied: チェック / I/O Std:LVCMOS33

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/9ac0640e-9f9c-7b58-7bb8-86cd74eb8795.png)


- Ctrl+Sで保存する
  - Save Constraintsウィンドウにて Select an existing file: useClockDiv.xdc を選択しOK
- Generate Bit Stream
- File > Export > Export Hardware...
  - Include bitstreamチェックしてOKクリック
- File > Launch SDK
  - OKクリック


## on XSDK

XSDK上では特にやることはない。
上記の実装で4つのLEDがカウントアップ点灯するようになっているので、Hello Wolrdのアプリを実装して実行をすればいい。


- File > New > Application Project
  - Project name: clockCounter
  - Nextクリック
  - Hellow Worldを選択してFinish
- メニュー Xilinx Tools > Program FPGA > Programを押す
- Project ExplorerのclockCounter > Binaries > clockCounter.elf上で右クリックして、Run As > 1. Launch on Hardware (System Debugger)で実行する

以上でZYBOのLD3からLD1までが0.1Hzでカウントアップしていく。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/8d448a2d-cb90-ce21-d229-bd37dae34400.png)

## 未消化だった事項

Resetの分周はClk入力の分周の16倍であれば4ビットのMSBまで点灯するかと思っていた。
以下のValを160000000 にすると4つあるうちのLEDのMSBが点灯せずにリセットがかかる。

```
- xlconstant_1をダブルクリックして以下の設定とする
  - Const Width: 29 (clockDividerのVHDL実装に合わせる)
  - Const Val: 320000000 (<font color=red>160000000 では失敗した</font>)
```

~~タイミング的に何か勘違いしているのかもしれない。~~

Run Simulationで確認した。
ResetピンがLレベルの間に4ビットの処理が実行されないといけないので分周は16倍でなく32倍になるようだ。

http://qiita.com/7of9/items/756e5ffd9eca884dd61e