Zynq+PyCoRAM(+Debian)入門

97
Zynq + PyCoRAM (+Debian) 入門 高前田 伸也 奈良先端科学技術大学院大学 情報科学研究科 E-mail: shinya_at_is_naist_jp

Transcript of Zynq+PyCoRAM(+Debian)入門

Page 1: Zynq+PyCoRAM(+Debian)入門

Zynq + PyCoRAM (+Debian) 入門

高前田 伸也

奈良先端科学技術大学院大学 情報科学研究科

E-mail: shinya_at_is_naist_jp

Page 2: Zynq+PyCoRAM(+Debian)入門

チュートリアルの目的

n 「Zynq+Vivado HLS入門」や「Zynq+Synthesijer入門」と同様にZynq上でPyCoRAMで生成したIPコアを用いたHW/SWシステムを動作させる方法を習得する l  ZynqにIPコアを組み込みDebian Linux上から利用します

n ターゲットボード: ZedBoard l  ZC706なども適宜読み替えれば同様の手順で可能

n 開発環境: Ubuntu (64-bit) 14.04 LTS

n  PyCoRAMを利用するためにPythonなどが必要です l  Linuxの利用を推奨

n 主な流れは 「Zynq+Vivado HLS入門」「Zynq+Synthesijer入門」とにならっています

2015-03-19 Shinya T-Y, NAIST 2

Page 3: Zynq+PyCoRAM(+Debian)入門

ゴールのシステム構成 n メモリコピーを行うハードウェアをARMから利用する

l  ARM上のソフトウェアでDRAM上に初期値を設定

l  IPコアがDRAMからデータを読み込み宛先領域に書き戻す

l  ARM上のソフトウェアで正しくコピーされたかどうか確認する

n  Debian Linuxを利用するリッチなシステム l  OSによるメモリ管理が存在

l 一部メモリ領域をLinux 管理外として割り当て mmapを介して利用

•  PL側は仮想アドレスでは メモリアクセスできない

•  連続する物理メモリ空間を PL側に割り当てる

2015-03-19 Shinya T-Y, NAIST 3

PS ARM

L1 L2

DRAM I/F

PL PyCoRAM IP

(memcpy)

DRAM

HP0 GP0

Zynq

Page 4: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 4

PyCoRAMによる開発

VivadoによるFPGAハードウェア開発

Linuxのビルド

実機検証

Page 5: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 5

Page 6: Zynq+PyCoRAM(+Debian)入門

Icarus Verilog・Python関連のインストール n  apt-getでインストール

n  pipでjinja2(テンプレートエンジン)をインストール

2015-03-19 Shinya T-Y, NAIST 6

sudo apt-get install iverilog gtkwave python3 python3-pip�

pip3 install jinja2�

Page 7: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 7

Page 8: Zynq+PyCoRAM(+Debian)入門

PyCoRAM/Pyverilogのダウンロード n 開発用ディレクトリを作成し そこにPyCoRAMをGitHubからダウンロード

n  PyCoRAMの中にPyverilogをダウンロードし さらにpycoramの中にシンボリックリンクを作成

2015-03-19 Shinya T-Y, NAIST 8

mkdir -p ~/work�cd ~/work�git clone https://github.com/shtaxxx/PyCoRAM.git�cd PyCoRAM�git clone https://github.com/shtaxxx/Pyverilog.git�cd pycoram�ln -s ../Pyverilog/pyverilog�cd ../�

Page 9: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 9

Page 10: Zynq+PyCoRAM(+Debian)入門

memcpyをコンパイルしてみる n おなじみのmemcpyの例を試してみる n  “PyCoRAM/sample/test/memcpy”へ移動しmake build

n  “pycoram_userlogic_v1_00_a”というpcore/IP-XACT 両対応のIPコアのディレクトリが作成される

n 中身が気になる方は”ctrl_thread.py”とuserlogic.vを確認

2015-03-19 Shinya T-Y, NAIST 10

cd sample/test/memcpy�make build�ls�

less ctrl_thread.py�less userlogic.v�

Page 11: Zynq+PyCoRAM(+Debian)入門

userlogic.v

2015-03-19 Shinya T-Y, NAIST 11

`include "pycoram.v"��`define THREAD_NAME "ctrl_thread"��module userlogic # � (� parameter W_A = 10,� parameter W_D = 32,� parameter W_COMM_A = 4� )� (� input CLK,� input RST� );�� reg [W_A-1:0] mem_addr;� reg [W_D-1:0] mem_d;� reg mem_we;� wire [W_D-1:0] mem_q;� � reg [W_D-1:0] comm_d;� reg comm_enq;� wire comm_full;� wire [W_D-1:0] comm_q;� reg comm_deq;� wire comm_empty;� � always @(posedge CLK) begin� if(RST) begin� mem_addr <= 0;� mem_d <= 0;� mem_we <= 0;� comm_d <= 0;� comm_deq <= 0;� comm_enq <= 0;� end else begin� // do nothing� mem_addr <= 0;� mem_d <= 0;� mem_we <= 0;� comm_d <= 0;� comm_deq <= 0;� comm_enq <= 0;� end� end�

CoramMemory1P� #(� .CORAM_THREAD_NAME(`THREAD_NAME),� .CORAM_ID(0),� .CORAM_SUB_ID(0),� .CORAM_ADDR_LEN(W_A),� .CORAM_DATA_WIDTH(W_D)� )� inst_data_memory� (.CLK(CLK),� .ADDR(mem_addr),� .D(mem_d),� .WE(mem_we),� .Q(mem_q)� );�� CoramChannel� #(� .CORAM_THREAD_NAME(`THREAD_NAME),� .CORAM_ID(0),� .CORAM_ADDR_LEN(W_COMM_A),� .CORAM_DATA_WIDTH(W_D)� )� inst_comm_channel� (.CLK(CLK),� .RST(RST),� .D(comm_d),� .ENQ(comm_enq),� .FULL(comm_full),� .Q(comm_q),� .DEQ(comm_deq),� .EMPTY(comm_empty)� );��endmodule� �

何もしないハードウェア (メモリがあるだけ) メモリコピーの振る舞いは Python側で記述 (そもそもPython側の 仕事がDMA転送の管理)

Page 12: Zynq+PyCoRAM(+Debian)入門

ctrl_thread.py

2015-03-19 Shinya T-Y, NAIST 12

DSIZE = 4 # = 32 bit�RAMSIZE = 1024��iochannel = CoramIoChannel(idx=0, datawidth=32)�ram = CoramMemory(idx=0, datawidth=DSIZE*8, size=RAMSIZE, length=1, scattergather=False)�channel = CoramChannel(idx=0, datawidth=32, size=16) # Unused��def body():� # wait request� src = iochannel.read()� dst = iochannel.read()� size = iochannel.read()�� while True:� chunk_size = size if size < RAMSIZE * DSIZE else RAMSIZE * DSIZE� ram.write(0, src, chunk_size/DSIZE) # from DRAM to BlockRAM� ram.read(0, dst, chunk_size/DSIZE) # from BlockRAM to DRAM� size -= chunk_size� src += chunk_size� dst += chunk_size� if size == 0: break�� # notification� iochannel.write(1) ��while True:� body()�

(AXI4/Avalon) slave interface

(AXI4/Avalon) master interface

BRAMからDRAMへDMA転送 DRAMからBRAMへDMA転送

Page 13: Zynq+PyCoRAM(+Debian)入門

testbench.v n このファイルの内容が自動的にテストベンチ本体

(pycoram_userlogic_v1_00_a/test/test_pycoram_userlogic.v) に追記される l  iochannel (Slaveインターフェース)にアクセスする

task文が自動的に生成されるのでそれを利用してアクセス

2015-03-19 Shinya T-Y, NAIST 13

reg [31:0] read_val;��initial begin� #1000;� wait(sim_resetn == 1);� nclk();� iochannel_write_ctrl_thread_coramiochannel_0(0, 0); // src� iochannel_write_ctrl_thread_coramiochannel_0(1024, 0); // dst� iochannel_write_ctrl_thread_coramiochannel_0(128, 0); // size (byte)� nclk();� iochannel_read_ctrl_thread_coramiochannel_0(read_val, 0);� nclk();� #1000;� � nclk();� iochannel_write_ctrl_thread_coramiochannel_0(0, 0); // src� iochannel_write_ctrl_thread_coramiochannel_0(8192, 0); // dst� iochannel_write_ctrl_thread_coramiochannel_0(8192, 0); // size (byte)� nclk();� iochannel_read_ctrl_thread_coramiochannel_0(read_val, 0);� nclk();� #1000;� $finish;�end�

Page 14: Zynq+PyCoRAM(+Debian)入門

シミュレーションで動作確認する n  Icarus Verilogで実行しGTKWaveで波形を確認

2015-03-19 Shinya T-Y, NAIST 14

make sim�make view�

Page 15: Zynq+PyCoRAM(+Debian)入門

GTKWaveで波形を確認する

2015-03-19 Shinya T-Y, NAIST 15

n  RVALIDのフェーズの後にWVALIDのフェーズが来る n アドレス (ARADDR, AWADDR) と データ (RDATA, WDATA) を見ると 正しく転送されているのがわかる

Page 16: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 16

Page 17: Zynq+PyCoRAM(+Debian)入門

Vivadoを起動する n 作業用ディレクトリを作成 (work/vivado_zynq_pycoram) n  “ip”というディレクトリを作成

n その中にPyCoRAM IPコアをコピー

n 設定ファイルを読み込みVivadoを起動

2015-03-19 Shinya T-Y, NAIST 17

mkdir -p ~/work/vivido_zynq_pycoram�cd ~/work/vivido_zynq_pycoram�mkdir ip�

cp -r ~/work/PyCoRAM/sample/test/�memcpy/pycoram_userlogic_v1_00_a ip/�

一行に続けて入力

source /opt/Xilinx/Vivado/2014.4/settings64.sh�vivado &�

Page 18: Zynq+PyCoRAM(+Debian)入門

Open Example Project

2015-03-19 Shinya T-Y, NAIST 18

Page 19: Zynq+PyCoRAM(+Debian)入門

Next

2015-03-19 Shinya T-Y, NAIST 19

Page 20: Zynq+PyCoRAM(+Debian)入門

Project nameを”zed”に

2015-03-19 Shinya T-Y, NAIST 20

Page 21: Zynq+PyCoRAM(+Debian)入門

Base Zynq Designを選択

2015-03-19 Shinya T-Y, NAIST 21

Page 22: Zynq+PyCoRAM(+Debian)入門

ZedBoardを選択

2015-03-19 Shinya T-Y, NAIST 22

Page 23: Zynq+PyCoRAM(+Debian)入門

Finish

2015-03-19 Shinya T-Y, NAIST 23

Page 24: Zynq+PyCoRAM(+Debian)入門

ZedBoardベースシステム完成

2015-03-19 Shinya T-Y, NAIST 24

Page 25: Zynq+PyCoRAM(+Debian)入門

IP Settingsを変更

2015-03-19 Shinya T-Y, NAIST 25

Page 26: Zynq+PyCoRAM(+Debian)入門

Add Repository

2015-03-19 Shinya T-Y, NAIST 26

Page 27: Zynq+PyCoRAM(+Debian)入門

先ほど作成した”ip”ディレクトリを選択

2015-03-19 Shinya T-Y, NAIST 27

Page 28: Zynq+PyCoRAM(+Debian)入門

PyCoRAM IPコアが認識された

2015-03-19 Shinya T-Y, NAIST 28

Page 29: Zynq+PyCoRAM(+Debian)入門

Add IPでPyCoRAM IPコアを追加する

2015-03-19 Shinya T-Y, NAIST 29

Page 30: Zynq+PyCoRAM(+Debian)入門

pycoram_userlogic_v1_0を選択

2015-03-19 Shinya T-Y, NAIST 30

Page 31: Zynq+PyCoRAM(+Debian)入門

PyCoRAM IPコアが追加された ZynqをダブルクリックしてRe-customize IP

2015-03-19 Shinya T-Y, NAIST 31

Page 32: Zynq+PyCoRAM(+Debian)入門

32ビット幅のHP0 Interfaceを追加

2015-03-19 Shinya T-Y, NAIST 32

Page 33: Zynq+PyCoRAM(+Debian)入門

Run Connection Automationを実行

2015-03-19 Shinya T-Y, NAIST 33

Page 34: Zynq+PyCoRAM(+Debian)入門

S_AXI_HP0とcorammemory_0_AXIを接続

2015-03-19 Shinya T-Y, NAIST 34

Page 35: Zynq+PyCoRAM(+Debian)入門

GP0とcoramiochannel_0_AXIを接続

2015-03-19 Shinya T-Y, NAIST 35

Page 36: Zynq+PyCoRAM(+Debian)入門

クロック・リセットを接続(繋ぐ前)

2015-03-19 Shinya T-Y, NAIST 36

Page 37: Zynq+PyCoRAM(+Debian)入門

リセットを接続

2015-03-19 Shinya T-Y, NAIST 37

Page 38: Zynq+PyCoRAM(+Debian)入門

クロックを接続

2015-03-19 Shinya T-Y, NAIST 38

Page 39: Zynq+PyCoRAM(+Debian)入門

アドレスをチェック(変更しない)

2015-03-19 Shinya T-Y, NAIST 39

Page 40: Zynq+PyCoRAM(+Debian)入門

Generate Bitstreamで合成

2015-03-19 Shinya T-Y, NAIST 40

Page 41: Zynq+PyCoRAM(+Debian)入門

聞かれたらYes

2015-03-19 Shinya T-Y, NAIST 41

Page 42: Zynq+PyCoRAM(+Debian)入門

合成が完了したらキャンセル

2015-03-19 Shinya T-Y, NAIST 42

Page 43: Zynq+PyCoRAM(+Debian)入門

File→Export→Export Hardware

2015-03-19 Shinya T-Y, NAIST 43

Page 44: Zynq+PyCoRAM(+Debian)入門

File→Launch SDK

2015-03-19 Shinya T-Y, NAIST 44

Page 45: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 45

Page 46: Zynq+PyCoRAM(+Debian)入門

コマンドラインに戻ってU-Bootの作成 n  workへ移動しコンパイルの準備

n  U-Bootのダウンロード

n  xilinx-v2014.4をチェックアウト

2015-03-19 Shinya T-Y, NAIST 46

cd ~/work�export CROSS_COMPILE=arm-xilinx-linux-gnueabi-�export ARCH=arm�

git clone git://git.xilinx.com/u-boot-xlnx.git; cd u-boot-xlnx�

git checkout -b xilinx-v2014.4 xilinx-v2014.4�

Page 47: Zynq+PyCoRAM(+Debian)入門

SDカードからブートするように編集 n  “include/configs/zynq-common.h” (-が削除,+が追加)

2015-03-19 Shinya T-Y, NAIST 47

emacs include/configs/zynq-common.h�

diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h�index db74f14..b3f821f 100644�--- a/include/configs/zynq-common.h�+++ b/include/configs/zynq-common.h�@@ -239,11 +239,11 @@� #define CONFIG_EXTRA_ENV_SETTINGS \� "ethaddr=00:0a:35:00:01:22\0" \a� "kernel_image=uImage\0" \�- "kernel_load_address=0x2080000\0" \�+ "kernel_load_address=0x3000000\0" \� "ramdisk_image=uramdisk.image.gz\0" \� "ramdisk_load_address=0x4000000\0" \� "devicetree_image=devicetree.dtb\0" \�- "devicetree_load_address=0x2000000\0" \�+ "devicetree_load_address=0x2A00000\0" \� "bitstream_image=system.bit.bin\0" \� "boot_image=BOOT.bin\0" \� "loadbit_addr=0x100000\0" \�@@ -289,8 +289,7 @@� "echo Copying Linux from SD to RAM... && " \� "fatload mmc 0 ${kernel_load_address} ${kernel_image} && " \� "fatload mmc 0 ${devicetree_load_address} ${devicetree_image} && " \�- "fatload mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \�- "bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \�+ "bootm ${kernel_load_address} - ${devicetree_load_address}; " \� "fi\0" \� “usbboot=if usb start; then ” \�

Page 48: Zynq+PyCoRAM(+Debian)入門

U-Bootをビルド n デフォルトの設定をロードしてからコンパイル

n 出来上がったu-bootをVivadoのディレクトリにコピー

n  u-boot.elf完成

2015-03-19 Shinya T-Y, NAIST 48

make zynq_zed_config�make�

cp u-boot ~/work/vivado_zynq_pycoram/u-boot.elf�

Page 49: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 49

Page 50: Zynq+PyCoRAM(+Debian)入門

SDKでFile→New→Project

2015-03-19 Shinya T-Y, NAIST 50

Page 51: Zynq+PyCoRAM(+Debian)入門

Application Projectを選択しNext

2015-03-19 Shinya T-Y, NAIST 51

Page 52: Zynq+PyCoRAM(+Debian)入門

Project nameをfsblとしてNext

2015-03-19 Shinya T-Y, NAIST 52

Page 53: Zynq+PyCoRAM(+Debian)入門

Zynq FSBLを選択しFinish

2015-03-19 Shinya T-Y, NAIST 53

Page 54: Zynq+PyCoRAM(+Debian)入門

fsblを右クリックしCreate Boot Imageを選択 Addをクリック

2015-03-19 Shinya T-Y, NAIST 54

Page 55: Zynq+PyCoRAM(+Debian)入門

Browse

2015-03-19 Shinya T-Y, NAIST 55

Page 56: Zynq+PyCoRAM(+Debian)入門

先ほど作成したu-boot.elfを選択

2015-03-19 Shinya T-Y, NAIST 56

Page 57: Zynq+PyCoRAM(+Debian)入門

OK

2015-03-19 Shinya T-Y, NAIST 57

Page 58: Zynq+PyCoRAM(+Debian)入門

Create Image

2015-03-19 Shinya T-Y, NAIST 58

Page 59: Zynq+PyCoRAM(+Debian)入門

完成したBOOT.binをコピー n  bootimage/BOOT.binをBOOT.BINとしてコピー

n  VivadoとSDKを閉じる

2015-03-19 Shinya T-Y, NAIST 59

cp ~/work/vivado_zynq_pycoram/zed.sdk/fsbl/�bootimage/BOOT.bin ~/work/BOOT.BIN�

1行で続けて

Page 60: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 60

Page 61: Zynq+PyCoRAM(+Debian)入門

uImage (カーネルイメージ) のダウンロード n  Gitでダウンロードしxcomm_zynqをチェックアウト

n  Zynq用設定を適用しmenuを開く

n  “Device Drivers”→“Userspace I/O drivers”を選択し すべてに<*>がついていることを確認する(図参照)

n  “less .config”として以下の設定があることを確認する

2015-03-19 Shinya T-Y, NAIST 61

cd ~/work�git clone https://github.com/analogdevicesinc/linux.git ; cd linux �git checkout xcomm_zynq�

make zynq_xcomm_adv7511_defconfig�make menuconfig�

CONFIG_UIO=y�CONFIG_UIO_PDRV=y�CONFIG_UIO_PDRV_GENIRQ=y�

Page 62: Zynq+PyCoRAM(+Debian)入門

NFSの設定(必要があれば設定) n 研究室などでNFSでファイルシステムを共有する場合に要設定(単独で利用する場合には不要ためスキップ)

n  NFSを利用するにはカーネルでNFSをONにする

n  “File systems”→”Network file systems”を<*>にする

n  NFS関連のオプションを<*>で選択する(図参照)

n  “less .config”として以下の設定があることを確認する (次ページ参照)

2015-03-19 Shinya T-Y, NAIST 62

Page 63: Zynq+PyCoRAM(+Debian)入門

2015-03-19 Shinya T-Y, NAIST 63

CONFIG_NETWORK_FILESYSTEMS=y�CONFIG_NFS_FS=y�CONFIG_NFS_V2=y�CONFIG_NFS_V3=y�CONFIG_NFS_V3_ACL=y�CONFIG_NFS_V4=y�CONFIG_NFS_SWAP=y�CONFIG_NFS_V4_1=y�CONFIG_NFS_V4_2=y�CONFIG_PNFS_FILE_LAYOUT=y�CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"�CONFIG_NFS_V4_1_MIGRATION=y�# CONFIG_ROOT_NFS is not set�CONFIG_NFS_USE_LEGACY_DNS=y�# CONFIG_NFSD is not set�CONFIG_GRACE_PERIOD=y�CONFIG_LOCKD=y�CONFIG_LOCKD_V4=y�CONFIG_NFS_ACL_SUPPORT=y�CONFIG_NFS_COMMON=y�

Page 64: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定: UIO (1)

2015-03-19 Shinya T-Y, NAIST 64

Page 65: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定: UIO (2)

2015-03-19 Shinya T-Y, NAIST 65

Page 66: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定: UIO (3)

2015-03-19 Shinya T-Y, NAIST 66

Page 67: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定 : NFS (1)

2015-03-19 Shinya T-Y, NAIST 67

Page 68: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定 : NFS (2)

2015-03-19 Shinya T-Y, NAIST 68

Page 69: Zynq+PyCoRAM(+Debian)入門

menuconfigの設定 : NFS (3)

2015-03-19 Shinya T-Y, NAIST 69

Page 70: Zynq+PyCoRAM(+Debian)入門

uImage (カーネルイメージ) のコンパイル n  PATHの設定

n コンパイル

n 完成したuImageはlinux/arch/arm/bootにあるのでコピー

2015-03-19 Shinya T-Y, NAIST 70

export PATH=/home/yourname/work/u-boot-xlnx/tools:$PATH�

make uImage LOADADDR=0x00008000�

cp ~/work/linux/arch/arm/boot/uImage ~/work�

Page 71: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 71

Page 72: Zynq+PyCoRAM(+Debian)入門

Device Tree設定ファイルの編集 n  zynq-zed.dtsi を編集する (-が削除,+が追加)

n  “mem=256M” を追加しLinuxに割り当てるメモリ量を256MBに制限 n  “dmem-io”で /dev/uioX を追加している

l  usermemoryでDRAM後半256MBを /dev/uio0 に割り当て

l  pycoram0は /dev/uio1 •  アドレス・サイズ値はVivadoでのAddress Editorと同じにする

2015-03-19 Shinya T-Y, NAIST 72

emacs ~/work/linux/arch/arm/boot/dts/zynq-zed.dtsi� chosen {� - bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait";� + bootargs = "console=ttyPS0,115200 mem=256M root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait";� linux,stdout-path = "/amba@0/uart@E0001000";� };� � + usermemory {� + compatible = "dmem-uio";� + reg = < 0x10000000 0x10000000 >; // (address, size)� + };� +� + pycoram0 {� + compatible = "dmem-uio";� + reg = < 0x43c00000 0x10000 >; // (address, size)� + };� +�

Page 73: Zynq+PyCoRAM(+Debian)入門

Device Tree設定ファイルの追加 n  zynq-zed-pycoram.dts を作成する(ほぼ空)

2015-03-19 Shinya T-Y, NAIST 73

touch ~/work/linux/arch/arm/boot/dts/zynq-zed-pycoram.dts�emacs ~/work/linux/arch/arm/boot/dts/zynq-zed-pycoram.dts�

/dts-v1/;��/include/ "zynq-zed.dtsi”�

Page 74: Zynq+PyCoRAM(+Debian)入門

Device Treeのコンパイル n  Linuxディレクトリの中でmakeする

n  linux/arch/arm/boot/dts/zynq-zed-pycoram.dtb をコピー

2015-03-19 Shinya T-Y, NAIST 74

cd ~/work/linux�make zynq-zed-pycoram.dtb�

cp ~/work/linux/arch/arm/boot/dtb/zynq-zed-pycoram.dtb�~/work/devicetree.dtb�

1行で続けて

Page 75: Zynq+PyCoRAM(+Debian)入門

uEnv.txtの作成 n  uEnv.txtに以下の内容を書き込む

2015-03-19 Shinya T-Y, NAIST 75

emacs ~/work/uEnv.txt�

fdt_high=0x10000000�initrd_high=0x10000000�

Page 76: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 76

Page 77: Zynq+PyCoRAM(+Debian)入門

rootfs構築のための環境設定 n 各種ツールをインストールし環境変数を設定

n  $targetdirの中に構築開始

2015-03-19 Shinya T-Y, NAIST 77

cd ~/work�sudo apt-get install qemu-user-static debootstrap binfmt-support�export targetdir=rootfs�export distro=wheezy�

mkdir $targetdir�sudo debootstrap --arch=armhf --foreign $distro $targetdir�sudo cp /usr/bin/qemu-arm-static $targetdir/usr/bin�sudo cp /etc/resolv.conf $targetdir/etc�sudo chroot $targetdir�

Page 78: Zynq+PyCoRAM(+Debian)入門

QEMUを使ってrootfs構築 (1) n 下記コマンドを順次入力

2015-03-19 Shinya T-Y, NAIST 78

distro=wheezy �export LANG=C�/debootstrap/debootstrap --second-stage�

cat <<EOT > /etc/apt/sources.list�deb http://ftp.jp.debian.org/debian $distro main contrib non-free�deb-src http://ftp.jp.debian.org/debian $distro main contrib non-free�deb http://ftp.debian.org/debian $distro-updates main contrib non-free�deb-src http://ftp.debian.org/debian $distro-updates main contrib non-free�deb http://security.debian.org/debian-security $distro/updates main contrib non-free�deb-src http://security.debian.org/debian-security $distro/updates main contrib non-free�EOT�

cat << EOT > /etc/apt/apt.conf.d/71-no-recommends�APT::Install-Recommends "0";�APT::Install-Suggests "0";�EOT�

Page 79: Zynq+PyCoRAM(+Debian)入門

QEMUを使ってrootfs構築 (2) n 下記コマンドを順次入力: passwdでrootパスワード設定

n  IPアドレス等は環境に応じて設定する

2015-03-19 Shinya T-Y, NAIST 79

apt-get update�apt-get install locales dialog �dpkg-reconfigure locales�apt-get install openssh-server ntpdate resolvconf sudo less hwinfo ntp tcsh zsh�passwd�

echo <<EOT >> /etc/network/interfaces�auto eth0�iface eth0 inet static�address 192.168.0.100�netmask 255.255.255.0�gateway 192.168.0.1�dns-nameservers 192.168.0.1�EOT�

Page 80: Zynq+PyCoRAM(+Debian)入門

QEMUを使ってrootfs構築 (3) n  resolv.conf も同様

n  /etc/ssh/sshd_config の設定を確認:

n  l  “PasswordAuthentication yes”

2015-03-19 Shinya T-Y, NAIST 80

echo <<EOT >> /etc/resolv.conf�nameserver 192.168.0.1�EOT�

vi /etc/ssh/sshd_config�

Page 81: Zynq+PyCoRAM(+Debian)入門

QEMUを使ってrootfs構築 (4) n いろいろインストール

n 必要あればNISとNFSをインストール(しなくて良い)

n 終了し不要なファイルを削除

2015-03-19 Shinya T-Y, NAIST 81

echo debian-zynq > /etc/hostname�echo T0:2345:respawn:/sbin/getty -L ttyS0 115200 vt1000 >> /etc/inittab�apt-get install screen bash-completion emacs time�apt-get install gcc g++ gcc-4.7 g++-4.7�apt-get install python python-pip python3 python3-pip�

apt-get install nis nfs-common�

exit�sudo rm -f $targetdir/usr/bin/qemu-arm-static�

Page 82: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 82

Page 83: Zynq+PyCoRAM(+Debian)入門

SDカードをフォーマットする n  16GB以上あると良い n  GpartedでSDカードのパーティションを編集

l インストールして実行

n 先頭から以下の様な構成にする l 空き領域 (4MB)

l  BOOT (64MB, FAT32, bootableフラグ追加)

l  rootfs (残りすべて, ext4)

2015-03-19 Shinya T-Y, NAIST 83

sudo apt-get install gparted –y�sudo gparted &�

Page 84: Zynq+PyCoRAM(+Debian)入門

SDカードに書き込む n  /media/yourname/BOOT/に4つのファイルをコピー

n  /media/yourname/rootfs/に~/work/rootfs/の内容をコピー

n システム完成! l ジャンパーピンの設定を確認

l イーサネットケーブルを差し込みネットワークに接続

l  SDカードをZedBoardに差し込んで起動しましょう

2015-03-19 Shinya T-Y, NAIST 84

cp ~/work/BOOT.BIN /media/yourname/BOOT/�cp ~/work/devicetree.dtb /media/yourname/BOOT/�cp ~/work/uEnv.txt /media/yourname/BOOT/�cp ~/work/uImage /media/yourname/BOOT/�

sudo cp -a ~/work/rootfs/* /media/yourname/rootfs/�

Page 85: Zynq+PyCoRAM(+Debian)入門

ジャンパーピン

2015-03-19 Shinya T-Y, NAIST 85

Page 86: Zynq+PyCoRAM(+Debian)入門

開発手順 n 開発環境の準備 n  PyCoRAM/Pyverilogのダウンロード

n  IPコア作成

n  Vivadoで合成

n  U-Bootのコンパイル

n  SDKでブートイメージ (BOOT.BIN) の作成

n  Linuxカーネルイメージの作成

n  Device Treeの作成

n  Debian ルートファイルシステム (rootfs) の作成

n  SDカードへの書き込み

n  Zynq+Debian上でプログラム実行 2015-03-19 Shinya T-Y, NAIST 86

Page 87: Zynq+PyCoRAM(+Debian)入門

ssh経由でログインする n  IPアドレスは先ほど設定したもの n  ID: root, パスワード: passwdで設定したもの

n こんな感じでログインできるはず

2015-03-19 Shinya T-Y, NAIST 87

ssh [email protected]

Page 88: Zynq+PyCoRAM(+Debian)入門

memcpyプログラム (1) n  memcpy.c を作成する

n 内容(次ページに続く)

2015-03-19 Shinya T-Y, NAIST 88

#include <stdio.h>�#include <stdlib.h>�#include <unistd.h>�#include <assert.h>�#include <sys/mman.h>�#include <fcntl.h>��#define UIO_MEM "/dev/uio0"�#define UIO_PYCORAM "/dev/uio1"��#define UMEM_SIZE (0x10000000)�#define UMEM_ADDR (0x10000000)�#define MAP_SIZE (0x00001000)��void cache_clean(char* addr, int size)�{� __clear_cache(addr, addr + size);�}��void usage()�{� printf("usage: pycoram_memcpy -s <size> -v <value> -c\n");�}�

touch memcpy.c�

Page 89: Zynq+PyCoRAM(+Debian)入門

memcpyプログラム (2) n 次のページに続く・・・

2015-03-19 Shinya T-Y, NAIST 89

int main(int argc, char *argv[])�{� int c;� int value = 0;� int check = 0;� unsigned int size = 1024;� while ((c = getopt(argc, argv, "s:v:ch")) != -1) {� switch(c) {� case 's':� size = atoi(optarg);� break;� case 'v':� value = atoi(optarg);� break;� case 'c':� check = 1;� break;� case 'h':� usage();� return 0;� default:� printf("invalid option: %c\n", c);� usage();� return -1;� }� }�

Page 90: Zynq+PyCoRAM(+Debian)入門

memcpyプログラム (3) n 次のページに続く・・・

2015-03-19 Shinya T-Y, NAIST 90

int fd_mem = open(UIO_MEM, O_RDWR);� if(fd_mem < 1){� perror(argv[0]);� printf("Invalid UIO device file: '%s'\n", UIO_MEM);� return -1;� }� volatile unsigned int *usermemory = (volatile unsigned int*) mmap(NULL, UMEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, 0);�� int fd_pycoram = open(UIO_PYCORAM, O_RDWR);� if(fd_pycoram < 1){� perror(argv[0]);� printf("Invalid UIO device file: '%s'\n", UIO_PYCORAM);� return -1;� }� volatile unsigned int *pycoram = (volatile unsigned int*) mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_pycoram, 0);�� volatile int *a = (volatile int*) &usermemory[0];� volatile int *b = (volatile int*) &usermemory[size];�

Page 91: Zynq+PyCoRAM(+Debian)入門

memcpyプログラム (4) n 次のページに続く・・・

2015-03-19 Shinya T-Y, NAIST 91

// initialization of data� int i;�� if(check) goto verify;�� for(i=0; i<size * 2; i++){� //printf("write %10d\n", i);� a[i] = i + value;� }�� cache_clean((char*)usermemory, size * sizeof(int) * 2);� msync((void*)usermemory, UMEM_SIZE, MS_SYNC);�� int src = UMEM_ADDR;� int dst = UMEM_ADDR + size * sizeof(int);�� printf("memcpy from 'a' to 'b'\n");� printf("src = %08x\n", src);� printf("dst = %08x\n", dst);� printf("size = %8d\n", size);�� *pycoram = (volatile unsigned int) src;� printf(".");� *pycoram = (volatile unsigned int) dst;� printf(".");� *pycoram = (volatile unsigned int) size * sizeof(int);� printf(".\n");� volatile int recv = *pycoram;�

Page 92: Zynq+PyCoRAM(+Debian)入門

memcpyプログラム (5)

2015-03-19 Shinya T-Y, NAIST 92

verify: if(check){ printf("check only\n"); } cache_clean((char*)usermemory, size * sizeof(int) * 2); msync((void*)usermemory, UMEM_SIZE, MS_INVALIDATE); int mismatch = 0; for(i=0; i<size; i++){ //printf("read %10d\n", b[i]); if(a[i] != b[i]){ mismatch = 1; printf("%10d %10d\n", a[i], b[i]); } if(i==size-1){ //printf("read %10d\n", b[i]); } } if(mismatch){ printf("NG\n"); }else{ printf("OK\n"); } munmap((void*) usermemory, UMEM_SIZE); munmap((void*) pycoram, MAP_SIZE); return 0; }

Page 93: Zynq+PyCoRAM(+Debian)入門

memcpyプログラムについて n  ARMで初期値を設定し,

PyCoRAM IPコアで違う領域へコピーしてもらい, 最後に正しくコピーされているかどうかを確認する

n なぜ /dev/uio0 をmmapしているのか? l  DRAM前半256MBはLinux管理の領域のためPL側はデータが存在する物理アドレスを知ることができない

l (物理アドレスがわかったとしても) 論理空間で連続していても物理空間で連続とは限らないため PL側での大規模データの取り扱いが面倒になる

l  DRAM後半256MBをLinux非管理領域とし/dev/uio0にファイルとしてマップ,PL側と連続256MBの領域を共有

l  mmapがデータをキャッシュする可能性があるのでmsyncで吐き出している(もしかしてなくても良い)

l  L1/L2キャッシュにDirtyなデータが残っている可能性があるのでgcc拡張の__clear_cache(begin, end)でフラッシュ

2015-03-19 Shinya T-Y, NAIST 93

Page 94: Zynq+PyCoRAM(+Debian)入門

memcpyプログラムをコンパイル&実行 n コンパイルする

n 実行する

n このような実行結果が得られればOK l どうでしたか?

2015-03-19 Shinya T-Y, NAIST 94

gcc -O2 memcpy.c�

./a.out -s 4096�

Page 95: Zynq+PyCoRAM(+Debian)入門

補足:もしHDMIを使いたい場合には n  Analog Devicesが配布しているリファレンスデザインを利用するのが良い l  ADI Reference Designs HDL User Guide

•  http://wiki.analog.com/resources/fpga/docs/hdl •  https://github.com/analogdevicesinc/hdl

l  Vivado 2014.2を対象としておりいくつかのファイルが要修正

l  IPコアをVivado上のtclで自前でビルドする必要があり面倒

l  ZC706等のボードのリファレンスデザインも同梱

n 上記リファレンスデザインでも PyCoRAM IPコアが動作することは確認済み

2015-03-19 Shinya T-Y, NAIST 95

Page 96: Zynq+PyCoRAM(+Debian)入門

補足:その他 n  /usr/bin/sudo のパーミッションがおかしいので修正する

n  /etc/hosts にホスト名を書く

n  sudoersの設定にはvisudoを使う

n  root以外が /dev/uio* を使う場合には パーミッションを変更する

2015-03-19 Shinya T-Y, NAIST 96

chmod 6755 /usr/bin/sudo�

127.0.0.1 localhost yourhostname�

chmod 777 /dev/uio*�

Page 97: Zynq+PyCoRAM(+Debian)入門

参考にしたウェブサイト n  Zynq + Vivado HLS入門

l  http://www.slideshare.net/narusugimoto/zynq-vivado-hls?related=1 n  Zynq + Synthesijer入門

l  http://www.slideshare.net/miyox/synthesijer-zynq-qs20150316

n  ZedBoard用のUbuntu Linuxをビルド: FPGAの部屋 l  http://marsee101.blog19.fc2.com/blog-entry-2813.html

n  Yet Another Guide to Running Linaro Ubuntu Linux Desktop on Xilinx Zynq on the ZedBoard l  https://fpgacpu.wordpress.com/2013/05/24/yet-another-guide-to-

running-linaro-ubuntu-desktop-on-xilinx-zynq-on-the-zedboard/

n  Building a pure Debian armhf rootfs l  https://blog.night-shade.org.uk/2013/12/building-a-pure-debian-

armhf-rootfs/

n  ADI Reference Designs HDL User Guide l  http://wiki.analog.com/resources/fpga/docs/hdl

2015-03-19 Shinya T-Y, NAIST 97