FC2カウンター FPGAの部屋 2017年03月
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Raspberry Pi Zeroが来ました

昨日、スイッチサイエンスに頼んでいた Raspberry Pi Zero がやっときました。忘れたころに届きましたが、製造元から届かなかったようです。

Raspberry Pi Zero の写真です。左端のアクリル板のRaspberry Pi Zero用ケースは、アマゾンで購入しました。
Raspberry_Pi_zero_1_170331.jpg

Raspberry Pi Zero を拡大してみます。
Raspberry_Pi_zero_2_170331.jpg

Raspberry_Pi_zero_3_170331.jpg
小さいです。

裏の写真です。
Raspberry_Pi_zero_4_170331.jpg

648円なので、夏休みの自由研究の題材に良さそうです。Scratch で初めてのプログラミングとか良さそうです。
試してみたいと思います。自由に買えるようになると良いのですが。。。
  1. 2017年03月31日 05:06 |
  2. マイコン関連
  3. | トラックバック:0
  4. | コメント:0

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる4(環境の整備)

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる3(PYNQでテスト)”の続き。

前回は、Micro SDカードのパーティションに必要なファイルをコピーして、PYNQに挿入してDebian をブートした。そして、Linux ヘッダ/イメージパッケージとデバイスドライバ パッケージのインストールを行った。今回は、そのPYNQのDebian 環境を整備しよう。

パッケージのアップデートからやってみる。
df して、Micro SDカードの使用率を見てみよう。
PYNQ_Linux_ikwzm_49_170328.png
6% なので、ほとんど使っていない。

パッケージリストの更新を行う。
sudo apt-get update
PYNQ_Linux_ikwzm_50_170328.png

インストールされているパッケージの更新を行う。
sudo apt-get upgrade
PYNQ_Linux_ikwzm_51_170328.png

ifconfig コマンドは無いと言われてしまった。ネットで検索すると
ip addr show に変更になったようだ。
PYNQ_Linux_ikwzm_52_170329.png

Tera Term をもう1つ起動して、調べた IP アドレスで入れた。

date を実行したが、JST になっていた。
次に、Ubuntu のファイル表示GUI の nautilus をインストールした。
sudo apt-get install nautilus
nautilus & で起動したが、 cannot open display で起動しなかった。なお、パソコンには、Xming がインストールしてあるので、X画面を持ってこられる。
PYNQ_Linux_ikwzm_53_170329.png

nautilus が起動しなかった件では、いろいろとツィッターで検討していただいてありがとうございました。おかげさまで、動作することができました。

もう一度、nautilus をインストールした。いろいろとやっていたので、パッケージが全部あるかどうか不安だったからだ。
次に、ikwzm さんに教えて頂いた xbase-clients と xterm をインストールした。
sudo apt-get install xbase-clients xterm
PYNQ_Linux_ikwzm_55_170329.png

nautilus & で起動した。
PYNQ_Linux_ikwzm_56_170329.png

Opps が出てしまったが、nautilus が起動できた。
PYNQ_Linux_ikwzm_57_170329.png

最後に geany をインストールした。
sudo apt-get install geany
PYNQ_Linux_ikwzm_58_170329.png

geany & で起動した。
PYNQ_Linux_ikwzm_59_170329.png

geany が起動できた。
PYNQ_Linux_ikwzm_60_170329.png
  1. 2017年03月29日 05:29 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる3(PYNQでテスト)

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる2(Micro SDカードの準備)”の続き。

前回は、Micro SDカードの準備を行った。今回は、そのMicro SDカードにファイルを書き込んで、PYNQに挿入してテストしてみよう。

Micro SDカードは、/media/masaaki の下に、PYNQ_BOO とROOT_FS がマウントされている。
FPGA-SoC-Linux/target/zynq-pynqz1/boot ディレクトリのすべてのファイルをPYNQ_BOO に書き込んだ。
cp target/zynq-pynqz1/boot/* /media/masaaki/PYNQ_BOO/
PYNQ_Linux_ikwzm_34_170327.png

PYNQ_BOO のファイルを示す。
PYNQ_Linux_ikwzm_35_170327.png

debian8-rootfs-vanilla.tgz を解凍して、/media/masaaki/ROOT_FS に書き込む。
sudo tar xfz debian8-rootfs-vanilla.tgz -C /media/masaaki/ROOT_FS/
sudo が必要だった。
PYNQ_Linux_ikwzm_36_170327.png

ROOT_FS のファイルを示す。
PYNQ_Linux_ikwzm_37_170327.png

FPGA-SoC-Linux の下の

fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb
linux-headers-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb
linux-image-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb

をROOT_FS の下のhome/fpga ディレクトリにコピー&ペーストした。
PYNQ_Linux_ikwzm_38_170327.png

ROOT_FS/home/fpgaを示す。
PYNQ_Linux_ikwzm_39_170327.png

これで、Micro SDカードで行う作業は終了したので、上の図で「取り出し」ボタンをクリックした。
最後に、VirtualBox のデバイスメニューからUSB -> USB カード・リーダ・ライタを選択して、外した。
PYNQ_Linux_ikwzm_40_170327.png

さて、いよいよ出来上がったMicro SDカードをPYNQ ボードに入れて電源をON してみよう。
PYNQ の電源をON したら、Linuxは起動したのだが、ボードのDONE LED が消えたままだった。これにはびっくり。そうかビットストリームがBOOT.bin に入ってなかったのね。。。
PYNQ_Linux_ikwzm_41_170327.png

fpga ユーザーでログインしてみた。
ls で確認すると、コピーしておいた3つのファイルが見えた。
PYNQ_Linux_ikwzm_42_170327.png

次に、Linux ヘッダ/イメージパッケージをインストールしよう。
sudo dpkg -i linux-image-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb
PYNQ_Linux_ikwzm_43_170328.png

sudo dpkg -i linux-headers-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb
PYNQ_Linux_ikwzm_44_170328.png

デバイスドライバ パッケージのインストールを行った。
sudo dpkg -i fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb
PYNQ_Linux_ikwzm_45_170328.png

デバイスドライバパッケージがインストールされたかチェックしてみよう。
sudo lsmod
PYNQ_Linux_ikwzm_46_170328.png

sudo systemctl status device-tree-overlay.service
sudo systemctl status fpga-manager.service

PYNQ_Linux_ikwzm_47_170328.png

sudo systemctl status udmabuf.service
sudo systemctl status zptty.service

PYNQ_Linux_ikwzm_48_170328.png
  1. 2017年03月28日 05:22 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる2(Micro SDカードの準備)

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる1(FPGA-SoC-Linux のクローン)”の続き。

前回は、FPGA-SoC-Linux をクローンした。今回は、Micro SDカードをフォーマットして、パーティションを切った。

最初に、SDカードフォーマッターでMicro SDカードをフォーマットする。このMicro SDカードはPYNQ用のイメージを書いてあるので、上書きフォーマットで論理サイズ調整 ON でフォーマットする。

SDFormatter V4.0 を起動して、オプション設定ボタンをクリックする。
PYNQ_Linux_ikwzm_15_170325.png

フォーマットオプション設定で、上書きフォーマットと論理サイズ調整 ON を指定してOKボタンをクリックする。
PYNQ_Linux_ikwzm_16_170325.png

フォーマットボタンをクリックし、Micro SDカードのフォーマットを行う。
PYNQ_Linux_ikwzm_17_170325.png

確認ダイアログが出るので、OKボタンをクリックした。
PYNQ_Linux_ikwzm_18_170325.png

しばらくの間、フォーマットしていたが、フォーマットが終了した。
PYNQ_Linux_ikwzm_19_170325.png

次にMicro SDカードにパーティションを作っていこう。
ZedBoard用のUbuntu Linuxをビルド6(SDカードを用意する)”を参考にした。
なお、FPGAマガジン No.5 の第3章”Zynq評価ボードZedBoardでLinuxを動かそう”という石原 ひでみさんの記事の中の48ページの”図17 SDカードのパーティション操作手順”を参考にさせて頂いています。

私の環境はWindows 10 でVirtualBoxを使用して、Ubuntu 16.04 をインストールしてある。
Micro SDカードは、秋月電子で購入した”TOSHIBA マイクロSDカード(microSDHC)EXCERIA 16GB 48MB/s”を使用している。このMicro SDカードは古いカード・リーダー・ライタでは認識できなかった。

Windows 10 のパソコンに挿入した Micro SDカードをVirtualBox 上のUbuntu にマウントするためにVirtualBox のデバイスメニュー -> USB -> USBリーダーの名前(Micro SDカードが装着してある)を選択した。
PYNQ_Linux_ikwzm_20_170326.png

/media/masaaki/1BC2-1630 としてマウントされた。
PYNQ_Linux_ikwzm_21_170326.png

lsblk コマンドを実行して、SDカードを検索した。
PYNQ_Linux_ikwzm_22_170326.png

/dev/sdb がSDカードのようだ。
sudo umount /dev/sdb1 で sdb1 をアンマウントしておく。こうしないと後で w コマンドで書き込むときにエラーになってしまう。
sudo fdisk /dev/sdb コマンドを実行してSDカードのフォーマットを開始した。
PYNQ_Linux_ikwzm_23_170326.png

p コマンドで既存のパーティションを表示した。FAT32パーティションが生成されていた。
d コマンドでパーティションを削除した。
p コマンドで見ると、パーティションが消去されていた。
PYNQ_Linux_ikwzm_24_170326.png

プライマリ・ディスクのパーティション番号1に100 MBの領域を確保する

n コマンドで新たにパーティションを作製した。
p を押して、primary パーティションを指定した。
パーティション番号を 1 にセット。
First sector で、リターンキーを入力した。
Last sector で、+100M を入力して、100 MB の領域を確保した。
p コマンドででパーティションを表示した。
PYNQ_Linux_ikwzm_25_170326.png

プライマリ・ディスクのパーティション番号2に残っている領域(14.3 GB)を確保する
n コマンドで新たにパーティションを作製した。
p を押して、primary パーティションを指定した。
パーティション番号を 2 にセット。
First sector で、リターンキーを入力した。
Last sector で、リターンキーを入力した。
p コマンドででパーティションを表示した。
PYNQ_Linux_ikwzm_26_170326.png

プライマリ・ディスクのパーティション番号1をFAT32にして、ブート可能フラグを付ける
t コマンドを入力した。
パーティション番号に 1 を入力した。
16進コードに、b を入力した。(W95 FAT32)
a コマンドを入力して、ブート可能フラグを付ける。
パーティション番号に 1 を入力した。
p コマンドででパーティションを表示した。
PYNQ_Linux_ikwzm_27_170326.png

SDカードへの書き込み

w コマンドを実行して、今まで設定してきたパーティション情報をMicro SDカードにWrite した。
PYNQ_Linux_ikwzm_28_170326.png

lsblk を行うと、設定したパーティションが sdb1, sdb2 として見えている。
FPGAマガジン No.5 の第3章”Zynq評価ボードZedBoardでLinuxを動かそう”という石原 ひでみさんの記事を参考に、/dev/sdb1 に対して、

sudo mkfs.msdos -n PYNQ_BOO /dev/sdb1

を実行した。(PYNQ_BOOT としたかったが、PYNQ_BOO とタイポしてしまった)
PYNQ_Linux_ikwzm_29_170326.png

PYNQ_BOO がマウントされた。
PYNQ_Linux_ikwzm_30_170326.png

同様に、/dev/sdb2 に対して、

sudo mkfs.ext3 -L ROOT_FS /dev/sdb2

を実行した。(ファイルシステムは ext3 指定だった)
Writing superblocks and filesystem accounting infomation: でリターンを入力した。
PYNQ_Linux_ikwzm_31_170326.png

コマンドが終了した。
PYNQ_Linux_ikwzm_32_170326.png

ROOT_FS がマウントされた。
PYNQ_Linux_ikwzm_33_170326.png

これで、Micro SDカードの用意は終了した。
  1. 2017年03月27日 04:50 |
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

Vivado WebPACK 2016.1 からWebPACKではラインセンスファイルは必要ありません

Vivado WebPACK 2016.1 からWebPACK では、ライセンスファイルは必要無くなりました。
ダウンロード時に登録は必要ですが、Vivado WebPACK 2016.1~は、インストールすればライセンスファイルを取得しなくても起動して普通に使えます。今のVivado WebPACK 2016.4 でも同様にラインセンスファイルは必要ありません。

詳しくは、”Vivado Design Suite ユーザー ガイド リリース ノート 、 インストールおよびライセンス UG973 (v2016.4) 2016 年 11 月 30 日”の 80 ページ ”Vivado WebPACK をライセンス ファイルなしで使用可能”をご覧ください。
  1. 2017年03月26日 21:57 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみる1(FPGA-SoC-Linux のクローン)

ikwzm さんの”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”を試してみようと思う。

Device Tree Overlay+FPGA Managerが使用できれば、SDSoC でビットストリームとアプリケーションソフトが作れれば、すでに動作しているLinux 上でリブートすること無しにいくらでも試すことができる。”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”もこのままの状態で起動したら、Device Tree Overlay+FPGA Managerでハードウェアとそのデバイスツリーを使ってFPGA を使うことができるはずだ。つまりLinux は動作しながら、FPGAでアクセラレーションできるわけだ。という理由でやってみることにした。
参考資料

FPGA+SoC+LinuxでDevice Tree Overlayを試してみた
”FPGA+SoC+LinuxでFPGA Managerを試してみた


まずは、”FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)”で指定されているように、Git LFS(Large File Storage)を自分のVirtualBox 上のUbuntu 16.04 に追加します。
sudo apt-get install git-lfs
PYNQ_Linux_ikwzm_1_170325.png

git-lfs が無いと言われてしまう。
GitHub のgit-lfs/git-lfs の Installation を見るとUbuntu での git-lfs のインストール方法が書いてあった。その手順に従ってUbuntu 16.04 上で git-lfs のインストールを行う。

sudo apt-get install python-software-properties
PYNQ_Linux_ikwzm_2_170325.png

Yをクリックしてインストールを進めると、python-software-properties がインストールできた。
sudo add-apt-repository ppa:git-core/ppa
PYNQ_Linux_ikwzm_3_170325.png

PYNQ_Linux_ikwzm_4_170325.png

ppa をインストールすることができた。
この後で、sudo apt-get update をするように書いてあるが、忘れてしまった。最後にsudo apt-get updatesudo apt-get upgrade を実行しておいたが、これで良いかどうか?よくわからない?

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
PYNQ_Linux_ikwzm_5_170325.png

sudo apt-get install git-lfs
PYNQ_Linux_ikwzm_6_170325.png

git lfs install
PYNQ_Linux_ikwzm_7_170325.png

これで git lfs がインストールできた。

さて、ikwzm さんのFPGA-SoC-Linux をクローンする。
git clone git://github.com/ikwzm/FPGA-SoC-Linux
cd FPGA-SoC-Linux
ls

PYNQ_Linux_ikwzm_8_170325.png

FPGA-SoC-Linux ディレクトリの下には12個のファイルまたはディレクトリがあった。
PYNQ_Linux_ikwzm_10_170325.png

git checkout v0.3.0
PYNQ_Linux_ikwzm_11_170325.png

git lfs pull
PYNQ_Linux_ikwzm_12_170325.png

FPGA-SoC-Linux ディレクトリの下のファイルまたはディレクトリが 9 個に減った。
PYNQ_Linux_ikwzm_13_170325.png

FPGA-SoC-Linux/target/zynq-pynqz1/boot ディレクトリのファイルを示す。
PYNQ_Linux_ikwzm_14_170325.png

boot.bin や u-boot, デバイスツリーの dts と dtb, uEnv.txt, zImage などが入っていた。
  1. 2017年03月26日 06:01 |
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

Vivado 2016.4 のSDKでデバイスツリーのソース(DTS)を生成する

Linux 上のISE のSDK からデバイスツリーのソース(DTS)を生成する方法は”SDKでDevice Treeを生成する2(SDKでxilinx.dtsを生成)”に書いた。今回は、Windows 10 上で、Vivado 2016.4 のSDKでデバイスツリーのソース(DTS)を生成してみよう。

自分のブログを参考しても良いのだが、ISE のSDK なので、”blog 渓鉄”さんの”Xilinx SDKでDevice Treeを生成する”を参考にさせて頂きます。

SDK は、”Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム”のSDK をそのまま使用する。

最初に、ブラウザで”Xilinx/device-tree-xlnx”を開く。
SDK_dts_1_170325.png

Clone of download ボタンをクリックして、Download ZIP ボタンをクリックする。
device-tree-xlnx-master.zip ファイルがダウンロードできるので、適当なフォルダを選択し、保存ボタンをクリックしてセーブする。
SDK_dts_2_170325.png

device-tree-xlnx-master.zip ファイルをダブルクリックすると、圧縮ファイル上のフォルダが見えるので、そのdevice-tree-xlnx-master フォルダを適当なフォルダにドラック&ドロップする。
SDK_dts_3_170325.png

SDK 2016.4 で、Xilinx Tools -> Repositories を選択する。
SDK_dts_4_170325.png

開いたダイアログのLocal Repositories で、New... ボタンをクリックする。
SDK_dts_5_170325.png

先ほどダウンロードして解凍したdevice-tree-xlnx-master フォルダを選択する。
SDK_dts_6_170325.png

Local Repositories にdevice-tree-xlnx-master フォルダのパスが入った。
SDK_dts_7_170325.png

OK ボタンをクリックするとSDK に戻った。
SDK_dts_8_170325.png

File メニューからNew -> Board Support Package を選択した。
SDK_dts_10_170325.png

Xilinx Board Support Package Project ダイアログが表示された。
SDK_dts_11_170325.png

Board Support Package OS にdevice_tree が増えているので、それを選択した。Finish ボタンをクリックした。
Board Support Package Settings が開いた。
最初はOverview 画面だ。
SDK_dts_12_170325.png

device_tree をクリックした。
SDK_dts_13_170325.png

DTS ファイルは分割されるようだ。
drivers をクリックした。
SDK_dts_14_170325.png

SDK に戻ると、device_tree_bsp_0 ができていて、下に示すファイルができていた。

pcw.dtsi
pl.dtsi
skeleton.dtsi
system-top.dts
system.dts
zynq-7000.dts


SDK_dts_15_170325.png
  1. 2017年03月26日 04:38 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム6(アプリの変更と30fpsへ)

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム5(ILAコアの削除)”の続き。

前回は、Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システムから 2 つの ILA コアを削除した。今回は、アプリケーションソフトを整備した後で、15 fps のカメラのフレームレートを 30 fps に変更する。

まずは、DMA_Read_addr IP の動作モードのDMA_WRITE_MODE はDMA_Write IP の書き込んでいる画像フレームの1つ前の画像フレームからDMA Read しているモードでこれは正常に動作している。問題は、FREE_RUM_MODE で、これは、3 つの画像フレームからフリーランで読んでるモードなのだが、15 fps でカメラがWrite していて、60 fps でビットマップ・ディスプレイ・コントローラがRead するので、画像フレームバッファが 3 つあると現在、過去が入り混じって画像がぶれてしまう。よって、FREE_RUM_MODE の場合は、画像フレームを 1 つにする必要があるようだ。そのように変更したところ、画像がぶれることは無くなった。
DMA_Read_IP_85_170320.png

cam_disp_hls.c を貼っておく。

/* * cam_disp_hls.c * *  Created on: 2016/08/21 *      Author: Masaaki */


#include <stdio.h>
#include <stdlib.h>
#include "xil_io.h"
#include "xdma_read_addr.h"
#include "xdma_write.h"
#include "sleep.h"

#define NUMBER_OF_WRITE_FRAMES    3 // Note: If not at least 3 or more, the image is not displayed in succession.

#define HORIZONTAL_PIXELS    800
#define VERTICAL_LINES        600
#define PIXEL_NUM_OF_BYTES    4

#define FRAME_BUFFER_ADDRESS 0x10000000

#define DMA_WRITE_MODE
//#define FREE_RUN_MODE

void cam_i2c_init(volatile unsigned *mt9d111_i2c_axi_lites) {
    mt9d111_i2c_axi_lites[64] = 0x2// reset tx fifo ,address is 0x100, i2c_control_reg
    mt9d111_i2c_axi_lites[64] = 0x1// enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
        // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile unsigned *mt9d111_i2c_axi_lites, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
    mt9d111_i2c_axi_lites[66] = 0x100 | (device_addr & 0xfe);   // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    mt9d111_i2c_axi_lites[66] = write_addr;
    mt9d111_i2c_axi_lites[66] = (write_data >> 8)|0xff;         // first data
    mt9d111_i2c_axi_lites[66] = 0x200 | (write_data & 0xff);        // second data
    cam_i2x_write_sync();
}

int main(){
    XDma_read_addr  dmar, *dmarp;
    XDma_write      dmaw, *dmawp;

    dmarp = &dmar;
    dmawp = &dmaw;

    // Initialization of DMA Read
    if (XDma_read_addr_Initialize(dmarp, 0) != XST_SUCCESS){
        fprintf(stderr,"DMA Read open error\n");
        exit(-1);
    }

    // Initialization of DMA Write
    if (XDma_write_Initialize(dmawp, 0) != XST_SUCCESS){
        fprintf(stderr,"DMA Write open error\n");
        exit(-1);
    }

    // frame buffer settings
#ifdef DMA_WRITE_MODE
    XDma_read_addr_Set_frame_buffer0(&dmar, FRAME_BUFFER_ADDRESS);
    XDma_read_addr_Set_frame_buffer1(&dmar, FRAME_BUFFER_ADDRESS+HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES);
    XDma_read_addr_Set_frame_buffer2(&dmar, FRAME_BUFFER_ADDRESS+2*HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES);

    XDma_write_Set_frame_buffer0(&dmaw, FRAME_BUFFER_ADDRESS);
    XDma_write_Set_frame_buffer1(&dmaw, FRAME_BUFFER_ADDRESS+HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES);
    XDma_write_Set_frame_buffer2(&dmaw, FRAME_BUFFER_ADDRESS+2*HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES);
#else // FREE_RUN_MODE
    XDma_read_addr_Set_frame_buffer0(&dmar, FRAME_BUFFER_ADDRESS);
    XDma_read_addr_Set_frame_buffer1(&dmar, FRAME_BUFFER_ADDRESS);
    XDma_read_addr_Set_frame_buffer2(&dmar, FRAME_BUFFER_ADDRESS);

    XDma_write_Set_frame_buffer0(&dmaw, FRAME_BUFFER_ADDRESS);
    XDma_write_Set_frame_buffer1(&dmaw, FRAME_BUFFER_ADDRESS);
    XDma_write_Set_frame_buffer2(&dmaw, FRAME_BUFFER_ADDRESS);
#endif

    // DMA_read_addr mode set
#ifdef DMA_WRITE_MODE
    XDma_read_addr_Set_mode_V(&dmar, 0); // DMA_WRITE_MODE
#else // FREE_RUN_MODE
    XDma_read_addr_Set_mode_V(&dmar, 1); // FREE_RUN_MODE
#endif

    // mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cont_axis_0
    volatile unsigned int *mt9d111_axiL;
    volatile unsigned int *cam_iic_axiL;
    volatile unsigned int *bmdc_axiL;

    mt9d111_axiL = (volatile unsigned int *)XPAR_MT9D111_INF_AXIS_0_BASEADDR;
    cam_iic_axiL = (volatile unsigned int *)XPAR_AXI_IIC_0_BASEADDR;
    bmdc_axiL = (volatile unsigned int *)XPAR_BITMAP_DISP_CONT_AXIS_0_BASEADDR;

    // bitmap_disp_cont_axis_0 is started
    bmdc_axiL[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Camera Interface start (Address is dummy)

    // DMA Start
    XDma_read_addr_DisableAutoRestart(&dmar);
    while(!XDma_read_addr_IsIdle(&dmar)) ;
    XDma_read_addr_Start(&dmar);
    XDma_read_addr_EnableAutoRestart(&dmar);

    XDma_write_DisableAutoRestart(&dmaw);
    while(!XDma_write_IsIdle(&dmaw)) ;
    XDma_write_Start(&dmaw);
    XDma_write_EnableAutoRestart(&dmaw);

    // mt9d111_inf_axis_0 is started
    mt9d111_axiL[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Camera Interface start (Address is dummy)

    // CMOS Camera initialize, MT9D111
    cam_i2c_init(cam_iic_axiL);

    cam_i2c_write(cam_iic_axiL, 0xba, 0xf00x1);      // Changed regster map to IFP page 1
    cam_i2c_write(cam_iic_axiL, 0xba, 0x970x20);     // RGB Mode, RGB565

    mt9d111_axiL[1] = 0// One_shot_mode is disabled

    return(0);
}


これで、FREE_RUM_MODE も問題が無くなったので、次は、カメラのフレームレートを 15 fps から 30 fps に向上させることにした。
やり方は、”MT9D111のフレームレートを 15 fps から 30 fps にした”に書いておいた。
早い話が、カメラに供給するクロックを 36 MHz から倍の 72 MHz に変更するということだ。それに合わせて制約も変更する。
具体的には、PS からのクロックの FCLK_CLK2 の周波数設定を 36 MHz から 72 MHz に変更した。
DMA_Read_IP_86_170320.png

もう一度、論理合成、インプリメント、ビットストリームの生成を行い、ハードウェアをエクスポートして、SDKを立ち上げた。
これで、画像のフレームレートが 15 fps から 30 fps に向上した。

このDMAWrite IPとDMA_Read_addr IP の組は使えそうだ。AXI VDMAの説明書を読まなくても簡単に使えるところが良いと思う。
願わくば、DMA_Read_addr IP を使うときのツールのバグが直ってほしいと思う。
  1. 2017年03月24日 05:17 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム5(ILAコアの削除)

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム4(ILAコアの挿入2)”の続き。

前回、Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システムが動作した。しかし、ブロックデザイン上で挿入したILA コアとネットリストの信号を観察するため入れたILA コアが残ってしまっている。それを削除した。

まずは、ブロックデザイン上で挿入したILA コアを削除しよう。

Debug にマーキングされた配線を複数選択して、右クリックし、右クリックメニューからClear Debug を選択する。
DMA_Read_IP_76_170320.png

ILA コアの system_ila が削除された。
DMA_Read_IP_77_170320.png

これで、ブロックデザイン上で挿入したILA コアが削除された。
次に、ネットリストの信号を観察するため入れたILA コアを削除する。

論理合成を行って、成功後に表示されるSynthesis Completed ダイアログで Open Synthesized Design を選択した。
DMA_Read_IP_78_170320.png

Synthesized Design が表示された。Tools -> Set Up Debug... を選択した。
DMA_Read_IP_79_170320.png

Set Up Debug ダイアログが表示された。Next ボタンをクリックした。
DMA_Read_IP_80_170320.png

Existing Debug Nets で、Disconnect all net and remove debug cores を選択した。
DMA_Read_IP_81_170320.png

Set Up Debug Summary が表示された。Finish ボタンクリックした。
DMA_Read_IP_82_170320.png

ネットリストの信号を観察するため入れたILA コアが削除された。
DMA_Read_IP_83_170320.png

確か、制約ファイルの ILA コア関連の制約は削除されたが、1つ ILA コアの制約が残っていたので、手動で削除した。

インプリメント、ビットストリームの生成を行った。結果を示す。
DMA_Read_IP_84_170320.png

ILA コアが入る前と同等のリソース使用量になった。

ハードウェアをエクスポートして、SDK を立ち上げて、カメラ画像をディスプレイに表示してみたところ正常に表示された。
DMA_Read_IP_87_170320.jpg
  1. 2017年03月23日 04:58 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム4(ILAコアの挿入2)

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム3(ILAコアの挿入)”の続き。

DMA_Read_addr_0 の m_axi_in_r と outs は波形が出ていて動作しているようだった。よって今回は、AXI4-Stream 版のビットマップ・ディスプレイ・コントローラの内部信号をVivado Analyzer で確認してみよう。

Flow Navigator -> Synthesis -> Open Synthesized Design をクリックして、Synthesized Design を開く。

Tools -> Set Up Debug... を選択する。
DMA_Read_IP_56_170320.png

Set Up Debug ダイアログが開いた。
DMA_Read_IP_57_170320.png

Nets to Debug でFind Nets to Add... をクリックする。
DMA_Read_IP_58_170320.png

Find Nets で、h_count を検索してみた。
DMA_Read_IP_59_170320.png

Add Nets to Debug で信号を選択する。
DMA_Read_IP_60_170320.png

観察する信号を示す。
DMA_Read_IP_61_170320.png

次は、ILA Core Options を設定する。
DMA_Read_IP_62_170320.png

Set Up Debug Summary が表示された。
DMA_Read_IP_63_170320.png

Debug 画面が表示された。
DMA_Read_IP_64_170320.png

cam_disp_axis.xdc の制約ファイルに挿入したu_ila_0 の制約が追加された。
DMA_Read_IP_65_170320.png

インプリメント、ビットストリームの生成を行った。結果を示す。
DMA_Read_IP_66_170320.png

SDK でXilinx Tools -> Program FPGA を選択して、ビットストリームをZynq にダウンロードした。
SDK で、Hello_World を起動して、PL にクロックを供給した。
Flow Navigator -> Program and Debug -> Open Hardware Manager -> Auto Connect を選択した。
Hardware Manager が起動した。
Dashboard Optionsを開いて、hw_ila_2, hw_ila_3 のすべてにチェックを入れた。
DMA_Read_IP_67_170320.png

hw_ila_1 のトリガをかけた。AXI4 バス。
DMA_Read_IP_68_170320.png

hw_ila_2 のトリガをかけた。ビットマップ・ディスプレイ・コントローラのclk_disp ドメイン。
DMA_Read_IP_69_170320.png

hw_ila_3 のトリガをかけた。ビットマップ・ディスプレイ・コントローラの clk_axi ドメイン。
DMA_Read_IP_70_170320.png

SDK で cam_disp_hls.elf をRun した。
hw_ila_3 の波形を示す。diap_mode_ena が 1 にならない。しかも init_done_d1 が上がったときに、u_ila_1_war_data_count_1[7:0] が 00 ではなかった。となると、ビットマップ・ディスプレイ・コントローラを活かすのが遅いことが考えられる。
DMA_Read_IP_71_170320.png

cam_disp_hls.c のアプリケーションソフトで、DMA_read_addr の起動の後で、ビットマップ・ディスプレイ・コントローラを活かしていたのだが、これでは、ビットマップ・ディスプレイ・コントローラを活かすのが遅い。ビットマップ・ディスプレイ・コントローラを生かす記述(ピンクの四角)を DMA_read_addr の起動(青の四角)の前に持ってきた。
DMA_Read_IP_72_170320.png

これでうまくDMA Read の波形が出力された。
DMA_Read_IP_73_170320.png

画像も表示された。
DMA_Read_IP_87_170320.jpg

DMA Read とDMA Write が両方表示されている波形を示す。
DMA_Read_IP_74_170320.png
DMA_Read_IP_75_170320.png
  1. 2017年03月21日 04:08 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム3(ILAコアの挿入)

Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム1(プロジェクト作成)
Vivado HLS で生成した AXI4 Master DMA IP を使用したカメラ画像表示システム2(SDK)”の続き。

前にやったのは半年くらい前だが、DMA Read IPが動作しないということで止まっていた。しかし、”「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション3”で論理合成しても機能シミュレーションが問題なくなったということで、もう一度やってみようと思う。

cam_disp_axis_162 プロジェクトはVivado 2016.2 なので、”Vivado 2016.2 からVivado 2016.4 へアップグレード”を参照して、Vivado 2016.4 のcam_disp_axis プロジェクトを作成した。
DMA_Read_IP_34_170319.png
当然、Target language はVHDL にしてある。
(2017/04/20 : 追記)この時点ではアプリケーションソフトがバグっていてディスプレイに表示できませんが、アプリケーションソフトのバグフィックス後に、Target language を Verilog にしても動作しました。論理合成後の機能シミュレーションを行うときに強瀬された EDIF からVerilog に変換するツールがバグっているようです。

論理合成、インプリメント、ビットストリームの生成を行ったところ、成功した。
リソース使用量は以前と変化が無い。今回のProject Summary はキャプチャするのを忘れてしまったので、以前のVivado 2016.2 のときのProject Summary を貼っておく。
cam_disp_axis_6_160821.png

ハードウェアをエクスポートして、SDKを立ち上げた。
cam_disp_hls プロジェクトを作成し、cam_disp_hls.c をコピー&ペーストした。
ビットストリームをZYBO にダウンロードして、cam_disp_hls.elf を起動したが、動作しなかった。
DMA_Read_IP_35_170319.png

Vivado 2016.4 になって変わったVivado Analyzer を試してみようということで、ブロックデザインでDMA_Read_addr_0 のm_axi_in_r と outs とDMA_Write_0 の m_axi_out_r を選択して、右クリックし右クリックメニューからDebug を選択した。
DMA_Read_IP_36_170319.png

選択したラインにデバックマークが付き、上に Run Connection Automation が出るので、クリックした。
DMA_Read_IP_37_170319.png

Run Connection Automation が表示された。OK ボタンをクリックした。
DMA_Read_IP_38_170319.png

system_ila が挿入された。ILA コアがブロックデザイン上に挿入されるようになった。
DMA_Read_IP_39_170319.png

論理合成、インプリメント、ビットストリームの生成を行った。結果を示す。
DMA_Read_IP_40_170319.png
全体的にリソース使用量が増えている。これはILA コアを入れたので、当然と言えば当然だ。

Vivado Analyzer はPL の回路にクロックが来ないと起動できない。ソフトウェアを起動しないと回路にクロックが供給されないので、Vivado Analyzer は起動しない。
と言う訳で、ZYBO にビットストリームをダウンロードしてから、cam_disp_hls.elf を起動した。
DMA_Read_IP_41_170319.png

その後で、Flow Navigator -> Program and Debug -> Open Hardware Manager -> Auto Connect を選択した。
DMA_Read_IP_42_170319.png

Hardware Manager が立ち上がった。
DMA_Read_IP_43_170319.png

Status ペインで Run trigger immediate for this ILA core をクリックすると、すぐに波形がキャプチャされる。
DMA_Read_IP_44_170319.png

Vivado 2016.4 では、AXI バスはステータスを表示してくれるようだ。トランザクションが全く見えなかった。
DMA_Read_IP_47_170319.png

よくわからなかったので、DMA_Write_0 の ins も追加した。
DMA_Read_IP_48_170319.png

論理合成、インプリメント、ビットストリームの生成を行った。成功した。
Project Summary を示す。
DMA_Read_IP_49_170319.png

Hardware Manager で net_slot_3_axis_tvalid = R (DMA_Write_0 の ins)でトリガをかけて Run trigger for this ILA core をクリックした。
DMA_Read_IP_50_170319.png

DMA_Write_0 の ins と m_axi_out_r は波形が出力されていることが分かった。
DMA_Read_IP_51_170319.png

次に、net_slot_0_axi_arvalid = R (DMA_Read_addr_0 の m_axi_in_r)でトリガをかけたが掛からなかった。
DMA_Read_IP_52_170319.png

これは、電源ON の少し間だけのみ DMA_Read_addr_0 の m_axi_in_r と outs が動作しているかもしれない。ということで、Hello_World プロジェクトを作成し、これを起動して、PL へクロックを供給してから cam_disp_hls.elf を起動することにした。

Hello_World プロジェクトを作成した。起動した。
DMA_Read_IP_53_170319.png

Flow Navigator -> Program and Debug -> Open Hardware Manager -> Auto Connect を選択し、Hardware Manager を起動する。
net_slot_0_axi_arvalid = R (DMA_Read_addr_0 の m_axi_in_r)でトリガをかけた。
DMA_Read_IP_54_170319.png

これで、SDK で、cam_disp_hls.elf を起動した。すると、トリガがかかってDMA_Read_addr_0 のm_axi_in_r と outs の波形が表示された。
DMA_Read_IP_55_170319.png

これを見るときちんとDMA_Read_addr_0 の m_axi_in_r はAXI4 Master Read ができていて、AXI4-Stream の outs にもきちんと出力できているように見える。しかし、途中で tready が 1 から 0 になってしまっている。これは、AXI4-Stream 版のビットマップ・ディスプレイ・コントローラのピクセル用FIFO がフルになってしまっているからだと思われる。
AXI4-Stream 版のビットマップ・ディスプレイ・コントローラがおかしい可能性が出てきた。
  1. 2017年03月20日 07:16 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション3

「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション2”の続き。

前回は、Vivado HLS 2016.4 で Verilog でIP をExport RTL して、Vivado 2016.4 では、Target language を VHDL にしたら、Post-Synthesis Functional Simulation が正常になった。ここでは、IO ピンが足りるようにVirtex7 の xc7vx980tffg1928-2 を使用していたが、IO ピンが足りないZYBO (xc7z010clg400-1)ではどうか?を確かめてみた。ikzwm さんがやってくれたので、大丈夫とは思うが自分でも確かめてみる。

まずは、Vivado HLS 2016.4 で、”Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)”のソースコードで、xc7z010clg400-1 をターゲットとして、Verilog でExport RTL を行った。
DMA_Read_IP_29_170319.png

そのVivado HLS2016.4 のDMA Read IPを使用して、Project part を xc7z010clg400-1 に変更し、Project Settings のTarget language を VHDL にした Vivado 2016.4 プロジェクトを作った。
DMA_Read_IP_30_170319.png

論理合成を行った。IO ピンはオーバーフローになっている。
DMA_Read_IP_31_170319.png

Flow Navigator の Simulation -> Run Simulation -> Run Post-Synthesis Functional Simulation を選択して、論理合成後の機能シミュレーションを行った。
DMA_Read_IP_32_170319.png
問題なく波形が出ている。

次に、念のため、Flow Navigator の Simulation -> Run Simulation -> Run Behavioral Simulation を選択して、論理シミュレーションを行った。
DMA_Read_IP_33_170319.png
こっちも問題なく波形が出ている。

よって、ZYBO (xc7z010clg400-1)でも問題なく波形が出ている。
論理合成で IO ピンがオーバーフローでも Post-Synthesis Functional Simulation には影響ないことが分かった。
  1. 2017年03月19日 06:22 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

ひるね姫(映画)を見てきました

今日は、ひるね姫(映画)を見てきました。とっても面白かったです。夢と日常が行ったり来たり。
しかし、自動運転のマスタコード?十数年もその価値を保っているとは思えないけど。。。作った人が超天才で、それ人でなければ作れないという設定なのか?
それに、予告編でも出てくるハンダ付けの場面はハンダ盛り過ぎなんじゃないか?と思う。
  1. 2017年03月18日 21:46 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション2

「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション”の続き。

ikwzm さんにVivado HLS のExport RTL のEvaluate Generated RTL をVHDL にしたら論理合成後の機能シミュレーションも動いたということでやってみたのだが、やはり結果は同様に動作していなかった。

Vivado RTL Synthesis のチェックを外して、Evaluate Generated RTL をVerilog でIP 化してやってみても同じだった。もう一度、Vivado RTL Synthesis のチェックを外して、Evaluate Generated RTL をVHDL でIP 化しても同様にダメだった。
DMA_Read_IP_24_170316.png

ikwzm さんからもう一度、教えてもらったところ、「Vivado-HLS の Export RTL as IP は Verilog かつ、Vivado の Target Language を VHDL にした場合」とのことだった。
もう一度、Vivado HLS 2016.4 で Evaluate Generated RTLVerilog に設定して、Export RTL を行った。
Vivado RTL Synthesis のチェックは外してあるが、IP になった後のファイルを見てみたところ、特に合成結果が入っているようには見えなかったので、やってみるだけなのだと思う。
DMA_Read_IP_25_170316.png

Vivado 2016.4 で DMA Read IP をリプレースして、Project Settings のTarget language VHDL にした。
DMA_Read_IP_26_170316.png

これで、論理合成(Run Synthesis)を行ってから、Flow Navigator の Simulation -> Run Simulation -> Run Post-Synthesis Functional Simulation を選択して、論理合成後の機能シミュレーションを行った。
やった~。波形が出た。。。
DMA_Read_IP_27_170316.png

DMA_Read_IP_28_170316.png

何でだろう?これで何で波形が出るの?
ともかくよかった。これはXilinx社にバグレポートしないと。。。

論理シミュレーションも問題なく波形が表示されている。。。
  1. 2017年03月18日 05:15 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

「Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)」を使って合成後の機能シミュレーション

Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)”の続き。

前回は絶対アドレス指定のDMA Read IPをVivado HLS 2016.4 で作成した。今回は、そのDMA Read IPをVivado で論理シミュレーションと合成後の機能シミュレーションを行った。

前回やったときの記事は、”DMA Read IP を単体でシミュレーション3(DMA Read IP単体で論理合成後にシミュレーション)

このプロジェクトを使用した。
DMA_Read_IP_9_170316.png

ただし新しく生成した DMA Read IPに入れ替えてある。それに、DMA Read IPのレジスタ設定を行う reg_write_read IP が一度設定を終了しても、また設定を繰り返し行っていたので、修正を行った。上に示す図は論理合成が終了している。
論理合成後のレポートを示す。
DMA_Read_IP_10_170316.png

IOポートはすべて割り振られている。これで論理合成後の機能シミュレーションは問題ない。しかし、IOがオーバーフローしていても論理合成後の機能シミュレーションがうまく行くのかもしれない?確実に動作する回路で試していないので、よくわからない?

ブロックデザインを示す。
DMA_Read_IP_11_170316.png

DMA Read IPとAXI Interconnect 2つだけのシンプルな構成だ。

Address Editor を示す。
DMA_Read_IP_12_170316.png

テストベンチとして、DMA Read IPのレジスタを設定する reg_write_read IP と AXI4 Slave BFM をメモリとして接続している。そのブロック図を下に示す。
DMA_Read_IP_13_170316.png

さて次に、論理シミュレーションを行う。
Flow Navigator の Simulation -> Run Simulation -> Run Behavioral Simulation を選択する。
DMA_Read_IP_14_170316.png

論理シミュレーション結果の全体波形を示す。
DMA_Read_IP_15_170316.png
波形1

DMA_Read_IP_17_170316.png
波形2

波形の数が多いので、2つの画像になってしまった。最初の画像は主にDMA Read IPのAXI4 Master Read アクセスが表示されている。2つ目の波形には、DMA Read IPのレジスタを設定するAXI4-Lite Slave アクセスとAXI4-Stream 出力が表示されている。

最初の波形を拡大してみよう。
DMA_Read_IP_16_170316.png
波形3

バーストに1クロックの Wait はあるがほとんどフルバーストでAXI4 Master Read が行われている。

次に、DMA Read IPを設定するのレジスタを設定するAXI4-Lite Slave アクセスを下に示す。
DMA_Read_IP_18_170316.png
波形4

まずは、DMA Read IPのレジスタマップを示す。

//------------------------Address Info-------------------
// 0x00 : Control signals
//        bit 0  - ap_start (Read/Write/COH)
//        bit 1  - ap_done (Read/COR)
//        bit 2  - ap_idle (Read)
//        bit 3  - ap_ready (Read)
//        bit 7  - auto_restart (Read/Write)
//        others - reserved
// 0x04 : Global Interrupt Enable Register
//        bit 0  - Global Interrupt Enable (Read/Write)
//        others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
//        bit 0  - Channel 0 (ap_done)
//        bit 1  - Channel 1 (ap_ready)
//        others - reserved
// 0x10 : Data signal of ap_return
//        bit 31~0 - ap_return[31:0] (Read)
// 0x18 : Data signal of frame_buffer0
//        bit 31~0 - frame_buffer0[31:0] (Read/Write)
// 0x1c : reserved
// 0x20 : Data signal of frame_buffer1
//        bit 31~0 - frame_buffer1[31:0] (Read/Write)
// 0x24 : reserved
// 0x28 : Data signal of frame_buffer2
//        bit 31~0 - frame_buffer2[31:0] (Read/Write)
// 0x2c : reserved
// 0x30 : Data signal of mode_V
//        bit 0  - mode_V[0] (Read/Write)
//        others - reserved
// 0x34 : reserved
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


レジスタを設定する reg_write_read IP の設定を示す。

// reg_write_read.h
// 2016/06/10 by marsee
//
// reg_addr_data フォーマット、
// 第1フィールド(reg_ad[x][0]):Write - 0, Read - 1
// 第2フィールド(reg_ad[x][1]):Delay、単位はクロック数
// 第3フィールド(reg_ad[x][2]):アドレス、16進数
// 第4フィールド(reg_ad[x][3]):データ、16進数
//
// 終了は第2フィールド:Delayに 0xffffffff が書いてあったとき

#define AD_ARRAY_LIMIT 256
#define REG_WRITE 0
#define REG_READ 1

#define R_W_FIELD 0
#define DELAY_FIELD 1
#define ADDRESS_FIELD 2
#define DATA_FIELD 3

const unsigned int reg_ad[AD_ARRAY_LIMIT][4]={
        {000x44A00018, 0x10000000},
        {000x44A00020, 0x10000000},
        {000x44A00028, 0x10000000},
        {000x44A00030, 0},
        {100x44A00000, 0},
        {000x44A00000, 1},
        {00xfffffffe, 00},
        {00xffffffff, 00},


つまり、0x44A00018、0x44A00020、0x44A00028 に 0x10000000 を書いているが、3つのフレームバッファのアドレスを書いている。
0x44A00030 でDMA Read IPのモードを書いている。 0 なので、DMA_WRITE_MODE だ。
0x44A00000 をRead してから、0x44A00000 に 1 を書いてDMA Read IPをスタートさせている。

DMA Read IPのAXI4-Stream 出力の波形を示す。
DMA_Read_IP_19_170316.png
波形5

前に示した全体波形では、outs_tlast が時々 1 変化していたのが見えたと思うが、画像フレームのスタート時には、outs_tuser が 1 クロック間だけ 1 となっているのがわかる。
と言う訳で完全に動作しているようだ。

次に、論理合成後の機能シミュレーションを行う。
Flow Navigator の Simulation -> Run Simulation -> Run Post-Synthesis Functional Simulation を選択する。

Post-Synthesis Functional Simulation での全体波形を示す。
DMA_Read_IP_21_170316.png
波形6

DMA_Read_IP_22_170316.png
波形7

やはり、Post-Synthesis Functional Simulation で波形が出てこない。

DMA Read IPのレジスタを設定するAXI4-Lite Slave アクセスを拡大してみよう。
DMA_Read_IP_23_170316.png
波形8

こちらは問題ないようだ。
  1. 2017年03月17日 05:32 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS で DMA Read IP を作る2(絶対アドレス指定版)

Vivado HLS で DMA Read IP を作る(絶対アドレス指定版)”の続き。

Vivado HLS で DMA Read IP を作る(絶対アドレス指定版)”では、DMA Read IPを作成したが、”Vivado HLSで作ったDMA Read IP を実機でテスト1(動作しない)”で実機で動作を確認しても動作しなかった。
DMA Read IP を単体でシミュレーション3(DMA Read IP単体で論理合成後にシミュレーション)”では、DMA Read IPを単体でシミュレーションしたが、論理シミュレーションはそれらしく動いても Post-Synthesis Fuctional Simulation では、動作しないという問題があった。これは、IOがオーバーフローしているからかもしれないということで、Vivado 2016.4 でテストしてすることにした。

DMA_Read_Addr_Virtex を示す。シミュレーション用のVivado 2016.4 プロジェクトを論理合成したときに、IOがオーバーフローしないように、Virtex7 の xc7vx980tffg1928-2 を使用している。
DMA_Read_IP_1_170316.png

なお、”Vivado HLS で DMA Read IP を作る(絶対アドレス指定版)”では、3フレームを一度に処理していたのだが、今回は、1フレーム分の処理に変更した。

C シミュレーションを行った。
DMA_Read_IP_2_170316.png

dma_result0.bmp を見ると正常に「A」の文字が見える。

Cコードの合成を行った。その結果を示す。
DMA_Read_IP_3_170316.png

Latency は 3083 クロックで、64 ピクセル x 48 行の「A」という画像の総ピクセル値 3072 から 11 クロックしか離れていないので、ほぼ 1 クロックで 1 ピクセルを処理することができている。

C/RTL協調シミュレーションを行ったところ、エラーになってしまった。
DMA_Read_IP_4_170316.png

「ERROR: [COSIM 212-4] *** C/RTL co-simulation finished: FAIL ***」を調べると、”AR# 61063 Vivado HLS 2014.2 : C/RTL 協調シミュレーションに関する問題を調査するためのデバッグ ガイド”が見つかった。そこに”Vivado HLS: Debug Guide for investigating C/RTL co-simulation issues”のリンクがあった。Vivado HLS: Debug Guide for investigating C/RTL co-simulation issuesを見ても原因はよくわからない?

IP 化を行った。
Vivado RTL Synthesis にチェックを入れた。
DMA_Read_IP_5_170316.png

結果を示す。
DMA_Read_IP_6_170316.png

Resource Usage のLUT が合成結果(1269 ) の半分程度の 695 になっている。ロジックが消されている恐れがある。

今までは、テスト用の64 ピクセル x 48 行の「A」という画像でやっていたので、800 ピクセル x 600 行の実際に処理する画像用に値を切り替えた。
もう一度、C コードの合成を行った。
DMA_Read_IP_7_170316.png

IP 化を行った。やはり LUT は合成時の約半分になっている。
DMA_Read_IP_8_170316.png

DMA_Read.h を示す。

// DMA_Read.h
// 2016/07/14 by marsee
// 2016/09/18 : BURST_LENGTH を追加
//

#ifndef __DMA_READ_H__
#define __DMA_READ_H__

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600

//#define HORIZONTAL_PIXEL_WIDTH    64
//#define VERTICAL_PIXEL_WIDTH    48

#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define MAX_FRAME_NUMBER    3

#define DMA_WRITE_MODE    0
#define FREE_RUN_MODE    1

#define MEMCPY_LENGTH    (HORIZONTAL_PIXEL_WIDTH*4)

#endif


DMA_Read_addr.cpp を示す。

// DMA_Read_addr.cpp
// 2016/07/13 by marsee
//
// frame_buffer0, frame_buffer1, frame_buffer2 には3つのフレームバッファのアドレスを入れる
// mode = 0 : DMA Write IP の active_frame を見て、その1つ前のフレームをDMA Readするモード(DMA_WRITE_MODE)
// mode = 1 : フリーラン モード(FREE_RUN_MODE)
//
// 2017/03/15 : 1フレーム分のDMAに変更
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "DMA_Read.h"

int DMA_Read_addr(volatile int *in, hls::stream<ap_axis<32,1,1,1> >& outs,
        unsigned int frame_buffer0, unsigned int frame_buffer1,
        unsigned int frame_buffer2, ap_uint<2> & active_frame,
        ap_uint<1> mode){
#pragma HLS INTERFACE s_axilite port=mode
#pragma HLS INTERFACE ap_none register port=active_frame
#pragma HLS INTERFACE s_axilite port=frame_buffer0
#pragma HLS INTERFACE s_axilite port=frame_buffer1
#pragma HLS INTERFACE s_axilite port=frame_buffer2
#pragma HLS INTERFACE m_axi depth=3072 port=in offset=off
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE s_axilite port=return

    ap_axis<32,1,1,1> pix;
    int dma_index;
    static int n = 0;

    if (mode == DMA_WRITE_MODE){
        n = (int)active_frame;
    }else{
        n++;
        if (n > 2)
            n = 0;
    }

    switch (n){ // 1つ前のフレームバッファを読みだす
        case 0 :
            dma_index = frame_buffer2/sizeof(int);
            break;
        case 1 :
            dma_index = frame_buffer0/sizeof(int);
            break;
        case 2 :
            dma_index = frame_buffer1/sizeof(int);
            break;
        default :
            dma_index = frame_buffer0/sizeof(int);
            break;
    }

    for (int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        for (int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS PIPELINE II=1
            pix.data = in[dma_index+(y*HORIZONTAL_PIXEL_WIDTH)+x];

            if (y==0 && x==0)
                pix.user = 1;
            else
                pix.user = 0;

            if (x == (HORIZONTAL_PIXEL_WIDTH-1))
                pix.last = 1;
            else
                pix.last = 0;

            outs << pix;
        }
    }

    return 0;
}


DMA_Read_addr_tb.cpp を示す。

// DMA_Read_addr_tb.cpp
// 2016/07/15 by marsee
// 2017/03/16 : 3フレーム処理から1フレーム処理に変更
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <ap_axi_sdata.h>

#include "DMA_Read.h"
#include "bmp_header.h"

int DMA_Read_addr(volatile int *in, hls::stream<ap_axis<32,1,1,1> >& outs,
        unsigned int frame_buffer0, unsigned int frame_buffer1,
        unsigned int frame_buffer2,  ap_uint<2> & active_frame,
        ap_uint<1> mode);

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > outs_dummy;
    hls::stream<ap_axis<32,1,1,1> > outs;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals, vals_dummy;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw;
    int *rd_bmp, *hw_lapd;
    int blue, green, red;
    ap_uint<2> active_frame = 0;
    int *frame_buffer;

    if ((fbmpr = fopen("test.bmp""rb")) == NULL){ // test.bmp をオープン
    //if ((fbmpr = fopen("road_1.bmp", "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(char), 2, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(long), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(short), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(short), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(long), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }

    int *buf;
    if ((buf =(int *)malloc(3 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate buf memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // frame buffer をアロケートする、3倍の領域を取ってそれを3つに分ける
    if ((frame_buffer =(int *)malloc(MAX_FRAME_NUMBER * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate frame_buffer0 ~ 2\n");
        exit(1);
    }

    // 3 つのフレームバッファにそれぞれ'A' を入力する(1つに変更)
    memcpy(frame_buffer, rd_bmp, bmpihr.biHeight * bmpihr.biWidth * sizeof(int));

    memcpy((int *)((unsigned int)frame_buffer + bmpihr.biHeight * bmpihr.biWidth * sizeof(int)),
        rd_bmp, bmpihr.biHeight * bmpihr.biWidth * sizeof(int));

    memcpy((int *)((unsigned int)frame_buffer + 2 * bmpihr.biHeight * bmpihr.biWidth * sizeof(int)),
        rd_bmp, bmpihr.biHeight * bmpihr.biWidth * sizeof(int));

    DMA_Read_addr((volatile int *)0, outs_dummy, (unsigned int)frame_buffer,
        (unsigned int)frame_buffer+(bmpihr.biWidth * bmpihr.biHeight * sizeof(int)),
        (unsigned int)frame_buffer+(2 * (bmpihr.biWidth * bmpihr.biHeight) * sizeof(int)),
        active_frame, DMA_WRITE_MODE);

    DMA_Read_addr((volatile int *)0, outs, (unsigned int)frame_buffer,
        (unsigned int)frame_buffer+(bmpihr.biWidth * bmpihr.biHeight * sizeof(int)),
        (unsigned int)frame_buffer+(2 * (bmpihr.biWidth * bmpihr.biHeight) * sizeof(int)),
        active_frame, FREE_RUN_MODE);

    // outs ストリームのデータを buf に入力する
    //for (int k=0; k<3; k++){
        int k = 0;
        for(int j=0; j < bmpihr.biHeight; j++){
            for(int i=0; i < bmpihr.biWidth; i++){
                outs >> vals;
                outs_dummy >> vals_dummy;
                ap_int<32> val = vals.data;
                buf[(k*bmpihr.biWidth*bmpihr.biHeight)+(j*bmpihr.biWidth)+i] = (int)val;
            }
        }
    //}

    // DMAされたデータをBMPフィルに書き込む
    char output_file[] = "dma_result0.bmp";
    //for (int i=0; i<MAX_FRAME_NUMBER; i++){
        int i=0;
        switch (i){
            case 0:
                strcpy(output_file,"dma_result0.bmp");
                break;
            case 1:
                strcpy(output_file,"dma_result1.bmp");
                break;
            case 2:
                strcpy(output_file,"dma_result2.bmp");
                break;
        }
        if ((fbmpw=fopen(output_file, "wb")) == NULL){
            fprintf(stderr, "Can't open %s by binary write mode\n", output_file);
            exit(1);
        }
        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(char), 2, fbmpw);
        fwrite(&bmpfhr.bfSize, sizeof(long), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved1, sizeof(short), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved2, sizeof(short), 1, fbmpw);
        fwrite(&bmpfhr.bfOffBits, sizeof(long), 1, fbmpw);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

        // RGB データの書き込み、逆順にする
        int offset = i * bmpihr.biWidth * bmpihr.biHeight;
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = buf[offset+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (buf[offset+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (buf[offset+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpw);
                fputc(green, fbmpw);
                fputc(red, fbmpw);
            }
        }
        fclose(fbmpw);
    //}
    free(rd_bmp);
    free(frame_buffer);
    return 0;
}

  1. 2017年03月16日 05:17 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

BNN-PYNQをアップグレード

BNN-PYNQが頻繁に変更されているので、PYNQボードのBNN-PYNQをアップグレードした。

ネットで検索したところ、アップグレードは pip install --upgrade で良いそうだ。
sudo pip3.6 install --upgrade git+https://github.com/Xilinx/BNN-PYNQ.git
コマンドを実行した。
BNN-PYNQ_37_170314.png

~/jupyter_notebooks/bnn を見てみると、更新されていたが日時がおかしい。
BNN-PYNQ_38_170314.png

date コマンドで見てみると、UTC だった。これなら仕方ないがJST に修正しよう。
sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime
これで、JST に変更できた。
BNN-PYNQ_39_170314.png
  1. 2017年03月14日 04:15 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

XilinxのBNN-PYNQをやってみる4(Hardware design rebuilt 2)

XilinxのBNN-PYNQをやってみる3(Hardware design rebuilt 1)”の続き。

前回は、BNN-PYNQの cnv-pynq をHardware design rebuilt したので、今回はもう1つの lfc-pynq をHardware design rebuilt してみよう。

最初に、BNN-PYNQ/bnn/src/network ディレクトに cd した。
cd /home/masaaki/BNN-PYNQ/bnn/src/network

もうすでにXILINX_BNN_ROOT 環境変数はセットしてある。
export XILINX_BNN_ROOT=/home/masaaki/BNN-PYNQ/bnn/src/

BNN-PYNQ/bnn/src/network ディレクトリの make_hw.sh を実行して、lfc-pynq のVivado HLS プロジェクトとVivado プロジェクトを生成する。
./make-hw.sh lfc-pynq pynq a
BNN-PYNQ_29_170312.png

すると、前回と同様に/home/masaaki/BNN-PYNQ/bnn/src/network/output ディレクトリのbitstream, hls-syn, report, vivado の各ディレクトリに lfc-pynq ディレクトリができていた。
BNN-PYNQ_30_170312.png

lfc-pynq のVivado HLS 2016.4 プロジェクトを開いた。
BNN-PYNQ_31_170312.png

合成レポートを示す。やはり、Target が 5.00 ns でEstimated が 7.90 ns だった。
BNN-PYNQ_32_170312.png

リソース使用量は cnv-pynq の方が、lfc-pynq よりも多かった。

次に、lfc-pynq のVivado 2016.4 プロジェクトを示す。
BNN-PYNQ_33_170313.png

レポートを示す。
BNN-PYNQ_36_170313.png

タイミングはメットしていた。

procsys ブロックデザインを示す。前回と同じだと思う。
BNN-PYNQ_34_170313.png

Address Editor を示す。
BNN-PYNQ_35_170313.png
  1. 2017年03月13日 05:06 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

XilinxのBNN-PYNQをやってみる3(Hardware design rebuilt 1)

XilinxのBNN-PYNQをやってみる2(jupyter notebook)”の続き。

Ubuntu16.04にVivado 2016.4をインストール”でVirtualBoxに新しいVirtualマシンを作って、Ubuntu 16.04 をインストールして、Vivado 2016.4 をインストールできたので、やっとBNN-PYNQのHardware design rebuilt がやれる環境が整った。それで、BNN-PYNQのHardware design rebuilt をやってみることにした。今回はcnv-pynq をやってみた。

BNN-PYNQ は、短い期間でアップデートされているので、GitHub からZIP ファイルをダウンロードするとアップデートするのが難しくなるので、git clone することにした。新しいUbuntu 16.04 上にBNN-PYNQ を git clone した。
git clone https://github.com/Xilinx/BNN-PYNQ.git
BNN-PYNQ_19_170311.png

これで、ホームディレクトリ上にBNN-PYNQ がクローンされた。

次に、BNN-PYNQのREADME.md のHardware design rebuilt を参照しながら、cnv-pynq のVivado HLS プロジェクトとVivado プロジェクトを生成する。

最初に、BNN-PYNQ/bnn/src/network ディレクトに cd した。
cd /home/masaaki/BNN-PYNQ/bnn/src/network

XILINX_BNN_ROOT 環境変数にBNN-PYNQ/bnn/src/ をセットする。
export XILINX_BNN_ROOT=/home/masaaki/BNN-PYNQ/bnn/src/

BNN-PYNQ/bnn/src/network ディレクトリの make_hw.sh を実行して、cnv-pynq のVivado HLS プロジェクトとVivado プロジェクトを生成する。
./make-hw.sh cnv-pynq pynq a

長い時間がかかったが、cnv-pynq のVivado HLS プロジェクトとVivado プロジェクトを生成することができた。その結果のディレクトリとファイルを示す。
BNN-PYNQ_20_170312.png

BNN-PYNQ/bnn/src/network ディレクトリの下に、output ディレクトリができて、その下に bitstream, hls-syn, report, vivado ディレクトリができていた。
hls-syn ディレクトリの下の cnv-pynq-pynq の下には、Vivado HLS のプロジェクトが生成されていた。
vivado ディレクトリの下の cnv-pynq-pynq の下には、Vivado のプロジェクトが生成されていた。

さっそく、Vivado HLS 2016.4 を立ち上げて、cnv-pynq-pynq の下のプロジェクトを開いた。
BNN-PYNQ_21_170312.png

合成結果を示す。
BNN-PYNQ_22_170312.png

Target が 5.00 ns に対して、Estimated は 7.90 ns で満たしていないが、実際のクロックは 100 MHz なので、大丈夫だろう?
BRAM_18K は96 % 使用している。DSP48E は 14 % 、FF は 26 %、LUT は 80 % 使用している。

次に、Vivado 2016.4 を立ち上げて、vivado ディレクトリの下の cnv-pynq-pynq の下のVivado プロジェクトを開いてみた。
BNN-PYNQ_23_170312.png

procsys ブロックデザインを示す。
BNN-PYNQ_24_170312.png

Address Editor を示す。
BNN-PYNQ_25_170312.png

Project Summary を示す。タイミング違反が出ている。
LUT はVivado HLS では 80 % 使用していたはずが、54 % になっている。BRAM も少ないので、ロジックを消されたのかもしれない?
BNN-PYNQ_26_170312.png

タイミング違反を調べるためにImplemented Design を開いた。
BNN-PYNQ_27_170312.png

BlackBoxJam_0 間がタイミング違反になっているので、Vivado HLS の合成したIP がタイミング違反になっている。
BNN-PYNQ_28_170312.png

このタイミング違反は直すのが難しそうです。Vivado HLS でTarget を 4 ns, 3ns にしてみたんですが、合成結果のEstimated は7.9 ns で変化がありませんでした。
Vivadoのimplementation のオプションのStrategy にPerformance_ExtraTimingOpt を選択してあるので、これ以上変更しても無理そうでした。
  1. 2017年03月12日 05:52 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

「モアナと伝説の海」(映画)を見てきました

「モアナと伝説の海」(映画)を見てきました。映像はとっても綺麗で良かったです。歌も良かったです。内容は少し平凡かもしれませんけど。。。
  1. 2017年03月11日 21:13 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Ubuntu16.04にVivado 2016.4をインストール

今日はUbuntu16.04にVivado 2016.4をインストールする覚書を書いておこうと思う。
ちなみに、私の環境は、VirtualBoxにUbuntu16.04をインストールしてある。

まずは、Xilinx Japan のサイトに行って、サポート→ダウンロードとライセンスを選択して、ダウンロードのサイトへ行く。

Vivado HLx 2016.4: WebPACK および Editions - Linux 用自己解凍型ウェブ インストーラー (BIN - 80.67 MB)をダウンロードする。
すると、Xilinx_Vivado_SDK_2016.4_0124_1_Lin64.bin がダウンロードできる。

Ubuntuでダウンロードしていれば、そのままだが、Windowsでダウンロードした場合は、Ubuntuに持っていく。

まずは、実行パーミッションを与える必要がある。
chmod +x Xilinx_Vivado_SDK_2016.4_0124_1_Lin64.bin

次に、Xilinx_Vivado_SDK_2016.4_0124_1_Lin64.bin を実行しよう。その際に、/opt/Xilinxに書くのでスーパーユーザーの権限が必要だ。
sudo ./Xilinx_Vivado_SDK_2016.4_0124_1_Lin64.bin

スーパーユーザーのパスワードを入力すると、Vivado 2016.4 Installer が起動する。
Ubuntu_Vivado_install_1_170311.png

Select Install Type では、Xilinx のUser ID とPassword を入れる。
Ubuntu_Vivado_install_2_170311.png

Accept License Agreements では、3つのチェックボックスにチェックを入れる。
Ubuntu_Vivado_install_3_170311.png

Select Ediition to Install では、私はVivado HL Webpack のラジオボタンを選択したが、これはお好みで。
Ubuntu_Vivado_install_4_170311.png

Vivado HL Webpack の画面では、Software Development Kit (SDK) のチェックを入れたほうが良い。
Ubuntu_Vivado_install_5_170311.png

後はデフォルトで良いと思うので、省略。
最初に5GB 以上ダウンロードしてからインストールを始めるので、時間がかかるのは覚悟した方が良い。

License Manager が起動するが、Vivado HL Webpack はライセンスは必要ないので、終了させておく。

インストールが終了しても、vivado コマンドを入れてもVivado は起動ないので、設定を行う。

LX Terminal から
gedit .bashrc
コマンドを実行する。

.bashrc の最後に
source /opt/Xilinx/Vivado/2016.4/settings64.sh
alias xsdk='env SWT_GTK3=0 xsdk'
alias vivado='env SWT_GTK3=0 vivado'

を追加する。
Ubuntu_Vivado_install_6_170311.png
なお、xsdk のスクリプトに関しては、「VivadoやXilinx SDKをLinux (Ubuntu) で動かすメモ (Ubuntu 16.04 LTS, Vivado 2016.4, 64bit環境)」から引用させて頂いた。これが無いと xsdk が起動できない。vivado もGTK3 を無効にしておかないと vivado から SDK を起動できない。

source .bashrc
で.bashrc の内容を反映する。これで、vivado コマンドが実行できるようになった。

ホームディレクトリの.Xilinx ディレクトリの一部がのユーザーとグループが root なので、ユーザーに変更する。ホームディレクトリに移動しておく(cd を実行すれば良い) なお、masaaki は自分のアカウント名に修正してください。
sudo chown -R masaaki:masaaki .Xilinx/

なお、ケーブル・ドライバがインストールされていないそうなので、下のコマンドでインストールした。これは、「VivadoやXilinx SDKをLinux (Ubuntu) で動かすメモ (Ubuntu 16.04 LTS, Vivado 2016.4, 64bit環境)」から引用させて頂いた。私のとディレクトリが違っているので、コマンドを書き換えた。
sudo /opt/Xilinx/Vivado/2016.4/data/xicom/cable_drivers/lin64/install_script/install_driverst/install_drivers
Ubuntu_Vivado_install_8_170311.png
エラーになってしまった。これは、ビットストリームのダウンロードに影響するので、最悪Windowsに持って行ってダウンロードすればよいと思うので、とりあえずはこのままとした。
(2017/07/26:追記)
オープンソースMCUをつくってArduinoでプログラミングしてみよう!”によると、cd してドライバをインストールすればドライバがインストールできるようだ。直接、パスを指定してインストールコマンドを起動するとエラーになってしまうようだ。つまり以下のようにすればよい。
cd /opt/Xilinx/Vivado/2016.4/data/xicom/cable_drivers/lin64/install_script/
sudo ./install_drivers


(2017/07/28:追記)
Vivado 2017.2 では、階層が1つ深く、
cd /opt/Xilinx/Vivado/2016.4/data/xicom/cable_drivers/lin64/install_script/install_drivers
sudo ./install_drivers

だった。2017.1 からなのかもしれない?

LX Termnal 上で vivado とタイプすると Vivado 2016.4 が起動する。
Ubuntu_Vivado_install_7_170311.png

.bashrc で vivado を起動するときにGTK3 を無効にしておいたので、vivado でFile メニューから Launch SDK でSDK を起動しても起動できた。
Ubuntu_Vivado_install_9_170311.png

Ubuntu_Vivado_install_10_170311.png

ちなみにSDK単体は xsdk で、Vivado HLS は vivado_hls コマンドで起動できる。
  1. 2017年03月11日 08:06 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

XilinxのBNN-PYNQをやってみる2(jupyter notebook)

XilinxのBNN-PYNQをやってみる1(インストール編)”の続き。

前回は、BNN-PYNQをインストールした。今回は、jupyter notebook の bnn/Cifar10.ipynb をやってみた。

まずは、私のルーターがPYNQボードに振ったIP アドレス:9090 をブラウザでアクセスした。

パスワードを聞かれるので、「xilinx」と入力した。

jupyter が表示された。
BNN-PYNQ_9_170308.png

bnn をクリックして、その下に行き、Cifar10.ipynb をクリックして実行した。
BNN-PYNQ_10_170308.png

Cifar10.ipynb が表示された。
BNN-PYNQ_11_170308.png

Cell をクリックして、Run All を選択した。

すべてのPython コードが実行された。結果を示す。
BNN-PYNQ_12_170308.png

BNN-PYNQ_13_170308.png

BNN-PYNQ_14_170308.png

BNN-PYNQ_15_170308.png

BNN-PYNQ_16_170308.png

BNN-PYNQ_17_170308.png

BNN-PYNQ_18_170308.png
  1. 2017年03月09日 05:29 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

XilinxのBNN-PYNQをやってみる1(インストール編)

XilinxのBNN-PYNQをやって見たいということで、やってみました。BNN-PYNQはBinarized Neural Network (BNN) on PYNQ だそうです。

まずは、PYNQボードを用意します。

使用している Linux のイメージは、pynq_z1_image_2017_02_10 です。
とりあえず、

sudo apt-get update
sudo apt-get upgrade

をしました。
次に、XilinxのBNN-PYNQに書いてあったように

sudo pip3.6 install git+https://github.com/Xilinx/BNN-PYNQ.git

を実行しました。
BNN-PYNQ_1_170307.png

~/jupyter_notebooks/bnn ディレクトリができていました。
BNN-PYNQ_2_170307.png

その他のBNN-PYNQ のファイルは /opt/python3.6/lib/python3.6/site-package/bnn ディレクトリに入っていました。
BNN-PYNQ_3_170307.png

bitstreams ディレクトリには、cnv-pynq-pynq.bit, cnv-pynq-pynq.tcl, lfc-pynq-pynq.bit, lfc-pynq-pynq.tcl が入っています。
BNN-PYNQ_4_170307.png

libraries ディレクトリには、以下のファイルがあります。(書いていくのが面倒になってきました)
BNN-PYNQ_5_170307.png

params ディレクトリの下です。cifar10, mnist, road-signs, streetview のディレクトリがあって、その下には、***-weights.bin や ***-thres.bin が並んでいます。
BNN-PYNQ_6_170307.png

__pycache__ ディレクトリです。
BNN-PYNQ_7_170307.png

src フォルダです。
BNN-PYNQ_8_170307.png

ちなみに、PYNQボードには、nautilus, geany, geeqie をインストールしてあります。パソコンには、Xming をインストールしてPYNQボードのX Window を持ってこられるようにしています。上の画像は nautilus のX を持ってきてパソコンで表示したときの画像です。
  1. 2017年03月08日 05:31 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋のまとめサイトの更新(2017年3月6日)

FPGAの部屋のまとめサイトを更新しました。
FPGAのマイクロプロセッサ演算処理のFPGAへの適用方法を追加して、その他のカテゴリーの記事を更新しました。
  1. 2017年03月06日 04:39 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

PYNQ祭りに参加してきました

昨日は、「FPGAエクストリーム・コンピューティング 番外編:PYNQ祭り」に参加して発表してきました。

PYNQでカメラ画像をリアルタイムFASTX コーナー検出」という題で発表してきました。スライドはSlideShareにアップしました。

いろいろな発表が聞けて、しかも、懇親会ではGraham Schelleさんと写真も取ってもらったり、いろいろな方とお話しすることができてとても楽しかったです。皆さん、ありがとうございました。

皆さんの持ってきたPYNQボードです。これだけ並ぶと壮観ですね。
PYNQ_maturi_170305.jpg
  1. 2017年03月05日 04:49 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

PYNQボードのFASTX コーナー検出にラプラシアンフィルタIPとアンシャープ・マスクキング・フィルタIPを追加6(Jupyter Notebookで開発中2)

PYNQボードのFASTX コーナー検出にラプラシアンフィルタIPとアンシャープ・マスクキング・フィルタIPを追加5(Jupyter Notebookで開発中)”の続き。

いろいろとJupyter Notebook でやってはいるが、まだカメラ画像が表示されない。ちなみに今使っているPYNQボードのMicro SDカードのイメージは 2017/02/10 以前のものだ。

症状としては、ディスプレイに映像信号が出ていない。ブルー画面のままになっている。
下に、Jupyter Notebook を Python に直したコードを貼っておく。

# coding: utf-8

# In[51]:

import os
import pynq.drivers.xlnk
from pynq.mmio import MMIO
import time

# fastx、ラプラシアンフィルタ、アンシャープ・マスクキング・フィルタのビットファイルをオープン

# bitfile open
with open('/home/xilinx/pynq/bitstream/pynq_fastx_wrapper.bit', 'rb') as bf:
    buf = bf.read()

with open('/sys/devices/soc0/amba/f8007000.devcfg/is_partial_bitstream', 'w') as fd:
    fd.write('0')

# /dev/xdevcfgにビットストリームを書き込む
with open('/dev/xdevcfg', 'wb') as f:
    f.write(buf)

# CMA領域を確保する
mmu = pynq.drivers.xlnk.xlnk()
print(mmu)

# 800x600x4バイトをCMA領域に割り当てて、仮想アドレスと物理アドレスを表示
buf = mmu.cma_alloc(800*600*4)
buf_phy = pynq.drivers.xlnk.libxlnk.cma_get_phy_addr(buf)
print("virtal", buf, "physical", hex(buf_phy))

# AXI VDMAのレジスタ領域をMMIOにとしてマップする、0x100 = 256バイトをアサイン
vdma = MMIO(0x43000000, 0x10000)
print(vdma)

# VDMAの設定
vdma.write(0x30, 0x4) # S2MM_VDMACR (Reset = 1)
i=0
while (vdma.read(0x30) & 0x4) == 0x4 :
    i += 1
vdma.write(0x30, 0x4) # S2MM_VDMACR (Reset = 1)
while (vdma.read(0x30) & 0x4) == 0x4 :
    i += 1
rd_data = vdma.read(0x30)
print('%x' % rd_data)
vdma.write(0x48, 3) # S2MM_FRMSTORE (0x48) register
vdma.write(0x30, 0x00010002) # S2MM_VDMACR (IRQFrameCount=1, Circular_Park=1)
vdma.write(0xA4, 800*4) #  S2MM_HSIZE
vdma.write(0xA8, 800*4) # S2MM_FRMDLY_STRIDE
vdma.write(0xAC, buf_phy) # S2MM_START_ADDRESS1
vdma.write(0xB0, buf_phy) # S2MM_START_ADDRESS2
vdma.write(0xB4, buf_phy) # S2MM_START_ADDRESS3
vdma.write(0x30, 0x00010003) # S2MM_VDMACR (IRQFrameCount=1, Circular_Park=1, RS=1(Run))
while (vdma.read(0x34) & 0x1) == 0x1 :
    i += 1
rd_data = vdma.read(0x30)
print('%x' % rd_data)

# FASTXコーナー検出IPの設定
fastx = MMIO(0x43C30000, 0x10000)
fastx.write(0x10, 600) # rows
fastx.write(0x18, 800) # cols
fastx.write(0x20, 20) # threshold
fastx_data = fastx.read(0x20)
print(fastx_data)

# ラプラシアンフィルタIPの設定
lap = MMIO(0x43C50000, 0x10000)
lap_data = lap.read(0)
print(lap_data)

# アンシャープ・マスキング・フィルタIPの設定
usm = MMIO(0x43C60000, 0x10000)
usm.write(0x18, 1) # usm_fil_enable_V
usm.write(0x20, 10) # k = 2.5
usm_data = usm.read(0x20)
print(usm_data)

# axisスイッチ0, 1 の初期設定(カメラ画像を選択)
axis_sw0 = MMIO(0x43C10000, 0x10000)
axis_sw1 = MMIO(0x43C20000, 0x10000)
axis_sw1.write(0x40, 0) # カメラをイネーブル
axis_sw1.write(0x44, 0x80000000) # FASTX
axis_sw1.write(0x48, 0x80000000) # ラプラシアンフィルタ
axis_sw1.write(0x4C, 0x80000000) # アンシャープ・マスキング・フィルタ
axis_sw1.write(0x0, 0x2) # Commit
axis_sw0.write(0x40, 0) # カメラを選択
axis_sw0.write(0x0, 0x2) # Commit
axis1_data = axis_sw1.read(0x44)
print('%x' % axis1_data)
axis0_data = axis_sw0.read(0x40)
print('%x' % axis0_data)

# AXI VDMA Start
#vdma.write(0xA0, 600) # S2MM Vertical Size 
vdmad = vdma.read(0xA0)
print(vdmad)

# ビットマップ・ディスプレイ・コントローラ、カメラ・コントローラ、カメラ用I2Cの設定
bmdc = MMIO(0x43C00000, 0x10000) # bitmap display controller
camc = MMIO(0x43C40000, 0x10000) # camera controller
cam_i2c = MMIO(0x41600000, 0x10000) # I2C controller for camera

# ビットマップ・ディスプレイ・コントローラのベースアドレス、カメラ・コントローラON
bmdc.write(0x0, buf_phy)
camc.write(0x0, buf_phy)
camc.write(0x4, 0) # One_shot_mode is disabled

bmdc_data = bmdc.read(0)
print('%x' % bmdc_data)
camc_data = camc.read(0)
print('%x' % camc_data)


# カメラ設定用I2Cの初期化と設定書き込み
cam_i2c.write(0x100, 0x2) # reset tx fifo ,address is 0x100, i2c_control_reg
cam_i2c.write(0x100, 0x1) # enable i2c

def cam_i2c_write_sync():
    time.sleep(1/1000) # 1ms wait

def cam_i2c_write(cam_i2c, device_addr, write_addr, write_data):
    cam_i2c.write(0x108, 0x100 | (device_addr & 0xfe)) # Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    cam_i2c.write(0x108, write_addr)
    cam_i2c.write(0x108, (write_data >> 8)|0xff) # first data
    cam_i2c.write(0x108, 0x200 | (write_data & 0xff)) # second data
    cam_i2c_write_sync()

# カメラの設定
cam_i2c_write(cam_i2c, 0xba, 0xf0, 0x1) # Changed regster map to IFP page 1
cam_i2c_write(cam_i2c, 0xba, 0x97, 0x20) # RGB Mode, RGB565

mmu.cma_get_buffer(buf,64)[:]


一旦、BOOT.bin を作ってやってみようと思っている。
  1. 2017年03月04日 05:24 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

PYNQボードのFASTX コーナー検出にラプラシアンフィルタIPとアンシャープ・マスクキング・フィルタIPを追加5(Jupyter Notebookで開発中)

PYNQボードのFASTX コーナー検出にラプラシアンフィルタIPとアンシャープ・マスクキング・フィルタIPを追加4(SDK)”の続き。

前回は、SDK のベアメタル・アプリケーションソフトでPYNQボード用のFASTX コーナー検出とラプラシアンフィルタ、アンシャープ・マスクキング・フィルタをテストできた。今回は、Jupyter Notebook を使用してPython で開発している。

CMA領域の使用方法は、@hasegaw さんにVDMA のテストコードを教えて頂いたので、それを参考に実装している。

慣れないPython でやり方を検索しながら作っているので、時間がかかっている。作りかけだがJupyter Notebook の画面を貼っておく。
pynq_de_other_filters_27_170303.png

pynq_de_other_filters_28_170303.png

pynq_de_other_filters_29_170303.png

明日のPYNQ祭りに間に合えば良いのだが。。。
  1. 2017年03月03日 05:15 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

「サバイバルファミリー」(映画)を見てきました

昨日、娘の卒業式の後で、奥さんと「サバイバルファミリー」(映画)を見てきました。
東日本大震災の時のことを思い出してしまいました。決して、他人事じゃないです。。。
という気持ちで見ていたので、見入っていたのですが、途中で汽車が来て助けてくれたのは、なぜなんだろう?という疑問が残りました。
  1. 2017年03月02日 13:05 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋のブログの2月のアクセス数

今、PYNQ祭りに向けて、FASTXコーナー検出などを動かすためにPython コードを書こうと思っていますが、寝坊の影響で頭が良く回りません。

今日は、2月のFPGAの部屋のブログのアクセス数を書いてみようと思います。
2月のFPGAの部屋のブログのアクセス数はFC2 ブログが 40,699 アクセス、livedoor ブログが 4,990 アクセスの合計 45,689 アクセスでした。

日本を含め32か国からアクセスされました。(.com とかがあるので正確ではありませんが)
FPGA_room_4_170301.png

パソコンの使用言語も見てみると、17か国語のパソコンからアクセスされています。
FPGA_room_3_170301.png
  1. 2017年03月01日 22:28 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0