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/lib
    from Rev 37 to Rev 39
    Reverse comparison

Rev 37 → Rev 39

/include/neorv32.h
143,8 → 143,11
* CPU <b>misa</b> CSR (r/-): Machine instruction set extensions (RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MISA_enum {
CPU_MISA_A_EXT = 0, /**< CPU misa CSR (0): A: Atomic instructions CPU extension available (r/-)*/
CPU_MISA_B_EXT = 1, /**< CPU misa CSR (1): B: Bit manipulation CPU extension available (r/-)*/
CPU_MISA_C_EXT = 2, /**< CPU misa CSR (2): C: Compressed instructions CPU extension available (r/-)*/
CPU_MISA_E_EXT = 4, /**< CPU misa CSR (3): E: Embedded CPU extension available (r/-) */
CPU_MISA_E_EXT = 4, /**< CPU misa CSR (4): E: Embedded CPU extension available (r/-) */
CPU_MISA_F_EXT = 4, /**< CPU misa CSR (5): F: Floating point (single-precision) extension available (r/-) */
CPU_MISA_I_EXT = 8, /**< CPU misa CSR (8): I: Base integer ISA CPU extension available (r/-) */
CPU_MISA_M_EXT = 12, /**< CPU misa CSR (12): M: Multiplier/divider CPU extension available (r/-)*/
CPU_MISA_U_EXT = 20, /**< CPU misa CSR (20): U: User mode CPU extension available (r/-)*/
/include/neorv32_cpu.h
52,6 → 52,7
uint64_t neorv32_cpu_get_systime(void);
void neorv32_cpu_delay_ms(uint32_t time_ms);
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void);
int neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired);
 
 
/**********************************************************************//**
/source/neorv32_cpu.c
217,23 → 217,26
 
 
/**********************************************************************//**
* Simple delay function (not very precise) using busy wait.
* Simple delay function using busy wait.
*
* @warning This function requires the cycle CSR(s). Hence, the Zicsr extension is mandatory.
*
* @param[in] time_ms Time in ms to wait.
**************************************************************************/
void neorv32_cpu_delay_ms(uint32_t time_ms) {
 
uint32_t clock_speed = SYSINFO_CLK >> 10; // fake divide by 1000
clock_speed = clock_speed >> 5; // divide by loop execution time (~30 cycles)
uint32_t cnt = clock_speed * time_ms;
uint64_t time_resume = neorv32_cpu_get_cycle();
 
// one iteration = ~30 cycles
while (cnt) {
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
cnt--;
uint32_t clock = SYSINFO_CLK; // clock ticks per second
clock = clock / 1000; // clock ticks per ms
 
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
time_resume += wait_cycles;
 
while(1) {
if (neorv32_cpu_get_cycle() >= time_resume) {
break;
}
}
}
 
241,16 → 244,54
/**********************************************************************//**
* Switch from privilege mode MACHINE to privilege mode USER.
*
* @note This function requires the U extension to be implemented.
* @note Maybe you should do a fence.i after this.
* @warning This function requires the U extension to be implemented.
**************************************************************************/
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) {
 
// make sure to use NO registers in here! -> naked
 
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can use ra as general purpose register in here
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can now use ra as general purpose register in here
"li ra, %[input_imm] \n\t" // bit mask to clear the two MPP bits
"csrrc zero, mstatus, ra \n\t" // clear MPP bits -> MPP=u-mode
"mret \n\t" // return and switch to user mode
: : [input_imm] "i" ((1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L)));
}
 
 
/**********************************************************************//**
* Atomic compare-and-swap operation (for implemeneting semaphores and mutexes).
*
* @warning This function requires the A (atomic) CPU extension.
*
* @param[in] addr Address of memory location.
* @param[in] expected Expected value (for comparison).
* @param[in] desired Desired value (new value).
* @return Returns 0 on success, 1 on failure.
**************************************************************************/
int __attribute__ ((noinline)) neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired) {
#ifdef __riscv_atomic
 
register uint32_t addr_reg = addr;
register uint32_t des_reg = desired;
register uint32_t tmp_reg;
 
// load original value + reservation (lock)
asm volatile ("lr.w %[result], (%[input])" : [result] "=r" (tmp_reg) : [input] "r" (addr_reg));
 
if (tmp_reg != expected) {
asm volatile ("lw x0, 0(%[input])" : : [input] "r" (addr_reg)); // clear reservation lock
return 1;
}
 
// store-conditional
asm volatile ("sc.w %[result], %[input_i], (%[input_j])" : [result] "=r" (tmp_reg) : [input_i] "r" (des_reg), [input_j] "r" (addr_reg));
 
if (tmp_reg) {
return 1;
}
 
return 0;
#else
return 1; // A extension not implemented -Y always fail
#endif
}
/source/neorv32_rte.c
397,38 → 397,38
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
 
// peripherals
neorv32_uart_printf("\n-- Processor Peripherals --\n");
neorv32_uart_printf("\n-- Available Processor Peripherals --\n");
 
tmp = SYSINFO_FEATURES;
 
neorv32_uart_printf("GPIO: ");
neorv32_uart_printf("GPIO - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
 
neorv32_uart_printf("MTIME: ");
neorv32_uart_printf("MTIME - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
 
neorv32_uart_printf("UART: ");
neorv32_uart_printf("UART - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
 
neorv32_uart_printf("SPI: ");
neorv32_uart_printf("SPI - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
 
neorv32_uart_printf("TWI: ");
neorv32_uart_printf("TWI - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
 
neorv32_uart_printf("PWM: ");
neorv32_uart_printf("PWM - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
 
neorv32_uart_printf("WDT: ");
neorv32_uart_printf("WDT - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
 
neorv32_uart_printf("TRNG: ");
neorv32_uart_printf("TRNG - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
 
neorv32_uart_printf("CFU0: ");
neorv32_uart_printf("CFU0 - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU0));
 
neorv32_uart_printf("CFU1: ");
neorv32_uart_printf("CFU1 - ");
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU1));
}
 
506,9 → 506,8
**************************************************************************/
void neorv32_rte_print_credits(void) {
 
neorv32_uart_print("\nThe NEORV32 Processor Project, by Stephan Nolting\n"
"https://github.com/stnolting/neorv32\n"
"made in Hannover, Germany EU\n\n");
neorv32_uart_print("The NEORV32 Processor Project by Stephan Nolting\n"
"https://github.com/stnolting/neorv32\n\n");
}
 
 

powered by: WebSVN 2.1.0

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