Zynq+PyCoRAM(+Debian)入門
-
Upload
shinya-takamaeda-yamazaki -
Category
Technology
-
view
1.292 -
download
1
Transcript of Zynq+PyCoRAM(+Debian)入門
Zynq + PyCoRAM (+Debian) 入門
高前田 伸也
奈良先端科学技術大学院大学 情報科学研究科
E-mail: shinya_at_is_naist_jp
チュートリアルの目的
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
ゴールのシステム構成 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
開発手順 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のビルド
実機検証
開発手順 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
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�
開発手順 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
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 ../�
開発手順 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
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�
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転送の管理)
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転送
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�
シミュレーションで動作確認する n Icarus Verilogで実行しGTKWaveで波形を確認
2015-03-19 Shinya T-Y, NAIST 14
make sim�make view�
GTKWaveで波形を確認する
2015-03-19 Shinya T-Y, NAIST 15
n RVALIDのフェーズの後にWVALIDのフェーズが来る n アドレス (ARADDR, AWADDR) と データ (RDATA, WDATA) を見ると 正しく転送されているのがわかる
開発手順 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
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 &�
Open Example Project
2015-03-19 Shinya T-Y, NAIST 18
Next
2015-03-19 Shinya T-Y, NAIST 19
Project nameを”zed”に
2015-03-19 Shinya T-Y, NAIST 20
Base Zynq Designを選択
2015-03-19 Shinya T-Y, NAIST 21
ZedBoardを選択
2015-03-19 Shinya T-Y, NAIST 22
Finish
2015-03-19 Shinya T-Y, NAIST 23
ZedBoardベースシステム完成
2015-03-19 Shinya T-Y, NAIST 24
IP Settingsを変更
2015-03-19 Shinya T-Y, NAIST 25
Add Repository
2015-03-19 Shinya T-Y, NAIST 26
先ほど作成した”ip”ディレクトリを選択
2015-03-19 Shinya T-Y, NAIST 27
PyCoRAM IPコアが認識された
2015-03-19 Shinya T-Y, NAIST 28
Add IPでPyCoRAM IPコアを追加する
2015-03-19 Shinya T-Y, NAIST 29
pycoram_userlogic_v1_0を選択
2015-03-19 Shinya T-Y, NAIST 30
PyCoRAM IPコアが追加された ZynqをダブルクリックしてRe-customize IP
2015-03-19 Shinya T-Y, NAIST 31
32ビット幅のHP0 Interfaceを追加
2015-03-19 Shinya T-Y, NAIST 32
Run Connection Automationを実行
2015-03-19 Shinya T-Y, NAIST 33
S_AXI_HP0とcorammemory_0_AXIを接続
2015-03-19 Shinya T-Y, NAIST 34
GP0とcoramiochannel_0_AXIを接続
2015-03-19 Shinya T-Y, NAIST 35
クロック・リセットを接続(繋ぐ前)
2015-03-19 Shinya T-Y, NAIST 36
リセットを接続
2015-03-19 Shinya T-Y, NAIST 37
クロックを接続
2015-03-19 Shinya T-Y, NAIST 38
アドレスをチェック(変更しない)
2015-03-19 Shinya T-Y, NAIST 39
Generate Bitstreamで合成
2015-03-19 Shinya T-Y, NAIST 40
聞かれたらYes
2015-03-19 Shinya T-Y, NAIST 41
合成が完了したらキャンセル
2015-03-19 Shinya T-Y, NAIST 42
File→Export→Export Hardware
2015-03-19 Shinya T-Y, NAIST 43
File→Launch SDK
2015-03-19 Shinya T-Y, NAIST 44
開発手順 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
コマンドラインに戻って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�
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 ” \�
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�
開発手順 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
SDKでFile→New→Project
2015-03-19 Shinya T-Y, NAIST 50
Application Projectを選択しNext
2015-03-19 Shinya T-Y, NAIST 51
Project nameをfsblとしてNext
2015-03-19 Shinya T-Y, NAIST 52
Zynq FSBLを選択しFinish
2015-03-19 Shinya T-Y, NAIST 53
fsblを右クリックしCreate Boot Imageを選択 Addをクリック
2015-03-19 Shinya T-Y, NAIST 54
Browse
2015-03-19 Shinya T-Y, NAIST 55
先ほど作成したu-boot.elfを選択
2015-03-19 Shinya T-Y, NAIST 56
OK
2015-03-19 Shinya T-Y, NAIST 57
Create Image
2015-03-19 Shinya T-Y, NAIST 58
完成した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行で続けて
開発手順 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
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�
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
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�
menuconfigの設定: UIO (1)
2015-03-19 Shinya T-Y, NAIST 64
menuconfigの設定: UIO (2)
2015-03-19 Shinya T-Y, NAIST 65
menuconfigの設定: UIO (3)
2015-03-19 Shinya T-Y, NAIST 66
menuconfigの設定 : NFS (1)
2015-03-19 Shinya T-Y, NAIST 67
menuconfigの設定 : NFS (2)
2015-03-19 Shinya T-Y, NAIST 68
menuconfigの設定 : NFS (3)
2015-03-19 Shinya T-Y, NAIST 69
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�
開発手順 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
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)� + };� +�
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”�
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行で続けて
uEnv.txtの作成 n uEnv.txtに以下の内容を書き込む
2015-03-19 Shinya T-Y, NAIST 75
emacs ~/work/uEnv.txt�
fdt_high=0x10000000�initrd_high=0x10000000�
開発手順 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
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�
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�
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�
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�
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�
開発手順 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
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 &�
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/�
ジャンパーピン
2015-03-19 Shinya T-Y, NAIST 85
開発手順 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
ssh経由でログインする n IPアドレスは先ほど設定したもの n ID: root, パスワード: passwdで設定したもの
n こんな感じでログインできるはず
2015-03-19 Shinya T-Y, NAIST 87
ssh [email protected]�
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�
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;� }� }�
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];�
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;�
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; }
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
memcpyプログラムをコンパイル&実行 n コンパイルする
n 実行する
n このような実行結果が得られればOK l どうでしたか?
2015-03-19 Shinya T-Y, NAIST 94
gcc -O2 memcpy.c�
./a.out -s 4096�
補足:もし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
補足:その他 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*�
参考にしたウェブサイト 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