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が通信できました。
後シミュレーション時間が同期できればおもしろいかなー