Line 44... |
Line 44... |
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* Unavailable extensions warning.
|
* Unavailable extensions warning.
|
**************************************************************************/
|
**************************************************************************/
|
#if defined __riscv_f || (__riscv_flen == 32)
|
|
#warning Single-precision floating-point extension <F/Zfinx> is WORK-IN-PROGRESS and there is NO NATIVE SUPPORT BY THE COMPILER yet!
|
|
#endif
|
|
|
|
#if defined __riscv_d || (__riscv_flen == 64)
|
#if defined __riscv_d || (__riscv_flen == 64)
|
#error Double-precision floating-point extension <D/Zdinx> is NOT supported!
|
#error Double-precision floating-point extension <D/Zdinx> is NOT supported!
|
#endif
|
#endif
|
|
|
#if (__riscv_xlen > 32)
|
#if (__riscv_xlen > 32)
|
#error Only 32-bit <rv32> is supported!
|
#error Only 32-bit <rv32> is supported!
|
#endif
|
#endif
|
|
|
#ifdef __riscv_b
|
|
#warning Bit-manipulation extension <B> is still experimental (non-ratified) and does not support all <Zb*> subsets yet.
|
|
#endif
|
|
|
|
#ifdef __riscv_fdiv
|
#ifdef __riscv_fdiv
|
#warning Floating-point division instruction <FDIV> is NOT supported yet!
|
#warning Floating-point division instruction <FDIV> is NOT supported yet!
|
#endif
|
#endif
|
|
|
#ifdef __riscv_fsqrt
|
#ifdef __riscv_fsqrt
|
Line 271... |
Line 263... |
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* Delay function using busy wait.
|
* Delay function using busy wait.
|
*
|
*
|
* @note This function uses the time CSRs (from int./ext. MTIME). A simple ASM loop
|
* @note This function uses MTIME as time base. A simple ASM loop
|
* is used as fall back if system timer is not advancing (no MTIME available).
|
* is used as fall back if system timer is not implemented.
|
*
|
*
|
* @warning Delay time might be less precise if M extensions is not available
|
* @warning Delay time might be less precise if M extensions is not available
|
* (especially if MTIME unit is not available).
|
* (especially if MTIME unit is not available).
|
*
|
*
|
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
Line 284... |
Line 276... |
void neorv32_cpu_delay_ms(uint32_t time_ms) {
|
void neorv32_cpu_delay_ms(uint32_t time_ms) {
|
|
|
uint32_t clock = NEORV32_SYSINFO.CLK; // clock ticks per second
|
uint32_t clock = NEORV32_SYSINFO.CLK; // clock ticks per second
|
clock = clock / 1000; // clock ticks per ms
|
clock = clock / 1000; // clock ticks per ms
|
|
|
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
|
register uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
|
|
register uint64_t tmp = 0;
|
|
|
register uint64_t tmp = neorv32_cpu_get_systime();
|
// MTIME available?
|
if (neorv32_cpu_get_systime() > tmp) { // system time advancing (MTIME available and running)?
|
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_MTIME)) {
|
|
|
// use MTIME machine timer
|
// use MTIME machine timer
|
tmp += wait_cycles;
|
tmp = neorv32_mtime_get_time() + wait_cycles;
|
while(1) {
|
while(1) {
|
if (neorv32_cpu_get_systime() >= tmp) {
|
if (neorv32_mtime_get_time() >= tmp) {
|
break;
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
else {
|
else {
|
// use ASM loop
|
// use ASM loop
|
// warning! not really precise (especially if M extensions is not available)!
|
// warning! not really precise (especially if M extensions is not available)!
|
|
|
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop
|
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop
|
uint32_t iterations = (uint32_t)(wait_cycles / loop_cycles_c);
|
register uint32_t iterations = (uint32_t)(wait_cycles / loop_cycles_c); // M (div) extension would be nice here!
|
|
|
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned
|
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned
|
" __neorv32_cpu_delay_ms_start: \n"
|
" __neorv32_cpu_delay_ms_start: \n"
|
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken)
|
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken)
|
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken)
|
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken)
|
Line 345... |
Line 338... |
* @return Returns number of available PMP regions.
|
* @return Returns number of available PMP regions.
|
**************************************************************************/
|
**************************************************************************/
|
uint32_t neorv32_cpu_pmp_get_num_regions(void) {
|
uint32_t neorv32_cpu_pmp_get_num_regions(void) {
|
|
|
// PMP implemented at all?
|
// PMP implemented at all?
|
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_PMP)) == 0) {
|
if ((neorv32_cpu_csr_read(CSR_MXISA) & (1<<CSR_MXISA_PMP)) == 0) {
|
return 0;
|
return 0;
|
}
|
}
|
|
|
uint32_t i = 0;
|
uint32_t i = 0;
|
|
|
Line 610... |
Line 603... |
* @return Returns number of available HPM counters (0..29).
|
* @return Returns number of available HPM counters (0..29).
|
**************************************************************************/
|
**************************************************************************/
|
uint32_t neorv32_cpu_hpm_get_counters(void) {
|
uint32_t neorv32_cpu_hpm_get_counters(void) {
|
|
|
// HPMs implemented at all?
|
// HPMs implemented at all?
|
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZIHPM)) == 0) {
|
if ((neorv32_cpu_csr_read(CSR_MXISA) & (1<<CSR_MXISA_ZIHPM)) == 0) {
|
return 0;
|
return 0;
|
}
|
}
|
|
|
// inhibit all HPM counters
|
// inhibit all HPM counters
|
uint32_t tmp = neorv32_cpu_csr_read(CSR_MCOUNTINHIBIT);
|
uint32_t tmp = neorv32_cpu_csr_read(CSR_MCOUNTINHIBIT);
|
Line 693... |
Line 686... |
* @return Size of HPM counter bits (1-64, 0 if not implemented at all).
|
* @return Size of HPM counter bits (1-64, 0 if not implemented at all).
|
**************************************************************************/
|
**************************************************************************/
|
uint32_t neorv32_cpu_hpm_get_size(void) {
|
uint32_t neorv32_cpu_hpm_get_size(void) {
|
|
|
// HPMs implemented at all?
|
// HPMs implemented at all?
|
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZIHPM)) == 0) {
|
if ((neorv32_cpu_csr_read(CSR_MXISA) & (1<<CSR_MXISA_ZIHPM)) == 0) {
|
return 0;
|
return 0;
|
}
|
}
|
|
|
// inhibt auto-update
|
// inhibt auto-update
|
asm volatile ("csrwi %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_HPM3));
|
asm volatile ("csrwi %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_HPM3));
|