OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sw/example/bitmanip_test
    from Rev 65 to Rev 66
    Reverse comparison

Rev 65 → Rev 66

/README.md
1,12 → 1,12
# NEORV32 Bit-Manipulation `B` Extension (`Zbb` sub-extension)
# NEORV32 Bit-Manipulation `B` Extension
 
:warning: The RISC-V bit-manipulation extension is frozen but not yet officially ratified.
 
:warning: The NEORV32 bit manipulation extensions only supports the `Zbb` sub-extension
:warning: The NEORV32 bit manipulation extensions `B` only supports the `Zbb` and `Zba` sub-extension
(basic bit-manipulation operation) yet.
 
The provided test program `main.c` verifies all currently implemented instruction by checking the results against a pure-software emulation model.
The emulation functions as well as the available **intrinsics** for the `Zbb` extension are located in `neorv32_b_extension_intrinsics.h`.
The emulation functions as well as the available **intrinsics** for the sub-extension are located in `neorv32_b_extension_intrinsics.h`.
 
:information_source: More information regarding the RISC-V bit manipulation extension can be found in the officail GitHub repo:
[github.com/riscv/riscv-bitmanip](https://github.com/riscv/riscv-bitmanip).
/main.c
1,5 → 1,5
// #################################################################################################
// # << NEORV32 - RISC-V Bit-Manipulation 'Zbb' Extension Test Program >> #
// # << NEORV32 - RISC-V Bit-Manipulation 'B' Extension Test Program >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
36,7 → 36,7
/**********************************************************************//**
* @file bitmanip_test/main.c
* @author Stephan Nolting
* @brief Test program for the NEORV32 'Zbb' extension using pseudo-random
* @brief Test program for the NEORV32 'B` extension using pseudo-random
* data as input; compares results from hardware against pure-sw reference functions.
**************************************************************************/
 
64,7 → 64,7
* Main function; test all available operations of the NEORV32 'Zbb' extensions
* using bit manipulation intrinsics and software-only reference functions (emulation).
*
* @note This program requires the Zbb CPU extension.
* @note This program requires the bit-manipulation CPU extension.
*
* @return Irrelevant.
**************************************************************************/
91,19 → 91,23
#endif
 
// intro
neorv32_uart0_printf("NEORV32 'Zbb' Bit-Manipulation Extension Test\n\n");
neorv32_uart0_printf("NEORV32 Bit-Manipulation Extension Test (Zba, Zbb)\n\n");
 
// check available hardware extensions and compare with compiler flags
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
 
// check if Zbb extension is implemented at all
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZBB)) == 0) {
neorv32_uart0_print("Error! <Zbb> extension not synthesized!\n");
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_B)) == 0) {
neorv32_uart0_print("Error! <B> extension not synthesized!\n");
return 1;
}
 
neorv32_uart0_printf("Starting Zbb bit-manipulation extension tests (%i test cases per instruction)...\n", num_tests);
neorv32_uart0_printf("Starting bit-manipulation extension tests (%i test cases per instruction)...\n\n", num_tests);
 
neorv32_uart0_printf("-----------------------------------------\n");
neorv32_uart0_printf("Zbb - Basic bit-manipulation instructions\n");
neorv32_uart0_printf("-----------------------------------------\n");
 
// ANDN
neorv32_uart0_printf("\nANDN:\n");
err_cnt = 0;
326,6 → 330,48
print_report(err_cnt, num_tests);
 
 
 
neorv32_uart0_printf("\n\n");
neorv32_uart0_printf("-----------------------------------------\n");
neorv32_uart0_printf("Zba - Address generation instructions\n");
neorv32_uart0_printf("-----------------------------------------\n");
 
// SH1ADD
neorv32_uart0_printf("\nSH1ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
opb = xorshift32();
res_sw = riscv_emulate_sh1add(opa, opb);
res_hw = riscv_intrinsic_sh1add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
// SH2ADD
neorv32_uart0_printf("\nSH2ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
opb = xorshift32();
res_sw = riscv_emulate_sh2add(opa, opb);
res_hw = riscv_intrinsic_sh2add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
// SH2ADD
neorv32_uart0_printf("\nSH3ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
res_sw = riscv_emulate_sh3add(opa, opb);
res_hw = riscv_intrinsic_sh3add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
 
neorv32_uart0_printf("\nBit manipulation extension tests done.\n");
 
return 0;
/neorv32_b_extension_intrinsics.h
1,8 → 1,8
// #################################################################################################
// # << NEORV32 - Intrinsics + Emulation Functions for the B CPU extensions >> #
// # << NEORV32 - Intrinsics + Emulation Functions for the CPU B extension >> #
// # ********************************************************************************************* #
// # The intrinsics provided by this library allow to use the hardware bit manipulation unit of #
// # the RISC-V B CPU extension without the need for B support by the compiler. #
// # the RISC-V B CPU extension without the need for support by the compiler. #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
39,10 → 39,10
/**********************************************************************//**
* @file bitmanip_test/neorv32_b_extension_intrinsics.h
* @author Stephan Nolting
* @brief "Intrinsic" library for the NEORV32 bit manipulation Zbb extension.
* @brief "Intrinsic" library for the NEORV32 bit manipulation B extension.
* Also provides emulation functions for all intrinsics (functionality re-built in pure software).
*
* @warning This library is just a temporary fall-back until the Zbb extensions are supported by the upstream RISC-V GCC port.
* @warning This library is just a temporary fall-back until the B extension is supported by the upstream RISC-V GCC port.
**************************************************************************/
#ifndef neorv32_b_extension_intrinsics_h
54,9 → 54,9
// ################################################################################################
 
 
// ---------------------------------------------
// ================================================================================================
// Zbb - Base instructions
// ---------------------------------------------
// ================================================================================================
 
/**********************************************************************//**
* Intrinsic: Bit manipulation CLZ (count leading zeros) [B.Zbb]
455,14 → 455,87
}
 
 
// ================================================================================================
// Zbb - Base instructions
// ================================================================================================
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 1)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh1add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh1add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b010, a0, 0b0110011);
 
return result;
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 2)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh2add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh2add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b100, a0, 0b0110011);
 
return result;
}
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-3-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 3)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh3add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh3add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b110, a0, 0b0110011);
 
return result;
}
 
 
 
// ################################################################################################
// Emulation functions
// ################################################################################################
 
 
// ---------------------------------------------
// ================================================================================================
// Zbb - Base instructions
// ---------------------------------------------
// ================================================================================================
 
 
/**********************************************************************//**
783,5 → 856,48
}
 
 
// ================================================================================================
// Zba - Address generation instructions
// ================================================================================================
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 1)
**************************************************************************/
uint32_t riscv_emulate_sh1add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 1);
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 2)
**************************************************************************/
uint32_t riscv_emulate_sh2add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 2);
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH3ADD (add with logical-3-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 3)
**************************************************************************/
uint32_t riscv_emulate_sh3add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 3);
}
 
 
#endif // neorv32_b_extension_intrinsics_h

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.