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


動作環境
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 (160000000 では失敗した)
  • 以下のように接続する
    • 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選択

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

  • 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) を展開表示する

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

  • 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でカウントアップしていく。

未消化だった事項

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倍になるようだ。