Line 112... |
Line 112... |
float_conv_t res_hw;
|
float_conv_t res_hw;
|
float_conv_t res_sw;
|
float_conv_t res_sw;
|
|
|
|
|
// init primary UART
|
// init primary UART
|
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
|
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
|
|
|
// capture all exceptions and give debug info via UART
|
// capture all exceptions and give debug info via UART
|
neorv32_rte_setup();
|
neorv32_rte_setup();
|
|
|
// check available hardware extensions and compare with compiler flags
|
// check available hardware extensions and compare with compiler flags
|
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
|
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
|
|
|
// check if Zfinx extension is implemented at all
|
// check if Zfinx extension is implemented at all
|
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZFINX)) == 0) {
|
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZFINX)) == 0) {
|
neorv32_uart_print("Error! <Zfinx> extension not synthesized!\n");
|
neorv32_uart0_print("Error! <Zfinx> extension not synthesized!\n");
|
return 1;
|
return 1;
|
}
|
}
|
|
|
|
|
// Disable compilation by default
|
// Disable compilation by default
|
#ifndef RUN_CHECK
|
#ifndef RUN_CHECK
|
#warning Program HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.
|
#warning Program HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.
|
|
|
// inform the user if you are actually executing this
|
// inform the user if you are actually executing this
|
neorv32_uart_printf("ERROR! Program has not been compiled. Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.\n");
|
neorv32_uart0_printf("ERROR! Program has not been compiled. Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.\n");
|
|
|
return 1;
|
return 1;
|
#endif
|
#endif
|
|
|
|
|
// intro
|
// intro
|
neorv32_uart_printf("<<< Zfinx extension test >>>\n");
|
neorv32_uart0_printf("<<< Zfinx extension test >>>\n");
|
#if (SILENT_MODE != 0)
|
#if (SILENT_MODE != 0)
|
neorv32_uart_printf("SILENT_MODE enabled (only showing actual errors)\n");
|
neorv32_uart0_printf("SILENT_MODE enabled (only showing actual errors)\n");
|
#endif
|
#endif
|
neorv32_uart_printf("Test cases per instruction: %u\n", (uint32_t)NUM_TEST_CASES);
|
neorv32_uart0_printf("Test cases per instruction: %u\n", (uint32_t)NUM_TEST_CASES);
|
neorv32_uart_printf("NOTE: The NEORV32 FPU does not support subnormal numbers yet. Subnormal numbers are flushed to zero.\n\n");
|
neorv32_uart0_printf("NOTE: The NEORV32 FPU does not support subnormal numbers yet. Subnormal numbers are flushed to zero.\n\n");
|
|
|
// clear exception status word
|
// clear exception status word
|
neorv32_cpu_csr_write(CSR_FFLAGS, 0); // real hardware
|
neorv32_cpu_csr_write(CSR_FFLAGS, 0); // real hardware
|
feclearexcept(FE_ALL_EXCEPT); // software runtime (GCC floating-point emulation)
|
feclearexcept(FE_ALL_EXCEPT); // software runtime (GCC floating-point emulation)
|
|
|
Line 156... |
Line 156... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Conversion Tests
|
// Conversion Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_CONV_TESTS != 0)
|
#if (RUN_CONV_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FCVT.S.WU (unsigned integer to float)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FCVT.S.WU (unsigned integer to float)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fcvt_swu(opa.binary_value);
|
res_hw.float_value = riscv_intrinsic_fcvt_swu(opa.binary_value);
|
res_sw.float_value = riscv_emulate_fcvt_swu(opa.binary_value);
|
res_sw.float_value = riscv_emulate_fcvt_swu(opa.binary_value);
|
Line 168... |
Line 168... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FCVT.S.W (signed integer to float)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FCVT.S.W (signed integer to float)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fcvt_sw((int32_t)opa.binary_value);
|
res_hw.float_value = riscv_intrinsic_fcvt_sw((int32_t)opa.binary_value);
|
res_sw.float_value = riscv_emulate_fcvt_sw((int32_t)opa.binary_value);
|
res_sw.float_value = riscv_emulate_fcvt_sw((int32_t)opa.binary_value);
|
Line 180... |
Line 180... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FCVT.WU.S (float to unsigned integer)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FCVT.WU.S (float to unsigned integer)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
res_hw.binary_value = riscv_intrinsic_fcvt_wus(opa.float_value);
|
res_hw.binary_value = riscv_intrinsic_fcvt_wus(opa.float_value);
|
res_sw.binary_value = riscv_emulate_fcvt_wus(opa.float_value);
|
res_sw.binary_value = riscv_emulate_fcvt_wus(opa.float_value);
|
Line 192... |
Line 192... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FCVT.W.S (float to signed integer)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FCVT.W.S (float to signed integer)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
res_hw.binary_value = (uint32_t)riscv_intrinsic_fcvt_ws(opa.float_value);
|
res_hw.binary_value = (uint32_t)riscv_intrinsic_fcvt_ws(opa.float_value);
|
res_sw.binary_value = (uint32_t)riscv_emulate_fcvt_ws(opa.float_value);
|
res_sw.binary_value = (uint32_t)riscv_emulate_fcvt_ws(opa.float_value);
|
Line 211... |
Line 211... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Add/Sub Tests
|
// Add/Sub Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_ADDSUB_TESTS != 0)
|
#if (RUN_ADDSUB_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FADD.S (addition)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FADD.S (addition)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fadds(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fadds(opa.float_value, opb.float_value);
|
Line 224... |
Line 224... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FSUB.S (subtraction)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FSUB.S (subtraction)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fsubs(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fsubs(opa.float_value, opb.float_value);
|
Line 244... |
Line 244... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Multiplication Tests
|
// Multiplication Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_MUL_TESTS != 0)
|
#if (RUN_MUL_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FMUL.S (multiplication)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FMUL.S (multiplication)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fmuls(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fmuls(opa.float_value, opb.float_value);
|
Line 264... |
Line 264... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Min/Max Tests
|
// Min/Max Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_MINMAX_TESTS != 0)
|
#if (RUN_MINMAX_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FMIN.S (select minimum)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FMIN.S (select minimum)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fmins(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fmins(opa.float_value, opb.float_value);
|
Line 277... |
Line 277... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FMAX.S (select maximum)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FMAX.S (select maximum)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fmaxs(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fmaxs(opa.float_value, opb.float_value);
|
Line 297... |
Line 297... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Comparison Tests
|
// Comparison Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_COMPARE_TESTS != 0)
|
#if (RUN_COMPARE_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FEQ.S (compare if equal)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FEQ.S (compare if equal)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.binary_value = riscv_intrinsic_feqs(opa.float_value, opb.float_value);
|
res_hw.binary_value = riscv_intrinsic_feqs(opa.float_value, opb.float_value);
|
Line 310... |
Line 310... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FLT.S (compare if less-than)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FLT.S (compare if less-than)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.binary_value = riscv_intrinsic_flts(opa.float_value, opb.float_value);
|
res_hw.binary_value = riscv_intrinsic_flts(opa.float_value, opb.float_value);
|
Line 323... |
Line 323... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FLE.S (compare if less-than-or-equal)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FLE.S (compare if less-than-or-equal)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.binary_value = riscv_intrinsic_fles(opa.float_value, opb.float_value);
|
res_hw.binary_value = riscv_intrinsic_fles(opa.float_value, opb.float_value);
|
Line 343... |
Line 343... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Sign-Injection Tests
|
// Sign-Injection Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_SGNINJ_TESTS != 0)
|
#if (RUN_SGNINJ_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FSGNJ.S (sign-injection)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FSGNJ.S (sign-injection)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fsgnjs(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fsgnjs(opa.float_value, opb.float_value);
|
Line 356... |
Line 356... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FSGNJN.S (sign-injection NOT)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FSGNJN.S (sign-injection NOT)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fsgnjns(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fsgnjns(opa.float_value, opb.float_value);
|
Line 369... |
Line 369... |
}
|
}
|
print_report(err_cnt);
|
print_report(err_cnt);
|
err_cnt_total += err_cnt;
|
err_cnt_total += err_cnt;
|
test_cnt++;
|
test_cnt++;
|
|
|
neorv32_uart_printf("\n#%u: FSGNJX.S (sign-injection XOR)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FSGNJX.S (sign-injection XOR)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
res_hw.float_value = riscv_intrinsic_fsgnjxs(opa.float_value, opb.float_value);
|
res_hw.float_value = riscv_intrinsic_fsgnjxs(opa.float_value, opb.float_value);
|
Line 389... |
Line 389... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Classify Tests
|
// Classify Tests
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_CLASSIFY_TESTS != 0)
|
#if (RUN_CLASSIFY_TESTS != 0)
|
neorv32_uart_printf("\n#%u: FCLASS.S (classify)...\n", test_cnt);
|
neorv32_uart0_printf("\n#%u: FCLASS.S (classify)...\n", test_cnt);
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
for (i=0;i<(uint32_t)NUM_TEST_CASES; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
res_hw.binary_value = riscv_intrinsic_fclasss(opa.float_value);
|
res_hw.binary_value = riscv_intrinsic_fclasss(opa.float_value);
|
res_sw.binary_value = riscv_emulate_fclasss(opa.float_value);
|
res_sw.binary_value = riscv_emulate_fclasss(opa.float_value);
|
Line 408... |
Line 408... |
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// UNSUPPORTED Instructions Tests - Execution should raise illegal instruction exception
|
// UNSUPPORTED Instructions Tests - Execution should raise illegal instruction exception
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
#if (RUN_UNAVAIL_TESTS != 0)
|
#if (RUN_UNAVAIL_TESTS != 0)
|
neorv32_uart_printf("\n# unsupported FDIV.S (division) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FDIV.S (division) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fdivs(opa.float_value, opb.float_value);
|
riscv_intrinsic_fdivs(opa.float_value, opb.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
|
|
neorv32_uart_printf("\n# unsupported FSQRT.S (square root) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FSQRT.S (square root) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fsqrts(opa.float_value);
|
riscv_intrinsic_fsqrts(opa.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
|
|
neorv32_uart_printf("\n# unsupported FMADD.S (fused multiply-add) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FMADD.S (fused multiply-add) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fmadds(opa.float_value, opb.float_value, -opa.float_value);
|
riscv_intrinsic_fmadds(opa.float_value, opb.float_value, -opa.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
|
|
neorv32_uart_printf("\n# unsupported FMSUB.S (fused multiply-sub) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FMSUB.S (fused multiply-sub) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fmsubs(opa.float_value, opb.float_value, -opa.float_value);
|
riscv_intrinsic_fmsubs(opa.float_value, opb.float_value, -opa.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
|
|
neorv32_uart_printf("\n# unsupported FNMSUB.S (fused negated multiply-sub) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FNMSUB.S (fused negated multiply-sub) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
|
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
|
|
neorv32_uart_printf("\n# unsupported FNMADD.S (fused negated multiply-add) [illegal instruction]...\n");
|
neorv32_uart0_printf("\n# unsupported FNMADD.S (fused negated multiply-add) [illegal instruction]...\n");
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
opb.binary_value = get_test_vector();
|
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
|
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
#endif
|
#endif
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
Line 497... |
Line 497... |
#if (RUN_TIMING_TESTS != 0)
|
#if (RUN_TIMING_TESTS != 0)
|
|
|
uint32_t time_start, time_sw, time_hw;
|
uint32_t time_start, time_sw, time_hw;
|
const uint32_t num_runs = 4096;
|
const uint32_t num_runs = 4096;
|
|
|
neorv32_uart_printf("\nAverage execution time tests (%u runs)\n", num_runs);
|
neorv32_uart0_printf("\nAverage execution time tests (%u runs)\n", num_runs);
|
|
|
|
|
// signed integer to float
|
// signed integer to float
|
neorv32_uart_printf("FCVT.S.W: ");
|
neorv32_uart0_printf("FCVT.S.W: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 529... |
Line 529... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// float to signed integer
|
// float to signed integer
|
neorv32_uart_printf("FCVT.W.S: ");
|
neorv32_uart0_printf("FCVT.W.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 566... |
Line 566... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// addition
|
// addition
|
neorv32_uart_printf("FADD.S: ");
|
neorv32_uart0_printf("FADD.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 604... |
Line 604... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// subtraction
|
// subtraction
|
neorv32_uart_printf("FSUB.S: ");
|
neorv32_uart0_printf("FSUB.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 642... |
Line 642... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// multiplication
|
// multiplication
|
neorv32_uart_printf("FMUL.S: ");
|
neorv32_uart0_printf("FMUL.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 680... |
Line 680... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// Max
|
// Max
|
neorv32_uart_printf("FMAX.S: ");
|
neorv32_uart0_printf("FMAX.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 718... |
Line 718... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// Comparison
|
// Comparison
|
neorv32_uart_printf("FLE.S: ");
|
neorv32_uart0_printf("FLE.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 756... |
Line 756... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
|
|
|
|
// Sign-injection
|
// Sign-injection
|
neorv32_uart_printf("FSGNJX.S: ");
|
neorv32_uart0_printf("FSGNJX.S: ");
|
time_sw = 0;
|
time_sw = 0;
|
time_hw = 0;
|
time_hw = 0;
|
err_cnt = 0;
|
err_cnt = 0;
|
for (i=0; i<num_runs; i++) {
|
for (i=0; i<num_runs; i++) {
|
opa.binary_value = get_test_vector();
|
opa.binary_value = get_test_vector();
|
Line 794... |
Line 794... |
err_cnt++;
|
err_cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (err_cnt == 0) {
|
if (err_cnt == 0) {
|
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
neorv32_uart0_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
|
err_cnt_total++;
|
err_cnt_total++;
|
}
|
}
|
#endif
|
#endif
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Final report
|
// Final report
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
if (err_cnt_total != 0) {
|
if (err_cnt_total != 0) {
|
neorv32_uart_printf("\n%c[1m[ZFINX EXTENSION VERIFICATION FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("\n%c[1m[ZFINX EXTENSION VERIFICATION FAILED!]%c[0m\n", 27, 27);
|
neorv32_uart_printf("%u errors in %u test cases\n", err_cnt_total, test_cnt*(uint32_t)NUM_TEST_CASES);
|
neorv32_uart0_printf("%u errors in %u test cases\n", err_cnt_total, test_cnt*(uint32_t)NUM_TEST_CASES);
|
return 1;
|
return 1;
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("\n%c[1m[Zfinx extension verification successful!]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("\n%c[1m[Zfinx extension verification successful!]%c[0m\n", 27, 27);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
}
|
}
|
|
|
Line 882... |
Line 882... |
* @return zero if results are equal.
|
* @return zero if results are equal.
|
**************************************************************************/
|
**************************************************************************/
|
uint32_t verify_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
|
uint32_t verify_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
|
|
|
#if (SILENT_MODE == 0)
|
#if (SILENT_MODE == 0)
|
neorv32_uart_printf("%u: opa = 0x%x, opb = 0x%x : ref[SW] = 0x%x vs. res[HW] = 0x%x ", num, opa, opb, ref, res);
|
neorv32_uart0_printf("%u: opa = 0x%x, opb = 0x%x : ref[SW] = 0x%x vs. res[HW] = 0x%x ", num, opa, opb, ref, res);
|
#endif
|
#endif
|
|
|
if (ref != res) {
|
if (ref != res) {
|
#if (SILENT_MODE != 0)
|
#if (SILENT_MODE != 0)
|
neorv32_uart_printf("%u: opa = 0x%x, opb = 0x%x : ref[SW] = 0x%x vs. res[HW] = 0x%x ", num, opa, opb, ref, res);
|
neorv32_uart0_printf("%u: opa = 0x%x, opb = 0x%x : ref[SW] = 0x%x vs. res[HW] = 0x%x ", num, opa, opb, ref, res);
|
#endif
|
#endif
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
return 1;
|
return 1;
|
}
|
}
|
else {
|
else {
|
#if (SILENT_MODE == 0)
|
#if (SILENT_MODE == 0)
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
#endif
|
#endif
|
return 0;
|
return 0;
|
}
|
}
|
}
|
}
|
|
|
Line 908... |
Line 908... |
*
|
*
|
* @param[in] num_err Number or errors in this test.
|
* @param[in] num_err Number or errors in this test.
|
**************************************************************************/
|
**************************************************************************/
|
void print_report(uint32_t num_err) {
|
void print_report(uint32_t num_err) {
|
|
|
neorv32_uart_printf("Errors: %u/%u ", num_err, (uint32_t)NUM_TEST_CASES);
|
neorv32_uart0_printf("Errors: %u/%u ", num_err, (uint32_t)NUM_TEST_CASES);
|
|
|
if (num_err == 0) {
|
if (num_err == 0) {
|
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
|
}
|
}
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|