From 0a8d829f15df319ed7387c63c9a8f54b908a4fa7 Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Sat, 4 Apr 2020 09:07:04 -0400 Subject: [PATCH] basic test update --- driver/tests/basic/Makefile | 30 +++++ driver/tests/basic/basic | Bin 44240 -> 47320 bytes driver/tests/basic/basic.cpp | 106 +++++++++--------- .../tests/basic/{snooping.bin => kernel.bin} | Bin 7436 -> 7428 bytes driver/tests/basic/kernel.c | 9 ++ driver/tests/basic/rv32ui-p-lw.bin | Bin 8208 -> 0 bytes driver/tests/basic/rv32ui-p-sw.bin | Bin 8240 -> 0 bytes driver/tests/demo/kernel.bin | Bin 92712 -> 92712 bytes 8 files changed, 92 insertions(+), 53 deletions(-) rename driver/tests/basic/{snooping.bin => kernel.bin} (89%) mode change 100644 => 100755 create mode 100644 driver/tests/basic/kernel.c delete mode 100644 driver/tests/basic/rv32ui-p-lw.bin delete mode 100644 driver/tests/basic/rv32ui-p-sw.bin diff --git a/driver/tests/basic/Makefile b/driver/tests/basic/Makefile index f29b8e64..786b0491 100644 --- a/driver/tests/basic/Makefile +++ b/driver/tests/basic/Makefile @@ -1,3 +1,21 @@ +RISCV_TOOL_PATH ?= $(wildcard ~/dev/riscv-gnu-toolchain/drops) +VX_RT_PATH ?= $(wildcard ../../../runtime) + +VX_CC = $(RISCV_TOOL_PATH)/bin/riscv32-unknown-elf-gcc +VX_CXX = $(RISCV_TOOL_PATH)/bin/riscv32-unknown-elf-g++ +VX_DMP = $(RISCV_TOOL_PATH)/bin/riscv32-unknown-elf-objdump +VX_CPY = $(RISCV_TOOL_PATH)/bin/riscv32-unknown-elf-objcopy + +VX_NEWLIB = $(VX_RT_PATH)/newlib/newlib.c +VX_STR = $(VX_RT_PATH)/startup/vx_start.S +VX_INT = $(VX_RT_PATH)/intrinsics/vx_intrinsics.s +VX_IO = $(VX_RT_PATH)/io/vx_io.s $(VX_RT_PATH)/io/vx_io.c +VX_API = $(VX_RT_PATH)/vx_api/vx_api.c +VX_FIO = $(VX_RT_PATH)/fileio/fileio.s + +VX_CFLAGS = -march=rv32im -mabi=ilp32 -O3 -Wl,-Bstatic,-T,$(VX_RT_PATH)/mains/vortex_link.ld -ffreestanding -nostartfiles -Wl,--gc-sections + +VX_SRCS = kernel.c CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -pedantic -Wfatal-errors @@ -11,6 +29,18 @@ SRCS = basic.cpp all: $(PROJECT) +kernel.dump: kernel.elf + $(VX_DMP) -D kernel.elf > kernel.dump + +kernel.hex: kernel.elf + $(VX_CPY) -O ihex kernel.elf kernel.hex + +kernel.bin: kernel.elf + $(VX_CPY) -O binary kernel.elf kernel.bin + +kernel.elf: $(SRCS) + $(VX_CC) $(VX_CFLAGS) $(VX_STR) $(VX_FIO) $(VX_NEWLIB) $(VX_INT) $(VX_IO) $(VX_API) $(VX_SRCS) -I$(VX_RT_PATH) -o kernel.elf + $(PROJECT): $(SRCS) $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -L../../sw/dummy -lvortex -o $@ diff --git a/driver/tests/basic/basic b/driver/tests/basic/basic index 3a7a03091f3607848c7bcca4a205adf24e2ba944..abc005ef76bd8a0d6d4ff5d323f73241235372ec 100755 GIT binary patch literal 47320 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 DlYujm literal 44240 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 WlFOe2{7CsP{+iCPHYr0=RQ(?XlP>oF diff --git a/driver/tests/basic/basic.cpp b/driver/tests/basic/basic.cpp index c73535c8..684d655d 100755 --- a/driver/tests/basic/basic.cpp +++ b/driver/tests/basic/basic.cpp @@ -28,10 +28,10 @@ uint64_t shuffle(int i, uint64_t value) { } int run_memcopy_test(vx_buffer_h sbuf, - vx_buffer_h dbuf, - uint32_t address, - uint64_t value, - int num_blocks) { + vx_buffer_h dbuf, + uint32_t address, + uint64_t value, + int num_blocks) { int ret; int errors = 0; @@ -73,8 +73,29 @@ int run_memcopy_test(vx_buffer_h sbuf, return 0; } -int run_riscv_test(vx_device_h device, const char* program) { +int run_kernel_test(vx_device_h device, + vx_buffer_h sbuf, + vx_buffer_h dbuf, + const char* program) { int ret; + int errors = 0; + + uint64_t seed = 0x0badf00d40ff40ff; + int num_blocks = 4; + + unsigned src_dev_addr = 0x10000000; + unsigned dest_dev_addr = 0x20000000; + + // write sbuf data + for (int i = 0; i < 8 * num_blocks; ++i) { + ((uint64_t*)vx_host_ptr(sbuf))[i] = shuffle(i, seed); + } + + // write buffer to local memory + std::cout << "write buffer to local memory" << std::endl; + ret = vx_copy_to_dev(sbuf, src_dev_addr, 64 * num_blocks, 0); + if (ret != 0) + return ret; // upload program std::cout << "upload program" << std::endl; @@ -97,40 +118,37 @@ int run_riscv_test(vx_device_h device, const char* program) { return ret; } - return 0; -} - -int run_snoop_test(vx_device_h device) { - int ret; - - // upload program - std::cout << "upload program" << std::endl; - ret = vx_upload_kernel_file(device, "snooping.bin"); - if (ret != 0) { - return ret; - } - - // start device - std::cout << "start device" << std::endl; - ret = vx_start(device); - if (ret != 0) { - return ret; - } - - // wait for completion - std::cout << "wait for completion" << std::endl; - ret = vx_ready_wait(device, -1); - if (ret != 0) { - return ret; - } - // flush the caches std::cout << "flush the caches" << std::endl; - ret = vx_flush_caches(device, 0x10000000, 64*8); + ret = vx_flush_caches(device, dest_dev_addr, 64 * num_blocks); if (ret != 0) { return ret; } + // read buffer from local memory + std::cout << "read buffer from local memory" << std::endl; + ret = vx_copy_from_dev(dbuf, dest_dev_addr, 64 * num_blocks, 0); + if (ret != 0) + return ret; + + // verify result + std::cout << "verify result" << std::endl; + for (int i = 0; i < 8 * num_blocks; ++i) { + auto curr = ((uint64_t*)vx_host_ptr(dbuf))[i]; + auto ref = shuffle(i, seed); + if (curr != ref) { + std::cout << "error @ " << std::hex << (dest_dev_addr + 64 * i) + << ": actual " << curr << ", expected " << ref << std::endl; + ++errors; + } + } + + if (errors != 0) { + std::cout << "Found " << errors << " errors!" << std::endl; + std::cout << "FAILED!" << std::endl; + return 1; + } + return 0; } @@ -197,26 +215,8 @@ int main(int argc, char *argv[]) { } if (1 == test || -1 == test) { - std::cout << "run riscv-lw test" << std::endl; - ret = run_riscv_test(device, "rv32ui-p-lw.bin"); - if (ret != 0) { - cleanup(); - return ret; - } - } - - if (2 == test || -1 == test) { - std::cout << "run riscv-sw test" << std::endl; - ret = run_riscv_test(device, "rv32ui-p-sw.bin"); - if (ret != 0) { - cleanup(); - return ret; - } - } - - if (3 == test || -1 == test) { - std::cout << "run snoop test" << std::endl; - ret = run_snoop_test(device); + std::cout << "run kernel test" << std::endl; + ret = run_kernel_test(device, sbuf, dbuf, "kernel.bin"); if (ret != 0) { cleanup(); return ret; diff --git a/driver/tests/basic/snooping.bin b/driver/tests/basic/kernel.bin old mode 100644 new mode 100755 similarity index 89% rename from driver/tests/basic/snooping.bin rename to driver/tests/basic/kernel.bin index c4b15898d79235d8eb76a2b9d2d9dfe365e40f29..55e20d29ee45c6f46dba89820ebd31744b154bbc GIT binary patch delta 290 zcmeCNYO$)H&dR_rx%DWAFlz%tw!l_~_Y4Qvg;@m{vKd$zgj)|D7H(raV$8P8VKPwN zdxnN6aUdiK(@1vIlb#)6w?HYnY`N zSvMbN)@NjE=>cl)nf!+(O4g-EnA5YznDeKDvYH^!yon6Lk(v(444h2DEH0B*vr10x zVdWA9spanVy&dR_rxz&|Zn6-f+TVN~0djs{<*#(5z#2J(qJZDf|be&}(91+paP^p0xa5dIL}`I|DC6atAwuIV(d0&``gPExVYQSlcH%Fek~n zb^wj#W?l+(0=p=K^16qIKw8X2K`L7}?`PI$WMk=_+|J%R`3p;w?2#T}&XYaHoIf3u z)dU%ol_oL>M`}7GGjK8qvmBY6&8jR4Qo-2^Qh_QXxp@yOhp + +void main() { + int64_t* x = (int64_t*)0x10000000; + int64_t* y = (int64_t*)0x20000000; + for (int i = 0; i < 8 * 4; ++i) { + y[i] = x[i]; + } +} \ No newline at end of file diff --git a/driver/tests/basic/rv32ui-p-lw.bin b/driver/tests/basic/rv32ui-p-lw.bin deleted file mode 100644 index 51c28eaac779eef685dc9244fafbb62a03f83cf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8208 zcmeH`!HUyR6o&t#Q$dB?I9Dx>wUeL?VPb zq5sEFW>%>Q1X75ZS`)Yf0qs>c1iJ7b?+&lmHi4#d__v!r&it15P1#lWE!$N$tK?3F zv~2hQqy-F2AnNsg`(elR+Ya3>-JVO&gQ)lHr@Ci?G&?fK8-94%^_z}+JiPtOZ$o=1 zd(H5}^=;k9hvN<$dKP#;`XgXsWr+4>)X#x>m|U4_!T0{iBhAR7Ju8)#3-u^z&9yk~ zj{-~@sUR(rmIpOVnsW_b`=c0>nMkQ7&EAFzOYIBQ%$EIbLG347#VntxCTWX)J5cwN z&0>~MR5M%lBi;{^OT{c7^D~tFLa2k}Vo~!$6ktZWx$OBw>lX_BeH0vJ{n5_KImcSB zNh^jVZgU^rX%@0?lxJ4wr{|=(j>vRy-01v~*3pXJdz1V1yVIFsHdUXVDKmAQdApJc zUYD6gu3(|;sVH+BI+w2GyjME6U_vh?TYuvh%v z3+*p6i+K)`YMG&P47O;Oc6SdeBLmWK5YZmdE*a`NfC(@GCcp%k025#WOn?b60Vco%m;e)C0!)AjFaajO Y1egF5U;<3wzY)lgfvzkSsh}(U2fxc9M*si- diff --git a/driver/tests/basic/rv32ui-p-sw.bin b/driver/tests/basic/rv32ui-p-sw.bin deleted file mode 100644 index 4a3db3b873a56c5bf88c72f97b11437d7601c8aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8240 zcmeH{&ui0Q7{{MPC#+!7_C=?nHSO!fA21_MiU((>2e0$TVJ8va!){KKC2p$xyqJjvb69g4>^?8%@ZM}K&^cF(N`+h&q^Sqygj6$&5 z+GF&)x(zJVT;=LzU~Bk)6`0yw)uV$=bbW=b)?oy6;8}K3hfyd2IXiixXDa|Tp8g(P zzTUKYOJ7;K3#{I>$%eZyy{r>04Hf_p4dAj0;Es>~w93a#YskRM#H(cDy6uiX`p(X) zfO~0It!}c)1=FI2`EK&e4{Hc`2HC@kRnGSFJ{B0}Wdqmj(zl}G0a2z>v|_--6o9XJ z;5suYq8Y%-;n6r3d@bGwk0?ro-r%_s_%-lcN2?Ic1a>VvlGOWB%v4gC^XM&}v%$|* zQke6IRswb<98BtcDo&*;*ca$+o(sUANmZ~fo^=S=#qdy^gHK{U&sf2}&Gvk!`FscC zoc&SEcZcWfW_!MKe7*xoy$@o(8J-K8?fLK-UI~jyz4v0imKQN!na{UB&XwL4kM(DX zGB!fSVTBq6HF9{WKkGWq2+=CQCd0i+&DX`f`C-g9<$2e3uv4OIgJJMw^OhiIQu4Hy;rUs%*CwojI$BHjq_v3Y3=BqF3$j@>n>0hVYIXjQ<4emLMv+P2c7i`oUl<2(GR|~FPoo=(rlc@KO z=-i55!+obVjrk64Gc zd~3Mo9Ai2gqYSc~6mNn*)V^;}~c_ayk4S=Av(1 z=XcLaLx7{mpEMv1NCVP}Uh)`l&N;#q}Uh)`l&N;#q