FC2カウンター FPGAの部屋 PYNQ

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

FPGAの部屋

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

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

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

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
»