FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Vivado HLS 2015.4を試す (チュートリアル Lab.1)

Vivado 2015.4 HLSでは、遂にHLSの機能が無償化されたらしい! 今まで触ってみたいと思いつつ、期限付きの評価ライセンスはきちんと使い切れる自信が無かったりて、申請していなかったので、今回の無償化は非常に嬉しい。さっそく試してみよう。

http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2015_4/ug973-vivado-release-notes-install-license.pdf

Vivado®DesignSuite2015.4リリースから、高位合成ツールであるVivadoHLSが無償で提供されるようになり、Vivado
のすべてのエディションに含まれるようになりました。この変更を示すため、エディションの名前はVivadoDesign
SuiteHLxEditionに変更されています。HLxEditionには、HLSystemEdition、HLDesignEdition、およびHLWebPACK™
Editionがあります。これらのエディションでは、AllProgrammableFPGA、SoC、および再利用可能なプラットフォー
ムを高い生産性で設計するための新しい手法がイネーブルになっています。すべてのHLxエディションにはVivado
高位合成(HLS)、VivadoIPインテグレーター、LogicCoreIPサブシステム、およびVivadoインプリメンテーション
ツールスイートすべてが含まれており、生産性が高く、高度なCおよびIPベースのデザインフローを即座に導入で
きるようになっています。

Lab1. FIRフィルタの高位合成を試してみる

Vivado 2015.4 HLSの起動画面はこんな感じだ。

f:id:msyksphinz:20151126225551p:plain

2014年のチュートリアルだが、一つ一つ試していこう。使ったのは以下のチュートリアル

http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_2/ug871-vivado-high-level-synthesis-tutorial.pdf

まずは言われるがままに、Lab1の、firのプロジェクトからHDLの生成を試してみる。 ただし、利用するボードを選択する所では、所持しているZedBoardを選択した。

f:id:msyksphinz:20151126230038p:plain

ちなみに元になっているfir.cだが、まあC言語っぽいとは言え、多少はHDL生成用にキーワードが入っている。 テストベンチであるfir_test.cは、まるっきりC言語という感じだ。

C言語によるシミュレーション

[Project]→[Run C Simulation]を選択すると、どうやらバイナリが生成され、シミュレーションが実行される。

f:id:msyksphinz:20151126230432p:plain

このバイナリ、生成オプションは良く分からないが、

   Compiling(apcc) ../../../../../lab1/fir_test.c in debug mode
@I [HLS-10] Running 'c:/Xilinx/Vivado_HLS/2015.4/bin/unwrapped/win64.o/apcc.exe'
            for user 'masayuki' on host 'fixedesk' (Windows NT_amd64 version 6.1) on Thu Nov 26 23:01:45 +0900 2015
            in directory 'C:/usr/work/vivado_hls/ug871-design-files/Vivado_HLS_Tutorial/Introduction/lab1_work/fir/solution1/csim/build'
@I [APCC-3] Tmp directory is apcc_db
@I [APCC-1] APCC is done.
   Compiling(apcc) ../../../../../lab1/fir.c in debug mode
@I [HLS-10] Running 'c:/Xilinx/Vivado_HLS/2015.4/bin/unwrapped/win64.o/apcc.exe'
            for user 'masayuki' on host 'fixedesk' (Windows NT_amd64 version 6.1) on Thu Nov 26 23:01:52 +0900 2015
            in directory 'C:/usr/work/vivado_hls/ug871-design-files/Vivado_HLS_Tutorial/Introduction/lab1_work/fir/solution1/csim/build'
@I [APCC-3] Tmp directory is apcc_db
@I [APCC-1] APCC is done.

APCCという謎なツールが動作しているね。最初はC言語によるシミュレーションだから,GCCとかが動いているのかと思ったけど、良く考えるとC言語以外のHDL生成用プリミティブも入っているからそうは行かないのか。 じゃあこれ、GCCとかで一般的に利用されているライブラリとかは、どこまで使えるんだろうね?

csim.exeというものが生成されており、これを実行することでシミュレーションとしている。

合成する

[Solution]→[Run C Synthesis]→[Active Solution]で合成が始まる。この規模だと、7秒くらいで終了した。

f:id:msyksphinz:20151126231311p:plain

でも、この規模を7秒でHDL生成してしまうというのは凄いな。生産性については物凄く上がりそうだ。 ただし、HDLソースをちらっと覗いてみると、必ずしも分かりやすいソースコードにはなっていないと感じた。ちょっとHDLの状態でのデバッグは厳しそうだ。。。

RTLとC言語のコシミュレーション

生成されたRTLのコードと、C言語のテストパタンを複合させて検証を走らせるらしい。チュートリアルの説明には、以下のように説明されている。

  • The C test bench generates input vectors for the RTL design.
  • The RTL design is simulated.
  • The output vectors from the RTL are applied back into the C test bench and the results-checking in the test bench verify whether or not the results are correct.

一旦C言語のテストベンチをRTLに変換?というかRTLのテストベクタを生成すると書いてあるが、詳細は分からない。普通にRTLを走らせて、その結果を再度C言語のテストベンチにフィードバックすると書いてある。 単純に考えた場合、そんなことしなくてもDPI-Cとかで接続すればいいんじゃないのと思うのだが、そうも行かないのかな(複雑そうだしな)

f:id:msyksphinz:20151126231926p:plain

IPの生成

xprを生成する。[Solution]→[Export RTL]を選択する。

f:id:msyksphinz:20151126232025p:plain

IPカタログを生成することで、Vivadoの方でも使えるようになるのかな?とりあえずこれでチュートリアルのLab.1は終了。

Vivado 2015.3の新機能であるCore Containerについて調査

今さらながらVivado 2015.3 をインストールして、IP Managerを立ち上げてみると、Core Containerという新機能が追加されていた。

Core Containerは、IPマネージャで管理されている各IPを、1つのファイルで管理できるようになるという構造だ。これまで複数のファイルにディレクトリとして別れていたものが、一つのxcixというファイルで管理されるようになり、バージョン管理システムでも扱いやすくなる。

http://www.xilinx.com/support/documentation/sw_manuals/xilinx2015_3/ug896-vivado-ip.pdf

実際、Vivado 2015.3より前に作っていたIPを 2015.3のIP Managerで開くと、バージョンアップとCore Containerの変換の確認メッセージが表示された。 また、IPのメニューでも「Enabel Core Container」を選択することで既存のIPをCore Container形式に変換することができる。

f:id:msyksphinz:20151115195830p:plain

実際にやってみると、これまで各IPでディレクトリが作成されていたものが、xcixというファイルに統一されるようになった。

もちろん、Generate Output Filesを選択することにより、これまで通りシミュレーションや合成用のファイルを作成することができる。

github.com

こちらにもXilinxのトレーニングビデオがある。こちらの英語は比較的易しいのでおすすめ。

Xilinx® トレーニング : IP 用 Core Container の使用

これでディレクトリ構造を変更すると、基本IPの設定を埋め込んだファイルは<IPファイル名>.xcixにまとめられ、それ以外の生成ファイルは、ip_user_filesに作成される。 treeで表示するとこんな感じだ。L2から下は切り取っているが、ちゃんと下の方にはシミュレーションファイルなども生成されている。

tree . -L 2
.
├── axi_dram_128bit.xcix
├── ip_user_files
│   ├── ip
│   ├── ipstatic
│   ├── mem_init_files
│   ├── README.txt
│   └── sim_scripts
├── managed_ip_project
│   ├── managed_ip_project.cache
│   ├── managed_ip_project.hw
│   ├── managed_ip_project.runs
│   ├── managed_ip_project.sim
│   └── managed_ip_project.xpr
├── pulsar1_connect.xcix
└── README.md

ip_user_files/ip/axi_dram_128bit/axi_dram_128bit_sim_netlist.v
ip_user_files/ip/pulsar1_connect/pulsar1_connect_sim_netlist.v

このように、<IP名_sim_netlist.v>というファイルがシミュレーションファイルだ。 これに登録名を変えて、シミュレーション環境を再構築してみよう。

Vivado 2015.2ではZedBoardのHello Worldがビルドできない

Vivado 2015.2 をダウンロードして、ZedBoardをちょっとやり直そうと思い、CTTのHello Worldを実行しようとすると、ビルドエラーが発生した。

http://forums.xilinx.com/xlnx/attachments/xlnx/ELINUX/8467/1/zedboard_CTT_v2013_2_130807.pdf

もともとVivado 2013をターゲットとした資料だが、Hello Worldが全然ビルドできないというのは頂けないなあ。

SDK 2015.2を立ち上げて、Hello_Worldをビルドしようとするとエラーが発生する。

環境はWindows 8.1 64bitだ。

02:20:23 **** Incremental Build of configuration Debug for project Hello_World ****
make all 
'Building file: ../src/helloworld.c'
'Invoking: ARM gcc compiler'
arm-xilinx-eabi-gcc -Wall -O0 -g3 -c -fmessage-length=0 -MT"src/helloworld.o" -I../../Hello_World_bsp/ps7_cortexa9_0/include -MMD -MP -MF"src/helloworld.d" -MT"src/helloworld.d" -o "src/helloworld.o" "../src/helloworld.c"
'Finished building: ../src/helloworld.c'
' '
'Building file: ../src/platform.c'
'Invoking: ARM gcc compiler'
arm-xilinx-eabi-gcc -Wall -O0 -g3 -c -fmessage-length=0 -MT"src/platform.o" -I../../Hello_World_bsp/ps7_cortexa9_0/include -MMD -MP -MF"src/platform.d" -MT"src/platform.d" -o "src/platform.o" "../src/platform.c"
'Finished building: ../src/platform.c'
' '
'Building target: Hello_World.elf'
'Invoking: ARM gcc linker'
arm-xilinx-eabi-gcc -Wl,-T -Wl,../src/lscript.ld -L../../Hello_World_bsp/ps7_cortexa9_0/lib -o "Hello_World.elf"  ./src/helloworld.o ./src/platform.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
c:/xilinx/sdk/2015.2/gnu/arm/nt/bin/../lib/gcc/arm-xilinx-eabi/4.9.1/../../../../arm-xilinx-eabi/bin/ld.exe: warning: cannot find entry symbol _vector_table; defaulting to 00000000
./src/helloworld.o: In function `main':
C:\usr\zynq\2015.2\project_1\project_1.sdk\Hello_World\Debug/../src/helloworld.c:57: undefined reference to `print'
./src/platform.o: In function `disable_caches':
C:\usr\zynq\2015.2\project_1\project_1.sdk\Hello_World\Debug/../src/platform.c:69: undefined reference to `Xil_DCacheDisable'
C:\usr\zynq\2015.2\project_1\project_1.sdk\Hello_World\Debug/../src/platform.c:70: undefined reference to `Xil_ICacheDisable'
collect2.exe: error: ld returned 1 exit status
make: *** [Hello_World.elf] エラー 1

02:20:27 Build Finished (took 3s.553ms)

XilinxのプリミティブのprintとXil_DcacheDisable, Xil_ICacheDisableを持っていないらしい。何故だ? Vivado 2014.4だと、同一設定でビルドできたので、違いを調査する。

なんか2つのHello_Worldプロジェクト内のディレクトリの違いを調査していると、 .metadata/.logに怪しげな違いが存在している。

...
!ENTRY org.eclipse.cdt.core 4 0 2015-07-18 18:19:37.051
!MESSAGE Error
!STACK 0
java.lang.NullPointerException
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer.processLine(ConsoleOutputSniffer.java:178)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer.access$0(ConsoleOutputSniffer.java:174)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer$ConsoleOutputStream.checkLine(ConsoleOutputSniffer.java:99)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer$ConsoleOutputStream.write(ConsoleOutputSniffer.java:58)
    at java.io.OutputStream.write(Unknown Source)
    at org.eclipse.cdt.internal.core.ProcessClosure$ReaderThread.run(ProcessClosure.java:57)

!ENTRY org.eclipse.cdt.core 4 0 2015-07-18 18:19:37.065
!MESSAGE Error
!STACK 0
java.lang.NullPointerException
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer.processLine(ConsoleOutputSniffer.java:178)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer.access$0(ConsoleOutputSniffer.java:174)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer$ConsoleOutputStream.checkLine(ConsoleOutputSniffer.java:99)
    at org.eclipse.cdt.internal.core.ConsoleOutputSniffer$ConsoleOutputStream.write(ConsoleOutputSniffer.java:58)
    at java.io.OutputStream.write(Unknown Source)
    at org.eclipse.cdt.internal.core.ProcessClosure$ReaderThread.run(ProcessClosure.java:57)

!ENTRY org.eclipse.cdt.core 1 0 2015-07-18 18:19:37.787
!MESSAGE Indexed 'Hello_World_bsp' (81 sources, 54 headers) in 4.02 sec: 2,480 declarations; 12,593 references; 44 unresolved inclusions; 3 syntax errors; 50 unresolved names (0.33%)
...

JavaでNullPointerExceptionが発生している?Vivado 2015.2はまだ信用ならないなあ。。。

Zynq用Yocto-LinuxをビルドするためのVagrantfileとchef

ビルドが失敗する理由はタイムアウトが短かすぎるせいだった。 修正方法をに記載しました。

msyksphinz.hatenablog.com

Yocto-Linuxってビルドするのに手順が多くて、良く忘れてしまう。 そして、一度ビルドするとその方法ってそうそう変わらないので、こういうものこそVagrantで仮想化した環境を持っておいて、Chefで形式化してしまおう。

Vagrant上のLinuxからSD-Cardにアクセスできるようにする。

通常の方法では、Vagrant上のUbuntuは、SDカードを認識できるようにはなっていない。 まず、VirtualBoxでUSBデバイスがどのように認識されているのか調査した。これにはVBoxManage.exeを使う。

$ VBoxManage.exe list help
Oracle VM VirtualBox Command Line Management Interface Version 4.3.28
(C) 2005-2015 Oracle Corporation
All rights reserved.

Usage:

VBoxManage list [--long|-l] vms|runningvms|ostypes|hostdvds|hostfloppies|
                            intnets|bridgedifs|hostonlyifs|natnets|dhcpservers|
                            hostinfo|hostcpuids|hddbackends|hdds|dvds|floppies|
                            usbhost|usbfilters|systemproperties|extpacks|
                            groups|webcams


Syntax error: Unknown subcommand "help".

という訳で、

$ VBoxManage.exe list usbhost
Host USB Devices:

UUID:               9648dad6-7ae6-416a-a1ce-ef206fc9d9ee
VendorId:           0x046d (046D)
ProductId:          0xc531 (C531)
Revision:           33.0 (3300)
Port:               0
USB version/speed:  2/2
Manufacturer:       Logitech
Product:            USB Receiver
Address:            {36fc9e60-c465-11cf-8056-444553540000}\0039
Current State:      Busy

UUID:               fe977f7f-734f-489f-946f-95a935d3dd35
VendorId:           0x05ac (05AC)
ProductId:          0x12a8 (12A8)
Revision:           6.1 (0601)
Port:               0
USB version/speed:  2/2
Manufacturer:       Apple Inc.
Product:            iPhone
SerialNumber:       06180e666d3694d6f8a23cd64e143b750e302ed1
Address:            {36fc9e60-c465-11cf-8056-444553540000}\0034
Current State:      Busy

UUID:               66eaba18-222c-4016-a208-28dfb36530ad
VendorId:           0x1307 (1307)
ProductId:          0x0310 (0310)
Revision:           1.0 (0100)
Port:               0
USB version/speed:  2/2
Manufacturer:       Generic
Product:            Mass Storage Device
Address:            {36fc9e60-c465-11cf-8056-444553540000}\0009
Current State:      Captured

UUID:               f24b2cca-9e0b-4714-8e10-d05b54f31dae
VendorId:           0x1307 (1307)
ProductId:          0x0310 (0310)
Revision:           1.0 (0100)
Port:               0
USB version/speed:  2/2
Manufacturer:       Generic
Product:            Mass Storage Device
SerialNumber:       00000000000006
Address:            \\?\usb#vid_80ee&pid_cafe#00000000000006#{00873fdf-cafe-80ee-aa5e-00c04fb1720b}
Current State:      Captured

UUID:               e883a1e6-c723-4e61-88a8-49088013cb0b
VendorId:           0x17ef (17EF)
ProductId:          0x6047 (6047)
Revision:           3.0 (0300)
Port:               0
USB version/speed:  2/2
Manufacturer:       Lenovo
Product:            ThinkPad Compact USB Keyboard with TrackPoint
Address:            {36fc9e60-c465-11cf-8056-444553540000}\0037
Current State:      Busy

UUID:               84f6a207-0345-4c13-98f5-1ae265fdc670
VendorId:           0x21ee (21EE)
ProductId:          0x1100 (1100)
Revision:           3.145 (03145)
Port:               0
USB version/speed:  2/2
Manufacturer:       Broadcom Corp
Product:            Broadcom Bluetooth V3.0 USB Device
SerialNumber:       0009DD40680B
Address:            {e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\0000
Current State:      Busy

おお、いろいろ出て来た。 まず注目すべきは、USB接続のSDカードアダプタ、そして、SDカードそのものだ。

UUID:               66eaba18-222c-4016-a208-28dfb36530ad
VendorId:           0x1307 (1307)
ProductId:          0x0310 (0310)
Revision:           1.0 (0100)
Port:               0
USB version/speed:  2/2
Manufacturer:       Generic
Product:            Mass Storage Device
Address:            {36fc9e60-c465-11cf-8056-444553540000}\0009
Current State:      Captured

f:id:msyksphinz:20150720102944j:plain

このうち、SDカードの情報をVagrantfileに追加すれば、USBデバイスとして認識できるらしい。やってみよう。

github.com

    vb.customize ['modifyvm', :id, '--usb', 'on']

    vb.customize ['usbfilter', 'add', '1',
                  '--target', :id,
                  '--name', 'Any mass storage',
                  '--manufacturer', 'Generic',
                  '--product', 'Mass Storage Device']

これで、vagrant upすると、SDカードがデバイスとして認識されている。

$ lsusb
Bus 001 Device 002: ID 1307:0310 Transcend Information, Inc. SD/MicroSD CardReader [hama]
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0    40G  0 disk
└─sda1   8:1    0    40G  0 part /
sdc      8:32   1   3.7G  0 disk
└─sdc1   8:33   1   3.7G  0 part

Chefを使ってYocto-Linuxをビルドする

結局は、以下の書籍に書いてあることをrecipeとして記述するだけだ。

FPGAマガジンNo.5 Linux/Android×FPGA

FPGAマガジンNo.5 Linux/Android×FPGA

github.com

Chef化するにあたって迷ったところ。

bitbake を実行するのだが、この時にRootユーザであってはならないらしい。従って、Chefにはユーザ名を指定している。

git "/home/vagrant/poky/meta-xilinx" do
  user "vagrant"
  repository "git://git.yoctoproject.org/meta-xilinx"
  revision "master"
  enable_submodules true
  action :sync
end

ときどきビルドが失敗する

時々、Sigtermを出して失敗する。その場合は、何度か vagrant provision を繰替えせば、最終的にビルドが実行できるようになる。

==> default: NOTE: recipe gettext-native-0.19.4-r0: task do_patch: Succeeded
==> default: NOTE: Running task 260 of 2265 (ID: 574, virtual:native:/home/vagrant/poky/meta/recipes-core/gettext/gettext_0.19.4.bb, do_configure)
==> default: NOTE: recipe gettext-native-0.19.4-r0: task do_configure: Started
==> default: STDERR: ERROR: UI received SIGTERM
==> default: Traceback (most recent call last):
==> default:   File "/home/vagrant/poky/bitbake/bin/bitbake", line 45, in <module>
==> default:     cookerdata.CookerConfiguration()))
==> default:   File "/home/vagrant/poky/bitbake/lib/bb/main.py", line 384, in bitbake_main
==> default:     server_connection.terminate()
==> default:   File "/home/vagrant/poky/bitbake/lib/bb/server/process.py", line 189, in terminate
==> default:     self.procserver.stop()
==> default:   File "/home/vagrant/poky/bitbake/lib/bb/server/process.py", line 163, in stop
==> default:     self.quitin.send("quit")
==> default: IOError: [Errno 9] Bad file descriptor
==> default: ---- End output of "bash"  "/tmp/chef-script20150720-2509-qa85nb" ----
==> default: Ran "bash"  "/tmp/chef-script20150720-2509-qa85nb" returned
==> default: [2015-07-20T15:51:57+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

これについては、まだ原因不明...

$ vagrant provision
==> default: Running provisioner: chef_solo...
==> default: Detected Chef (latest) is already installed
Generating chef JSON and uploading...
==> default: Running chef-solo...
==> default: stdin: is not a tty
==> default: [2015-07-20T07:12:59+00:00] INFO: Forking chef instance to converge...
==> default: [2015-07-20T07:12:59+00:00] INFO: *** Chef 12.4.1 ***
==> default: [2015-07-20T07:12:59+00:00] INFO: Chef-client pid: 27870
==> default: [2015-07-20T07:13:04+00:00] INFO: Setting the run_list to ["recipe[yocto-tools]"] from CLI options
==> default: [2015-07-20T07:13:04+00:00] INFO: Run List is [recipe[yocto-tools]]
==> default: [2015-07-20T07:13:04+00:00] INFO: Run List expands to [yocto-tools]
==> default: [2015-07-20T07:13:04+00:00] INFO: Starting Chef Run for vagrant-ubuntu-trusty-64
==> default: [2015-07-20T07:13:04+00:00] INFO: Running start handlers
==> default: [2015-07-20T07:13:04+00:00] INFO: Start handlers complete.
==> default: [2015-07-20T07:13:04+00:00] INFO: execute[sed apt-source] ran successfully
==> default: [2015-07-20T07:13:08+00:00] INFO: execute[update package index] ran successfully
==> default: [2015-07-20T07:13:08+00:00] INFO: execute[sed apt-source] ran successfully
==> default: [2015-07-20T07:49:25+00:00] INFO: bash[Format Build environment] ran successfully
==> default: [2015-07-20T07:49:25+00:00] INFO: Chef Run complete in 2181.180758673 seconds
==> default: [2015-07-20T07:49:25+00:00] INFO: Skipping removal of unused files from the cache
==> default: [2015-07-20T07:49:25+00:00] INFO: Running report handlers
==> default: [2015-07-20T07:49:25+00:00] INFO: Report handlers complete

VivadoのIPをgitなどのバージョン管理システムで取り扱う方法 (IPをsubmoduleとして管理する)

これはVivadoの使い方じゃなくて、gitの使い方なんだけれども。

github.com

http://japan.xilinx.com/support/documentation/application_notes/j_xapp1165.pdf

http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2013_2/ug896-vivado-ip.pdf

前回までで作成したリポジトリを、別プロジェクトのsubmoduleとして使って、gitのリポジトリを階層構造として管理しておく。

IPと、それを使う側のリポジトリを別々に分ける理由として、

  • そもそもこれらは関係無いファイル同士(IPとそれを使う側のデザインは、関連性は強くない)
  • IPの改変をしただけでは、本体側のデザインのリビジョンが変わる訳ではない(急な変更が発生する訳ではない)

従って、依存関係の弱いモジュールは、なるべくならリポジトリを分けるべきだと思う。ここでは、IPを別モジュールとしてロードした方法を示す。

$ cd path_of_main_project
$ git submodule add https://github.com/msyksphinz/fpga_ips.git
$ git status
$ git st
On branch axi_connect
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   .gitmodules
        deleted:    fpga_ips

Untracked files:
  (use "git add <file>..." to include in what will be committed)

...

こんな感じで追加される。

$ git commit -a -m "Func: add fpga_ips directory as submodule"

できた。

あとは、ここに入っているxciなどを好きに使うだけで良い。シミュレーション用のxxx_funcsim.vを生成したければ、普通にVivadoから追加したIPを右クリックして、Generate Product Outputsをクリックすれば作成される。 ただし、それらの生成されたファイルはリポジトリには入らない。それは「一つのxciファイルが存在していれば、そこから自動生成できるファイルはリポジトリに入れるべきではない」という精神に則っている。 必要ならば生成して、使えばいいのでわざわざリポジトリには登録しないし、それでリポジトリが汚くならないように配慮するという方針だ。

f:id:msyksphinz:20150606214924j:plain

VivadoのIPをgitなどのバージョン管理システムで取り扱う方法 (既存のIPを追加する)

既存のIPを、Managed IP Projectに追加するためには、どういたらいいんだろうか?

ここでは、pulsar1_connect(AXIバス)というIPを、IPとしてgit管理したいとする。

github.com

http://japan.xilinx.com/support/documentation/application_notes/j_xapp1165.pdf

http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2013_2/ug896-vivado-ip.pdf

$ ls -lt
合計 13
-rw-r--r--+ 1 masayuki None 49 6月   6 20:59 README.md
d---------+ 1 masayuki None  0 6月   6 20:48 managed_ip_project
d---------+ 1 masayuki None  0 6月   6 20:44 axi_dram_128bit

$ cp ../path_of_original_ips/pulsar1_connect/ .
$ ls -lt
ls -lt
合計 13
-rw-r--r--+ 1 masayuki None 49 6月   6 20:59 README.md
drwxr-xr-x+ 1 masayuki None  0 6月   6 20:50 pulsar1_connect
d---------+ 1 masayuki None  0 6月   6 20:48 managed_ip_project
d---------+ 1 masayuki None  0 6月   6 20:44 axi_dram_128bit

これで、まずはGUIでIPの登録を行う。とは言っても、tclを叩くだけである。

Tcl Console上にて

cd path_of_fpga_ip_project  # 当該プロジェクトディレクトリへ
add_files pulsar1_connect/pulsar1_connect.xci

xciを追加することで、プロジェクトに追加される。スクリーキャプチャでも失敗しているが、まずはcdコマンドでIPの存在している場所に移らないと、うまく追加できないので注意。 登録してみると、なんかいろいろ追加されている。dcpとかも登録されているし。

f:id:msyksphinz:20150606213400j:plain

これらの余計なファイルまでgitに登録してしまうと、後々面倒なので、まずは全体をクリーンアップしようと思う。 右クリックで、[Reset Output Products]をクリックする。

f:id:msyksphinz:20150606213656j:plain

完了すると、生成されたファイルがクリーンアップされる。

f:id:msyksphinz:20150606213724j:plain

この状態でgitに登録してしまえば良い。

$ git add pulsar1_connect
$ git commit -a -m "Func: add pulsar1_connect
$ git push origin master

あとは、これらのIPを使用する側のプロジェクトでこのリポジトリをsubmoduleとしてクローンし、xciファイルなどをVivado上でIPとして使えば良い。

VivadoのIPをgitなどのバージョン管理システムで取り扱う方法 (Managed IP Projectを作成する)

Vivadoのプロジェクトはバージョン管理がしにくい。やたらと意味不明なファイルが更新されてファイルのmodificationマークが付くし、しかもファイル群が巨大なので、全部格納していたのでは、リポジトリが大変なことになる。 そのために、XilinxはVivadoのプロジェクトを使うにあたって、バージョン管理システムを使うときのガイドを示している。

http://japan.xilinx.com/support/documentation/application_notes/j_xapp1165.pdf

  • Vivado Design Suite ユーザーガイド

http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2013_2/ug896-vivado-ip.pdf

基本的には、最小限のものだけバージョン管理システムに登録し、それ以外のものは自動生成に任せるのが良いと思う。IPの利用のときは特に顕著だ。 ついでに言うなら、gitを使うなら、IPはsubmoduleで管理したほうが良いかな。全部のIPを同じプロジェクトで管理するのは大変だし、再利用が難しくなる。

とりあえず、チュートリアルに従って、どのようにしてバージョン管理システムで管理すれば良いのか、いろいろ試してみた。

  1. まずはgithubの上にでも、IP用のリポジトリを作成する。ここでは、 https://github.com/msyksphinz/fpga_ips を作ってみた。

github.com

  1. [Tasks]→[Manage IP]→[New IP Location]をクリックする

f:id:msyksphinz:20150606211131j:plain

f:id:msyksphinz:20150606211348j:plain

  1. 必要に応じてコンフィグを変えていき、Managed IPプロジェクトを作成していく。

f:id:msyksphinz:20150606211416j:plain

僕はZynqユーザなのでZynqを設定した。

f:id:msyksphinz:20150606211429j:plain

f:id:msyksphinz:20150606211448j:plain

IPプロジェクトの設定が完了すると、プロジェクトマネージャが表示される。

この状態で、プロジェクトのツリー構造は以下のようになっている。

$ tree .
.
└── managed_ip_project
    ├── managed_ip_project.cache
    │   └── compile_simlib
    └── managed_ip_project.xpr

3 directories, 1 file

この段階で、もうgitに登録してしまおう。

$ cd fpga_ips
$ git init
$ git add managed_ip_project
$ git commit -a -m "Func: add initial manager files"
  1. 新しいIPを作って登録をする。まずは、IP Generatorで欲しいIPを選択する。

f:id:msyksphinz:20150606211812j:plain

ここで、AXI BRAM Controllerを選択した。

f:id:msyksphinz:20150606211818j:plain

Xilinxのgitガイドにも書いてあるように、ウィザードの最後で、「Skip」とする。これで、余計なファイルが生成されない。

f:id:msyksphinz:20150606211846j:plain

これで、右上のProject Manager [sources]にIPが追加された。この段階でこのIPのディレクトリはクリーンな状態なので、もうgitに登録してしまおう。

$ git add axi_dram_128bit
$ git commit -a -m "Func: add axi_dram_128bit repository"