V-Ext: Tests for vle8 and vse8 * Verification of a simple load then store. * Adds tests for multiple VL and LMUL values. Tests were verified to pass in Qemu. Change-Id: Icf0cb445534b0de60aadfc9aff0aeadb29329dc3
diff --git a/CMakeLists.txt b/CMakeLists.txt index cd80428..e7acefb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -36,4 +36,7 @@ add_subdirectory(pw_unit_test_demo) +add_subdirectory(test_v_helpers) + add_subdirectory(test_vsetvl) +add_subdirectory(test_vle_vse)
diff --git a/cmake/vec_cc_test.cmake b/cmake/vec_cc_test.cmake index ff355ba..332a085 100644 --- a/cmake/vec_cc_test.cmake +++ b/cmake/vec_cc_test.cmake
@@ -20,6 +20,7 @@ pw_unit_test pw_unit_test.main pw_assert_basic + test_v_helpers ${_RULE_DEPS} LINKOPTS ${_RULE_LINKOPTS}
diff --git a/test_v_helpers/CMakeLists.txt b/test_v_helpers/CMakeLists.txt new file mode 100644 index 0000000..5a3b3ce --- /dev/null +++ b/test_v_helpers/CMakeLists.txt
@@ -0,0 +1,9 @@ + +add_library(test_v_helpers + test_v_helpers.cpp) + +target_include_directories(test_v_helpers PUBLIC include) + +target_compile_options(test_v_helpers PUBLIC + ${VEC_DEFAULT_COPTS} +)
diff --git a/test_v_helpers/include/test_v_helpers.h b/test_v_helpers/include/test_v_helpers.h new file mode 100644 index 0000000..25d8975 --- /dev/null +++ b/test_v_helpers/include/test_v_helpers.h
@@ -0,0 +1,35 @@ +#ifndef TEST_V_HELPERS_H +#define TEST_V_HELPERS_H + +namespace test_v_helpers { + +enum VSEW { + SEW_E8 = 0, + SEW_E16 = 1, + SEW_E32 = 2, +/* // SEW limited to E32 + SEW_E64 = 3, + SEW_E128 = 4, + SEW_E256 = 5, + SEW_E512 = 6, + SEW_E1024 = 7, +*/ +}; + +enum VLMUL { + +/* // Fractional LMUL not supported by our compiler + LMUL_MF8 = 5, + LMUL_MF4 = 6, + LMUL_MF2 = 7, +*/ + LMUL_M1 = 0, + LMUL_M2 = 1, + LMUL_M4 = 2, + LMUL_M8 = 3, +}; + +int set_vsetvl_intrinsic(VSEW sew, VLMUL lmul, uint32_t avl); + +} +#endif \ No newline at end of file
diff --git a/test_v_helpers/test_v_helpers.cpp b/test_v_helpers/test_v_helpers.cpp new file mode 100644 index 0000000..6d91c16 --- /dev/null +++ b/test_v_helpers/test_v_helpers.cpp
@@ -0,0 +1,78 @@ +#include <riscv_vector.h> +#include "test_v_helpers.h" + + +namespace test_v_helpers { + +int set_vsetvl_intrinsic(VSEW sew, VLMUL lmul, uint32_t avl) { + switch(lmul) { + case VLMUL::LMUL_M1: + switch(sew) { + case VSEW::SEW_E8: + return vsetvl_e8m1(avl); + break; + case VSEW::SEW_E16: + return vsetvl_e16m1(avl); + break; + case VSEW::SEW_E32: + return vsetvl_e32m1(avl); + break; + default: + return -1; + break; + } + break; + case VLMUL::LMUL_M2: + switch(sew) { + case VSEW::SEW_E8: + return vsetvl_e8m2(avl); + break; + case VSEW::SEW_E16: + return vsetvl_e16m2(avl); + break; + case VSEW::SEW_E32: + return vsetvl_e32m2(avl); + break; + default: + return -1; + break; + } + case VLMUL::LMUL_M4: + switch(sew) { + case VSEW::SEW_E8: + return vsetvl_e8m4(avl); + break; + case VSEW::SEW_E16: + return vsetvl_e16m4(avl); + break; + case VSEW::SEW_E32: + return vsetvl_e32m4(avl); + break; + default: + return -1; + break; + } + break; + case VLMUL::LMUL_M8: + switch(sew) { + case VSEW::SEW_E8: + return vsetvl_e8m8(avl); + break; + case VSEW::SEW_E16: + return vsetvl_e16m8(avl); + break; + case VSEW::SEW_E32: + return vsetvl_e32m8(avl); + break; + default: + return -1; + break; + } + break; + default: + break; + } + return -1; +} + +} \ No newline at end of file
diff --git a/test_vle_vse/CMakeLists.txt b/test_vle_vse/CMakeLists.txt new file mode 100644 index 0000000..8a98026 --- /dev/null +++ b/test_vle_vse/CMakeLists.txt
@@ -0,0 +1,12 @@ + +vec_cc_test( + NAME + test_vle_vse + SRCS + test_vle_vse.cpp + DEPS + springbok + LINKOPTS + -T${LINKER_SCRIPT} + -Xlinker --defsym=__itcm_length__=256K +)
diff --git a/test_vle_vse/test_vle_vse.cpp b/test_vle_vse/test_vle_vse.cpp new file mode 100644 index 0000000..e2a9152 --- /dev/null +++ b/test_vle_vse/test_vle_vse.cpp
@@ -0,0 +1,143 @@ +#include <riscv_vector.h> +#include <stddef.h> +#include <springbok_intrinsics.h> + +#include "test_v_helpers.h" +#include "pw_unit_test/framework.h" + +namespace vle_vse_test { +namespace { + +using namespace test_v_helpers; + +const int VLEN = 512u; +const int ELEN = 32u; +const int LMUL_MAX = 8u; +const int MAXVL_BYTES = VLEN / sizeof(uint8_t) * LMUL_MAX; +const int AVL_STEP = 4; + +uint8_t test_vector_1[MAXVL_BYTES]; +uint8_t test_vector_2[MAXVL_BYTES]; + +static int get_vsetvlmax(VSEW sew, VLMUL lmul) { + switch(lmul) { + case VLMUL::LMUL_M1: + switch(sew) { + case VSEW::SEW_E8: + return vsetvlmax_e8m1(); + break; + case VSEW::SEW_E16: + return vsetvlmax_e16m1(); + break; + case VSEW::SEW_E32: + return vsetvlmax_e32m1(); + break; + default: + return -1; + break; + } + break; + case VLMUL::LMUL_M2: + switch(sew) { + case VSEW::SEW_E8: + return vsetvlmax_e8m2(); + break; + case VSEW::SEW_E16: + return vsetvlmax_e16m2(); + break; + case VSEW::SEW_E32: + return vsetvlmax_e32m2(); + break; + default: + return -1; + break; + } + case VLMUL::LMUL_M4: + switch(sew) { + case VSEW::SEW_E8: + return vsetvlmax_e8m4(); + break; + case VSEW::SEW_E16: + return vsetvlmax_e16m4(); + break; + case VSEW::SEW_E32: + return vsetvlmax_e32m4(); + break; + default: + return -1; + break; + } + break; + case VLMUL::LMUL_M8: + switch(sew) { + case VSEW::SEW_E8: + return vsetvlmax_e8m8(); + break; + case VSEW::SEW_E16: + return vsetvlmax_e16m8(); + break; + case VSEW::SEW_E32: + return vsetvlmax_e32m8(); + break; + default: + return -1; + break; + } + break; + default: + break; + } + return -1; +} + + +static void vle8vse8_test(VSEW sew, VLMUL lmul, bool use_intrinsic) { + int vlmax = get_vsetvlmax(sew, lmul); + + for (int avl = 0; avl <= vlmax; avl+=AVL_STEP) { + // clear arrays + memset(test_vector_1, 0, MAXVL_BYTES); + memset(test_vector_2, 0, MAXVL_BYTES); + int vl = set_vsetvl_intrinsic(sew, lmul, avl); + EXPECT_EQ(avl, vl); + uint8_t *dest = (uint8_t *)test_vector_1; + for (int idx = 0; idx < vl; idx++) { + dest[idx] = idx; + } + + // load c-array values into vector + // TODO(gkielian): utilize intrinsics for vle + if (use_intrinsic) { + + } else { + __asm__ volatile("vle8.v v0, (%0)" : : "r" (test_vector_1)); + + // 2) store the vector back into memory (into result c-array) + __asm__ volatile("vse8.v v0, (%0)" : : "r" (test_vector_2)); + } + for(int idx = 0; idx < MAXVL_BYTES; idx++) + { + EXPECT_EQ(test_vector_1[idx], test_vector_2[idx]); + } + } +} + +TEST(VleVseTest, vle8vse8_e8m1) { + vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M1, false); +} + +TEST(VleVseTest, vle8vse8_e8m2) { + vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M2, false); +} + +TEST(VleVseTest, vle8vse8_e8m4) { + vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M4, false); +} + +TEST(VleVseTest, vle8vse8_e8m8) { + vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M8, false); +} + +} // namespace +} // namespace test_vle_vse +