「車輪の再実装」って言葉が好き(実践はできてない)

Vivado入門1(CPU実験その1)

この記事は IS17er Advent Calendar 2017 - Adventarの1日目の記事として書かれました。  

CPU実験とは

東大理学部情報科学科では名物講義のひとつにCPU実験というものがあります。

CPU実験の説明は歴代の先輩方が様々説明を書いてくださっているので説明は割愛します。

Redirecting…
CPU実験2016年度D班コア係(CPU実験でマルチコア) - sueki743's blog
adventar.org

なぜVivado入門なのか

CPU実験ではFPGAを使ってCPUを作ります。

その際に用いるボードが昨年度からXilinx社製のものに更新され 、その統合開発環境であるVivadoに悩まされたので、本記事を書くことにしました。

各種バージョン

  • IDE :Vivado v2016.4(64bit) Ubuntu

  • ボード: Xilinx社製Kintex Ultrascale(KCU105)

 

今回やること

LEDをチカチカさせよう!!

  • Vivadoプロジェクトの作成
  • IPインテグレーター(ブロックデザイン)及びIPコアの使用*1
  • クロックの生成
  • LEDの使用*2
  • 合成(シンセサイズ)、配置配線(インプリメンテーション)、及びビットストリームの生成*3
  • FPGAボードのコンフィギュレーション*4

Vivadoプロジェクトの作成

f:id:progrunner17:20171201223735p:plain

 Vivadoを起動すると以下のようなウィンドウが表示されるので、
まずはプロジェクトを作成します。

f:id:progrunner17:20171201155144p:plain プロジェクト名とプロジェクトの保存場所を指定します.
この時 Create project subdirectoryのチェックを外すと指定したフォルダにVivadoが生成する大量のファイルが広がることになるので、外さないことを推奨します。

f:id:progrunner17:20171201223658p:plain

プロジェクトの種類を指定します。
ここでは基本的なプロジェクトであるRTL Projectを選択してください。 Do not specify sources at this timeのチェックを外すと使用するソースファイルを指定できますが、後から指定できるのでチェックをつけたままにしてください。

f:id:progrunner17:20171201223714p:plain
Boardsタブから使用するFPGAボードを指定します。 *5

これで設定は終わりです。最後に確認ウィンドウが表示されるのでfinishを選択するとプロジェクトが生成されます。

f:id:progrunner17:20171201224058p:plain

プロジェクトができました。

IPインテグレーター(ブロックデザイン)の使用

f:id:progrunner17:20171201224118p:plain
Vivadoには様々な機能がありますが、ウィンドウ左側に表示されているFlow Navigatorに表示されているコマンドを上から下に実行して行くことがプロジェクトの基本的な流れになります。

まずはじめに、Create Block Design*6を実行してください。 f:id:progrunner17:20171201225436p:plain
プロジェクト名は基本的にデフォルトで大丈夫なのですが、今回はtest_block_designと名付けました。

f:id:progrunner17:20171201225700p:plain

こんな感じでブロックデザインが生成されます。

クロックの生成

f:id:progrunner17:20171201225910p:plain
画面中央にあるboard タブからsystem differential clockのいづれかをドラック&ドロップでブロックデザインに追加します。*7

f:id:progrunner17:20171201230117p:plain

これでクロックを生成するIPコア(Clocking Wizard)が生成されました
クロック周波数はデフォルトで100MHzに設定されています。

IPコアの使用

さて、今回の目標であるLチカのためにはクロックの周波数は速すぎて人の目に追えません。
そこでバイナリカウンターを用いていい感じに遅い周波数を取り出したいと思います。
verilog等で直接書いてもいいですが、今回はXilinxが提供しているモジュール(IPコア)を使用したいと思います。

f:id:progrunner17:20171201230321p:plain

IPコアは右クリックかブロックデザインサイドバーから追加できます。 検索ウィンドウにbinaryと入力すればバイナリカウンターが見つかると思うので追加してください。

f:id:progrunner17:20171201231045p:plain

追加できたら上記のようにドラッグしてバイナリカウンターにクロックをつなげてください。

f:id:progrunner17:20171201231310p:plain デフォルトでは0~216-1までカウントできますが、これでもまだ速すぎるのでバイナリカウンターをクリックして設定ウィンドウ開いてIPコアに変更を加えます。

f:id:progrunner17:20171201231544p:plain とりあえず28bit分くらい使えば228/100MHz > 1Hzとなりいい感じでチカチカが見えると思います。

LEDの使用(物理制約及びポートの使用)

それではLEDに繋がるポートを追加します。
ブロックデザイン上で右クリックしてポートの追加を選択してください. f:id:progrunner17:20171201231758p:plain

今回使用するKCU105のボードにはユーザー用に8個のLEDがあるので上記のように設定してください。

f:id:progrunner17:20171201231904p:plain

led用のポートが生成されました。 ただ、このままではバイナリカウンターの出力が28bitに対しledの入力が8bitなのでsliceと呼ばれるIPコアを追加して出力の一部を取り出します。

f:id:progrunner17:20171201232057p:plain

上記のように設定してください。

f:id:progrunner17:20171201232243p:plain

こんな感じに各モジュールを繋いでブロックデザイン上部にあるrun connection automationを実行してブロックデザインでの基本的な作業は終了です 。

ソースファイル(制約)の追加

先ほどブロックデザインに追加したledポートですがこのままでは実際のLEDに紐付けされていないので使用できません。 それを解決するために制約ファイルと呼ばれるファイルを追加してポートを指定します。 Flow Navigator(左サイドバー)からadd sources を実行してください。

f:id:progrunner17:20171201232906p:plain

add or crate constraints をチェックしてください。

f:id:progrunner17:20171201233000p:plain

create fileを選択し制約ファイルを作ります。 ここでの制約ファイル名は特に重要ではないですが今回はled.xdc*8とします。

f:id:progrunner17:20171201233024p:plain

制約ファイルを追加したらウィンドウ中央からled.xdcをダブルクリックしてテキストエディタを開き下記の設定項目を入力してください。*9

set_property PACKAGE_PIN AP8 [get_ports "led[0]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[0]"]
set_property PACKAGE_PIN H23 [get_ports "led[1]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[1]"]
set_property PACKAGE_PIN P20 [get_ports "led[2]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[2]"]
set_property PACKAGE_PIN P21 [get_ports "led[3]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[3]"]
set_property PACKAGE_PIN N22 [get_ports "led[4]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[4]"]
set_property PACKAGE_PIN M22 [get_ports "led[5]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[5]"]
set_property PACKAGE_PIN R23 [get_ports "led[6]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[6]"]
set_property PACKAGE_PIN P23 [get_ports "led[7]"]
set_property IOSTANDARD LVCMOS18 [get_ports "led[7]"]

これで制約ファイルがの設定が終わりました。

HDLwrapperの生成

f:id:progrunner17:20171201233325p:plain

最後に、ウィンドウ中央のSources - Hierarchyタブを開きブロックデザインを右クリックしてcreat HDL wrapper を実行してください。

合成、配置配線及びビットストリームの生成

FPGAに書き込むために合成、配置配線及びビットストリームの生成*10を行います。

f:id:progrunner17:20171201233705p:plain

Flow Navigatorから run synthesizeを実行

f:id:progrunner17:20171201234009p:plain

しばらく待つとこの様なポップアップが現れるのでrun implementation を実行します。

f:id:progrunner17:20171201234409p:plain

generate bitstreamを実行
これでFPGAに書き込むファイルが生成できました。

f:id:progrunner17:20171201234435p:plain

ボードに電源をつなぎ、JTAGポートとPCをマイクロusbケーブルでつなぎFlownavigatorからハードウェアマネージャーを開き auto connectを行うとPCとFPGAが繋がります。 右クリックでprogram deviceを実行するとこんな感じでLEDがチカチカ光り始めるはずです。

f:id:progrunner17:20171201235140g:plain

最後に

もしやる気があれば次はBlock memoryやverilogなどの使い方を書きます。

*1:今回はclock wizard,binary counter, sliceを用いた

*2:ポート及び物理制約の使用

*3:要はFPGAボードへ書き込む準備

*4:実際にFPGAに書き込みを行うこと

*5:おそらく基本設定でボードを指定するとこの選択ができるようになると思うのですが、その設定方法を知らないので割愛します。

*6:ブロクデザインはGUIを使用した設計ツールです

*7:clocking wizardもIPコアの一つなのでadd IPから追加することも可能ですが、この方法で追加することで制約ファイルを自分で書くことなくクロックを簡単に生成することができます。

*8:xdcは制約ファイルの拡張子

*9:制約ファイルの物理制約はボード毎に異なりますKCU105の場合このリンクのPDFの末尾の方に設定例が乗っています。

*10:かなり適当に例えると推論、リンク、コンパイルみたいな感覚です。