qemu2svを試してみた-3-
qemu2svを試してみた-2- - 日曜技術者のメモの続き
プログラムを書いてWrite/Readテストをした
qemu⇔svの通信テスト
通信プログラムの作成
qemuからsvへアクセスする為のプログラムを作成した。
sv側にライトしてからリードするだけのプログラム。
- main.c
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) int main(void){ int mem_fd; void *hw_if_map; volatile unsigned int* phy_pt; unsigned int ret; int i; if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { printf("can't open /dev/mem \n"); return 0; } hw_if_map = mmap( NULL, //Any adddress in our space will do BLOCK_SIZE, //Map length PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory MAP_SHARED, //Shared with other processes mem_fd, //File to map 0xe0004000 //Offset to GPIO peripheral ); close(mem_fd); phy_pt = hw_if_map; for (i = 0 ;i < 0x100 ; i = i + 4){ printf("CPU Write Address = 0x%x data = 0x%x\n",0xe0004000+i,i + 0x10 ); *(phy_pt+i) = (0x10 + i); printf("CPU Read Address = 0x%x\n",0xe0004000+i); ret = *(phy_pt+i); printf("CPU Read Data = 0x%x\n",ret); if (ret != (0x10 + i)){ printf("Error::not compare\n"); return 0; } } return 1; }
ビルド
XilinxSDKの中にあるarm-xilinx-linux-gnueabi-gcc
を使ってビルドした。
/opt/Xilinx/SDK/2014.2/gnu/arm/lin/bin/arm-xilinx-linux-gnueabi-gcc -o ./main main.
QEMU Linuxに転送
QEMU上ではFTPサーバーが動作しているのでFTPを使って送付する。
ビルドしたmain
と同じフォルダに以下テキストを作成。
- ftp.txt
open localhost 10021 user root root passive put main close
作成後ftp -n < ftp.txt
を実行する事でQEMU Linuxのルートディレクトリにファイルが送られる。
動作確認。
QEMU Linux上にmainがある事が確認できたらchmod +x main
で実行権限を与えておく。
- QEMU側
zynq> ./main CPU Write Address = 0xe0004000 data = 0x10 CPU Read Address = 0xe0004000 CPU Read Data = 0x10 CPU Write Address = 0xe0004004 data = 0x14 CPU Read Address = 0xe0004004 CPU Read Data = 0x14 ・・・ CPU Write Address = 0xe00040f8 data = 0x108 CPU Read Address = 0xe00040f8 CPU Read Data = 0x108 CPU Write Address = 0xe00040fc data = 0x10c CPU Read Address = 0xe00040fc CPU Read Data = 0x10c zynq>
- sv側
# Start server connect... # sv::write::rw_packet.offset = 0x00000000 rw_packet.data = 0x00000010 # # sv::read::rw_packet.offset = 0x00000000 rw_packet.data = 0x00000010 # # sv::write::rw_packet.offset = 0x00000010 rw_packet.data = 0x00000014 # # sv::read::rw_packet.offset = 0x00000010 rw_packet.data = 0x00000014 # # sv::write::rw_packet.offset = 0x00000020 rw_packet.data = 0x00000018 # # sv::read::rw_packet.offset = 0x00000020 rw_packet.data = 0x00000018 ・・・ # sv::write::rw_packet.offset = 0x000003e0 rw_packet.data = 0x00000108 # # sv::read::rw_packet.offset = 0x000003e0 rw_packet.data = 0x00000108 # # sv::write::rw_packet.offset = 0x000003f0 rw_packet.data = 0x0000010c # # sv::read::rw_packet.offset = 0x000003f0 rw_packet.data = 0x0000010c #
ちゃんとアクセスしている様に見えるがアドレスが違うと思い調べた結果、sv側のoffsetを2ビット右シフトする事でアドレスが一致しました。
QEMUを終了するにはQEMUのターミナル上でCtrl+A
を入力した後x
を入力すると終了します。
(その際sv側も勝手に終了する。)
終了する際に気になったのはQEMU側を終了際にsv側にアクセスが発生する様です。 以下終了時のログには0x00000000へ2回リードが発生している。
# sv::read::rw_packet.offset = 0x000003f0 rw_packet.data = 0x0000010c # # sv::read::rw_packet.offset = 0x00000000 rw_packet.data = 0x00000010 # # sv::read::rw_packet.offset = 0x00000000 rw_packet.data = 0x00000010 # # SV::connection faild # # ** Note: $finish : mem_model.sv(47) # Time: 95 ps Iteration: 1 Instance: /mem_model [ginnyu-tei@localhost svdpi_test]$
そこそこ簡単にQEMUとSVが通信できました。
後シミュレーション時間が同期できればおもしろいかなー
qemu2svを試してみた-2-
qemu2svを試してみた-1- - 日曜技術者のメモの続き
Device Treeの準備と動作確認
Linux
Device Tree
Linuxカーネルに付属しているDevice Treeを使うとqemu上でブートはするがネットワークが繋がらなかった。
色々試した結果zynq-zed.dts
を修正する事で接続できた。
- zynq-zed.dtsを以下の様に修正
chosen { /*bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";*/ bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk ip=:::::eth0:dhcp"; linux,stdout-path = "/amba@0/serial@e0001000"; } ;
修正後dtsからdtbを生成する。
zynq_linux/linux-xlnx/scripts/dtc/dtc -I dts -O dtb -o zynq-zed.dtb zynq-zed.dts
QEMU
スタートスクリプト
- start_qemu.sh
#!/bin/sh qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio \ -dtb ./zynq-zed.dts -smp 1 -nographic \ -kernel ./zImage \ -initrd filesystem/ramdisk.img \ -net nic,model=cadence_gem \ -net user \ -tftp ~/ \ -redir tcp:10023::23 -redir tcp:10080::80 -redir tcp:10022::22 -redir tcp:10021::21 -redir tcp:1234::1234
A9 MPコアなので-smp 2
だと思うのだが、そうするとQEMUがエラーになったので-smp 1
にしている。
-redir
のオプションはポートフォワーディングで<tcp or udp> : <ホスト側ポート> :: <QEMU上OSのポート>
となっている。
-initrd
でしていしているramdisk.imgはhttp://www.xilinx.com/member/zynq_linux/zynq_linux.tar.gzの中にあるファイルをそのまま
使っている。
動作テスト
OSブート
ターミナルを二つ用意し、一つのターミナルで`./start_qemu.sh
を実行後もう一つのターミナルでsv側のmake
を実行するとLinuxがブートする。
以下にログを貼っておく。
- qemu側
[ginnyu-tei@localhost zynq_linux]$ ./start_qemu.sh [hw_if] Socket is listening for connections... Please start the rtl simulation. Timeout after 15 sec Warning: nic cadence_gem.1 has no peer console [ttyPS0] enabled console [ttyPS0] enabled bootconsole [earlycon0] disabled bootconsole [earlycon0] disabled xdevcfg f8007000.ps7-dev-cfg: ioremap 0xf8007000 to f0066000 [drm] Initialized drm 1.1.0 20060810 brd: module loaded loop: module loaded m25p80 spi0.0: SPI transfer timed out m25p80: probe of spi0.0 failed with error -110 e1000e: Intel(R) PRO/1000 Network Driver - 2.3.2-k e1000e: Copyright(c) 1999 - 2013 Intel Corporation. libphy: XEMACPS mii bus: probed xemacps e000b000.ps7-ethernet: invalid address, use assigned xemacps e000b000.ps7-ethernet: MAC updated ea:05:dc:07:2d:7b xemacps e000b000.ps7-ethernet: pdev->id -1, baseaddr 0xe000b000, irq 54 ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver ehci-pci: EHCI PCI platform driver zynq-dr e0002000.ps7-usb: Unable to init USB phy, missing? usbcore: registered new interface driver usb-storage mousedev: PS/2 mouse device common for all mice i2c /dev entries driver zynq-edac f8006000.ps7-ddrc: ecc not enabled cpufreq_cpu0: failed to get cpu0 regulator: -19 Xilinx Zynq CpuIdle Driver started sdhci: Secure Digital Host Controller Interface driver [ginnyu-tei@localhost zynq_linux]$ ./start_qemu.sh [hw_if] Socket is listening for connections... Please start the rtl simulation. Timeout after 15 sec Warning: nic cadence_gem.1 has no peer console [ttyPS0] enabled console [ttyPS0] enabled bootconsole [earlycon0] disabled bootconsole [earlycon0] disabled xdevcfg f8007000.ps7-dev-cfg: ioremap 0xf8007000 to f0066000 [drm] Initialized drm 1.1.0 20060810 brd: module loaded loop: module loaded m25p80 spi0.0: SPI transfer timed out m25p80: probe of spi0.0 failed with error -110 e1000e: Intel(R) PRO/1000 Network Driver - 2.3.2-k e1000e: Copyright(c) 1999 - 2013 Intel Corporation. libphy: XEMACPS mii bus: probed xemacps e000b000.ps7-ethernet: invalid address, use assigned xemacps e000b000.ps7-ethernet: MAC updated ae:93:fe:cd:f7:8a xemacps e000b000.ps7-ethernet: pdev->id -1, baseaddr 0xe000b000, irq 54 ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver ehci-pci: EHCI PCI platform driver zynq-dr e0002000.ps7-usb: Unable to init USB phy, missing? usbcore: registered new interface driver usb-storage mousedev: PS/2 mouse device common for all mice i2c /dev entries driver zynq-edac f8006000.ps7-ddrc: ecc not enabled cpufreq_cpu0: failed to get cpu0 regulator: -19 Xilinx Zynq CpuIdle Driver started sdhci: Secure Digital Host Controller Interface driver sdhci: Copyright(c) Pierre Ossman sdhci-pltfm: SDHCI platform and OF driver helper mmc0: no vqmmc regulator found mmc0: no vmmc regulator found mmc0: SDHCI controller on e0100000.ps7-sdio [e0100000.ps7-sdio] using ADMA usbcore: registered new interface driver usbhid usbhid: USB HID core driver TCP: cubic registered NET: Registered protocol family 17 zynq_pm_remap_ocm: OCM pool is not available zynq_pm_late_init: Unable to map OCM. Registering SWP/SWPB emulation handler regulator-dummy: disabling drivers/rtc/hctosys.c: unable to open rtc device (rtc0) Sending DHCP requests ., OK IP-Config: Got DHCP answer from 10.0.2.2, my address is 10.0.2.15 IP-Config: Complete: device=eth0, hwaddr=ae:93:fe:cd:f7:8a, ipaddr=10.0.2.15, mask=255.255.255.0, gw=10.0.2.2 host=10.0.2.15, domain=, nis-domain=(none) bootserver=10.0.2.2, rootserver=10.0.2.2, rootpath= nameserver0=10.0.2.3 ALSA device list: No soundcards found. RAMDISK: ext2 filesystem found at block 0 RAMDISK: Loading 8192KiB [1 disk] into ram disk... done. VFS: Mounted root (ext2 filesystem) on device 1:0. devtmpfs: mounted Freeing unused kernel memory: 184K (c05f9000 - c0627000) Starting rcS... ++ Mounting filesystem ++ Setting up mdev ++ Starting telnet daemon ++ Starting http daemon ++ Starting ftp daemon ++ Starting dropbear (ssh) daemon random: dropbear urandom read with 0 bits of entropy available xemacps e000b000.ps7-ethernet: Set clk to 123809522 Hz xemacps e000b000.ps7-ethernet: link up (1000/FULL) rcS Complete zynq>
- sv側
[ginnyu-tei@localhost svdpi_test]$ make vlib work vlog -sv -dpiheader dpiheader.h mem_model.sv Model Technology ModelSim ALTERA vlog 10.1d Compiler 2012.11 Nov 2 2012 -- Compiling package mem_model_sv_unit -- Compiling module mem_model Top level modules: mem_model gcc -c -g -fpic -m32 -I/mnt/sdb1/altera/13.1/modelsim_ase//include mem_model.c gcc -O0 -shared -m32 mem_model.o -o svdpi.so vsim -c -sv_lib svdpi mem_model -do "run -all; quit " Reading /mnt/sdb1/altera/13.1/modelsim_ase/tcl/vsim/pref.tcl # 10.1d # vsim -do {run -all; quit } -c -sv_lib svdpi mem_model # Loading /var/tmp/ginnyu-tei@localhost.localdomain_dpi_13953/linuxpe_gcc-4.5.0/export_tramp.so # Loading sv_std.std # Loading work.mem_model_sv_unit # Loading work.mem_model # Compiling /var/tmp/ginnyu-tei@localhost.localdomain_dpi_13953/linuxpe_gcc-4.5.0/exportwrapper.c # Loading /var/tmp/ginnyu-tei@localhost.localdomain_dpi_13953/linuxpe_gcc-4.5.0/dpi_auto_compile.so # Loading ./svdpi.so # run -all # Start server connect...
また長くなったので次回
qemu2svを試してみた-1-
qemuとSystemVerilogを接続してシミュレーションをするqemu2svがgithubにて公開されていたので試してみた
qemu2sv
qemu2svの入手&ビルド
git clone https://github.com/SVHackathon2014B/qemu2sv.git
qemu2svのビルドは付属しているREADME.mdの通りやればビルドできた。
ただ、qemuをビルドする為にいくつかのパッケージをインストールした。
sudo yum install pixman-devel sudo yum install flex bison sudo yum install glib
Linux
ソースコードの入手
zynq qemu用のLinuxはxilinxが公開している。
http://www.xilinx.com/member/zynq_linux/zynq_linux.tar.gz *1
Xilinx Wiki - QEMUに書いてある手順で実行したがブートしなかったのでカーネルをビルドした。
zynq用のLinuxはgithubにあるのでclone
Windowsでcloneする場合
cloneする際に改行コードをCRLFに変える設定があり有効であればlinuxをビルドできない
(defconfigでエラーになる)
git config --list | grep autocrlf
を実行してtrueであれば
git config --global core.autocrlf input
を実行する。
最新のコードだと動かなかったのでタグを指定して古いバージョンにする。
(xilinx-v2014.2.01で動作を確認)
checkoutで良いがソースコードを別PCでビルドしたかったのでarchiveにした。
git archive --format tar --prefix=export/ xilinx-v2014.2.01 | gzip > export.tar.gz
ビルド
export.tar.gzを解凍後ビルドする。
gccはxilinxSDKに付属しているarm-xilinx-linux-gnueabi-gccを使った。
make ARCH=arm xilinx_zynq_defconfig export CROSS_COMPILE=/opt/Xilinx/SDK/2014.2/gnu/arm/lin/bin/arm-xilinx-linux-gnueabi- make ARCH=arm
ビルド後以下ファイルを使う。
- arch/arm/boot/dts/zynq-zed.dts
- arch/arm/boot/zImage
続きは次回
*1:
ブログ書いてる途中で見つけましたがxilinxのフォーラムに新しいQEMU用Linuxが公開されている様です。
(これで動くかは試してません)
Getting started with Zynq 14.5 and QEMU - Xilinx User Community Forums
C++11とC++14とSystemC
C++11やC++14といった新しいC++でSystemCを使ったらどうなるか軽く試したメモ
C++11
C++11でSystemCがどうなるかについては↓の資料にまとめられています。
http://www.nascug.org/events/17th/black_cpp11_2_27_2012.pdf
一番気になったのはテンプレートについて。
C99だと>
が二つ続く際は右シフトと認識しない様にスペースが必要。
でもC++11ではちゃんと判別してくれる様です。
実際にやってみた。
#include <systemc.h> int sc_main(int argc, char *argv[]) { sc_signal<sc_uint<5> > c99; sc_signal<sc_uint<5>> cpp11; //こっちはC++11専用 }
C99環境だと
clang++ -O2 -Wall -I. -I/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//include -c main.cpp main.cpp:6:25: error: use of undeclared identifier 'cpp11' sc_signal<sc_uint<5>> cpp11; ^ main.cpp:6:30: error: expected a type sc_signal<sc_uint<5>> cpp11; ^ 2 errors generated. make: *** [main.o] エラー 1
もちろんエラー
次は同じコードをC++11環境でやってみる。
C++11環境にするにはオプションに-std=c++11
を追加する。
(gccのバージョンによっては-std=c++0x
)
clang++ -O2 -Wall -std=c++11 -I. -I/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//include -c main.cpp clang++ -o run.x -L. -L/home/ginnyu-tei/lib/SystemC-2.3.0_Debug//lib-linux64 -lsystemc -lm main.o
問題なくビルド出来ました。
C++14
C++14では2進数表記が追加される様です。
ドラフト規格ですが、コンパイラが独自規格で実装している様なので試してみました。
#include <systemc.h> int sc_main(int argc, char *argv[]) { sc_uint<5> hoge; sc_uint<32> piyo; hoge = 0b10000; piyo = 0b10101010010101010000000011111111; cout << std::hex << "hoge = " << hoge << endl; cout << std::hex << "piyo = " << piyo << endl; return 0; }
実行結果
[ginnyu-tei@localhost SystemC_Test]$ ./run.x SystemC 2.3.0-ASI --- Mar 9 2014 13:23:24 Copyright (c) 1996-2012 by all Contributors, ALL RIGHTS RESERVED hoge = 10 piyo = 0aa5500ff
C++14の新機能はまだまだあるけどそれは正式な規格になってから調べる
clangでSystemC2.2をビルドしてみた
clangでSystemC2.2がビルドできたのでメモ
ただしこの方法はclangのバージョン3.3のみに有効
clangインストール
インストールは以下ページを参考にしました。
CentOS5にLLVMとclangをインストールする | CentOS・Red Hat Linux実践テクニック - サンプルコードによるPerl入門 〜 伝統と信頼のPerlを学ぼう 〜
automake-1.6.3 インストール
Fedora Coreに入っているautomakeは1.12は新しすぎて
SystemC2.2では使えないので1.6.3をインストール
wget http://ftp.gnu.org/gnu/automake/automake-1.6.3.tar.gz tar zxvf automake-1.6.3.tar.gz cd automake-1.6.3 ./configure make sudo make install
SystemC2.2修正
そのままではビルドできないのでコードに手をいれる。
修正は以下を参照
configure
@@ -3445,7 +3445,7 @@ ;; x86_64*linux*) case "$CXX_COMP" in - c++ | g++) + c++ | g++ | clang++) EXTRA_CXXFLAGS="-Wall" DEBUG_CXXFLAGS="-g" OPT_CXXFLAGS="-O3"
src/sysc/datatypes/bit/sc_bit_proxies.h
@@ -713,7 +713,7 @@ protected: - mutable X& m_obj; + X& m_obj; int m_hi; int m_lo; int m_len; @@ -1190,10 +1190,10 @@ protected: - mutable X& m_left; - mutable Y& m_right; + X& m_left; + Y& m_right; mutable int m_delete; - mutable int& m_refs; + int& m_refs; private:
src/sysc/datatypes/fx/scfx_rep.h
@@ -74,6 +74,7 @@ void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int ); scfx_rep* neg_scfx_rep( const scfx_rep& ); scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int ); +scfx_rep* mult_scfx_rep( const scfx_rep& ); scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int ); scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int ); scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int ); @@ -374,6 +375,15 @@ inline scfx_rep* +mult_scfx_rep( const scfx_rep& a, const scfx_rep& b) +{ + scfx_rep& c = *new scfx_rep; + sc_dt::multiply( c, a, b, SC_DEFAULT_MAX_WL_ ); + return &c; +} + +inline +scfx_rep* lsh_scfx_rep( const scfx_rep& a, int b ) { scfx_rep& c = *new scfx_rep( a );
src/sysc/utils/sc_utils_ids.cpp
@@ -59,6 +59,8 @@ // #include "sysc/utils/sc_report.h" +#include <cstdlib> +#include <cstring> namespace sc_core {
SystemC2.2ビルド&インストール
手順は普通のやり方。
ただし、環境変数でコンパイラをclangにする。
mkdir build cd build env CC=clang CXX=clang++ ../configure --prefix=/home/ginnyu-tei/lib/SystemC-2.2_Clang make sudo make install make check
参考にしたサイト
LSI設計雑記帳 [SystemC] clangでインストール
clang - Installing SystemC 2.2.0, compilation with GCC 4.6 and package for Fedora - Stack Overflow