Skip to content

Commit

Permalink
minor software framework cleanups and optimizations (#940)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Jul 5, 2024
2 parents 7a2cdcc + 8808998 commit cb058a8
Show file tree
Hide file tree
Showing 18 changed files with 276 additions and 369 deletions.
2 changes: 1 addition & 1 deletion docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ To benchmark a certain processor configuration for its setup-specific CPI value
The `A` ISA extension adds instructions and mechanisms for atomic memory access operations. Note that the NEORV32 `A`
only includes the _load-reservate_ (`lr.w`) and _store-conditional_ (`sc.w`) instructions - the remaining read-modify-write
instructions (like `amoswap`) are **not supported**. However, these missing instructions can be emulated using the
LR and SC operations.
LR and SC operations (quote from the RISC-V spec.: "_Any AMO can be emulated by an LR/SC pair._").

.AMO Emulation
[NOTE]
Expand Down
10 changes: 5 additions & 5 deletions docs/datasheet/soc_gpio.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files: | neorv32_gpio.vhd |
| Hardware source files: | neorv32_gpio.vhd |
| Software driver files: | neorv32_gpio.c |
| | neorv32_gpio.h |
| Top entity ports: | `gpio_o` | 64-bit parallel output port
Expand Down Expand Up @@ -37,8 +37,8 @@ be performed within a single clock cycle.
[options="header",grid="rows"]
|=======================
| Address | Name [C] | Bit(s) | R/W | Function
| `0xfffffc00` | `INPUT_LO` | 31:0 | r/- | parallel input port pins 31:0
| `0xfffffc04` | `INPUT_HI` | 31:0 | r/- | parallel input port pins 63:32
| `0xfffffc08` | `OUTPUT_LO` | 31:0 | r/w | parallel output port pins 31:0
| `0xfffffc0c` | `OUTPUT_HI` | 31:0 | r/w | parallel output port pins 63:32
| `0xfffffc00` | `INPUT[0]` | 31:0 | r/- | parallel input port pins 31:0
| `0xfffffc04` | `INPUT[1]` | 31:0 | r/- | parallel input port pins 63:32
| `0xfffffc08` | `OUTPUT[0]` | 31:0 | r/w | parallel output port pins 31:0
| `0xfffffc0c` | `OUTPUT[1]` | 31:0 | r/w | parallel output port pins 63:32
|=======================
1 change: 0 additions & 1 deletion sw/bootloader/bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

/**
* @file bootloader.c
* @author Stephan Nolting
* @brief Default NEORV32 bootloader.
*/

Expand Down
11 changes: 7 additions & 4 deletions sw/common/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,23 @@ __crt0_call_constructors_loop_end:
__crt0_main_entry:
addi x10, zero, 0 // x10 = a0 = argc = 0
addi x11, zero, 0 // x11 = a1 = argv = 0
jal x1, main // call actual app's main function
jal x1, main // call actual main function

__crt0_main_exit: // main's "return" and "exit" will arrive here
csrw mie, zero // disable all interrupt sources
csrw mscratch, a0 // backup main's return code to mscratch (for debugger)
csrw mscratch, a0 // backup main's return code to mscratch (for debugger or destructors)



// ************************************************************************************************
// Call destructors
// ************************************************************************************************
#ifndef MAKE_BOOTLOADER // destructors are not supported for bootloader
__crt0_call_destructors:
la x8, __fini_array_start
la x9, __fini_array_end
la x8, __crt0_trap_handler // use the crt0 trap handler if there are exceptions in the destructors
csrw mtvec, x8
la x8, __fini_array_start
la x9, __fini_array_end

__crt0_call_destructors_loop:
bge x8, x9, __crt0_call_destructors_loop_end
Expand Down
4 changes: 2 additions & 2 deletions sw/example/atomic_test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ int main() {

#else

#warning Program HAS NOT BEEN COMPILED as RISC-V A ISA extensions is not enabled!
neorv32_uart0_printf("\nProgram HAS NOT BEEN COMPILED as RISC-V A ISA extensions is not enabled!\n");
#warning Program HAS NOT BEEN COMPILED since RISC-V 'A' ISA extension is not enabled!
neorv32_uart0_printf("\nProgram HAS NOT BEEN COMPILED since RISC-V 'A' ISA extension is not enabled!\n");

#endif

Expand Down
17 changes: 14 additions & 3 deletions sw/example/demo_newlib/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
/**@}*/


/**********************************************************************//**
* @name Print main's return code using a destructor
**************************************************************************/
void __attribute__((destructor)) main_destructor_test(void) {

int32_t main_ret = (int32_t)neorv32_cpu_csr_read(CSR_MSCRATCH);
neorv32_uart0_printf("\nDestructor: main terminated with return/exit code %i.\n", main_ret);
}


/**********************************************************************//**
* @name Max heap size (from linker script's "__neorv32_heap_size")
**************************************************************************/
Expand Down Expand Up @@ -111,10 +121,11 @@ int main() {
// NOTE: exit is highly over-sized as it also includes clean-up functions (destructors), which
// are not required for bare-metal or RTOS applications... better use the simple 'return' or even better
// make sure main never returns. Anyway, let's check if 'exit' works.
neorv32_uart0_printf("terminating via <exit> ");
exit(0);
int exit_code = 7;
neorv32_uart0_printf("<exit> terminating by exit(%i)...\n", exit_code);
exit(exit_code);

// should never be reached
neorv32_uart0_printf("failed!n");
neorv32_uart0_printf("exit failed!\n");
return 0;
}
16 changes: 8 additions & 8 deletions sw/example/processor_check/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1898,12 +1898,12 @@ int main() {
amo_var = 0x00cafe00; // initialize
asm volatile ("fence"); // flush/reload d-cache

tmp_a = neorv32_cpu_load_reservate_word((uint32_t)&amo_var);
tmp_a = neorv32_cpu_amolr((uint32_t)&amo_var);
amo_var = 0x10cafe00; // break reservation
asm volatile ("fence"); // flush/reload d-cache
tmp_b = neorv32_cpu_store_conditional_word((uint32_t)&amo_var, 0xaaaaaaaa);
tmp_b = (tmp_b << 1) | neorv32_cpu_store_conditional_word((uint32_t)&amo_var, 0xcccccccc); // another SC: must fail
tmp_b = (tmp_b << 1) | neorv32_cpu_store_conditional_word((uint32_t)ADDR_UNREACHABLE, 0); // another SC: must fail; no bus exception!
tmp_b = neorv32_cpu_amosc((uint32_t)&amo_var, 0xaaaaaaaa);
tmp_b = (tmp_b << 1) | neorv32_cpu_amosc((uint32_t)&amo_var, 0xcccccccc); // another SC: must fail
tmp_b = (tmp_b << 1) | neorv32_cpu_amosc((uint32_t)ADDR_UNREACHABLE, 0); // another SC: must fail; no bus exception!
asm volatile ("fence"); // flush/reload d-cache

if ((tmp_a == 0x00cafe00) && // correct LR.W result
Expand Down Expand Up @@ -1939,12 +1939,12 @@ int main() {
amo_var = 0x00abba00; // initialize
asm volatile ("fence"); // flush/reload d-cache

tmp_a = neorv32_cpu_load_reservate_word((uint32_t)&amo_var);
tmp_a = neorv32_cpu_amolr((uint32_t)&amo_var);
asm volatile ("fence"); // flush/reload d-cache
neorv32_cpu_load_unsigned_word((uint32_t)&amo_var); // dummy read, must not alter reservation set state
tmp_b = neorv32_cpu_store_conditional_word((uint32_t)&amo_var, 0xcccccccc);
tmp_b = (tmp_b << 1) | neorv32_cpu_store_conditional_word((uint32_t)&amo_var, 0xcccccccc); // another SC: must fail
tmp_b = (tmp_b << 1) | neorv32_cpu_store_conditional_word((uint32_t)ADDR_UNREACHABLE, 0); // another SC: must fail; no bus exception!
tmp_b = neorv32_cpu_amosc((uint32_t)&amo_var, 0xcccccccc);
tmp_b = (tmp_b << 1) | neorv32_cpu_amosc((uint32_t)&amo_var, 0xcccccccc); // another SC: must fail
tmp_b = (tmp_b << 1) | neorv32_cpu_amosc((uint32_t)ADDR_UNREACHABLE, 0); // another SC: must fail; no bus exception!
asm volatile ("fence"); // flush/reload d-cache

if ((tmp_a == 0x00abba00) && // correct LR.W result
Expand Down
47 changes: 35 additions & 12 deletions sw/lib/include/neorv32_aux.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,50 @@


/**********************************************************************//**
* Processor clock prescaler select
* Processor clock prescaler select (relative to processor's main clock)
**************************************************************************/
/**@{*/
enum NEORV32_CLOCK_PRSC_enum {
CLK_PRSC_2 = 0, /**< CPU_CLK (from clk_i top signal) / 2 */
CLK_PRSC_4 = 1, /**< CPU_CLK (from clk_i top signal) / 4 */
CLK_PRSC_8 = 2, /**< CPU_CLK (from clk_i top signal) / 8 */
CLK_PRSC_64 = 3, /**< CPU_CLK (from clk_i top signal) / 64 */
CLK_PRSC_128 = 4, /**< CPU_CLK (from clk_i top signal) / 128 */
CLK_PRSC_1024 = 5, /**< CPU_CLK (from clk_i top signal) / 1024 */
CLK_PRSC_2048 = 6, /**< CPU_CLK (from clk_i top signal) / 2048 */
CLK_PRSC_4096 = 7 /**< CPU_CLK (from clk_i top signal) / 4096 */
CLK_PRSC_2 = 0, /**< CPU_CLK / 2 */
CLK_PRSC_4 = 1, /**< CPU_CLK / 4 */
CLK_PRSC_8 = 2, /**< CPU_CLK / 8 */
CLK_PRSC_64 = 3, /**< CPU_CLK / 64 */
CLK_PRSC_128 = 4, /**< CPU_CLK / 128 */
CLK_PRSC_1024 = 5, /**< CPU_CLK / 1024 */
CLK_PRSC_2048 = 6, /**< CPU_CLK / 2048 */
CLK_PRSC_4096 = 7 /**< CPU_CLK / 4096 */
};
/**@}*/


/**********************************************************************//**
* @name Date and time struct
* @name Subword-access helper
**************************************************************************/
/**@{*/
/** @name 64-bit */
typedef union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/sizeof(uint32_t)];
uint16_t uint16[sizeof(uint64_t)/sizeof(uint16_t)];
uint8_t uint8[ sizeof(uint64_t)/sizeof(uint8_t)];
} subwords64_t;
/** @name 32-bit */
typedef union {
uint32_t uint32[sizeof(uint32_t)/sizeof(uint32_t)];
uint16_t uint16[sizeof(uint32_t)/sizeof(uint16_t)];
uint8_t uint8[ sizeof(uint32_t)/sizeof(uint8_t)];
} subwords32_t;
/** @name 16-bit */
typedef union {
uint16_t uint16[sizeof(uint16_t)/sizeof(uint16_t)];
uint8_t uint8[ sizeof(uint16_t)/sizeof(uint8_t)];
} subwords16_t;
/**@}*/


/**********************************************************************//**
* @name Date and time struct
**************************************************************************/
typedef struct {
uint16_t year; /**< current year (absolute) */
uint8_t month; /**< 1..12 */
Expand All @@ -57,11 +81,10 @@ typedef struct {
uint8_t minutes; /**< 0..59 */
uint8_t seconds; /**< 0..59 */
} date_t;
/**@}*/


/**********************************************************************//**
* @name Prototypes
* @name AUX prototypes
**************************************************************************/
/**@{*/
uint64_t neorv32_aux_date2unixtime(date_t* date);
Expand Down
Loading

0 comments on commit cb058a8

Please sign in to comment.