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
    from Rev 39 to Rev 40
    Reverse comparison

Rev 39 → Rev 40

/cpu_test/main.c
59,6 → 59,8
 
 
// Prototypes
void sim_trigger_msi(void);
void sim_trigger_mei(void);
void global_trap_handler(void);
void test_ok(void);
void test_fail(void);
90,6 → 92,24
 
 
/**********************************************************************//**
* Simulation-based function to trigger CPU MSI (machine software interrupt).
**************************************************************************/
void sim_trigger_msi(void) {
 
*(IO_REG32 (0xFF000000)) = 1;
}
 
 
/**********************************************************************//**
* Simulation-based function to trigger CPU MEI (machine external interrupt).
**************************************************************************/
void sim_trigger_mei(void) {
 
*(IO_REG32 (0xFF000004)) = 1;
}
 
 
/**********************************************************************//**
* This program uses mostly synthetic case to trigger all implemented exceptions.
* Each exception is captured and evaluated for correct detection.
*
99,6 → 119,19
**************************************************************************/
int main() {
 
register uint32_t tmp_a, tmp_b;
int i;
volatile uint32_t dummy_dst __attribute__((unused));
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} cpu_systime;
 
 
// init UART at default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
 
// Disable cpu_test compilation by default
#ifndef RUN_CPUTEST
#warning cpu_test HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CPUTEST clean_all exe<< to compile it.
109,23 → 142,24
return 0;
#endif
 
neorv32_uart_printf("\n--- PROCESSOR/CPU TEST ---\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
neorv32_uart_printf("This test suite is intended to verify the default NEORV32 processor setup using the default testbench.\n\n");
 
register uint32_t tmp_a, tmp_b, tmp_c;
uint32_t i, j;
volatile uint32_t dummy_dst __attribute__((unused));
// check if we came from hardware reset
neorv32_uart_printf("Coming from hardware reset? ");
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_RESET) {
neorv32_uart_printf("true\n");
}
else {
neorv32_uart_printf("unknown (mcause != TRAP_CODE_RESET)\n");
}
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} cpu_systime;
 
// reset performance counter
neorv32_cpu_set_minstret(0);
neorv32_cpu_set_mcycle(0);
 
// init UART at default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
 
neorv32_mtime_set_time(0);
// set CMP of machine system timer MTIME to max to prevent an IRQ
uint64_t mtime_cmp_max = 0xFFFFFFFFFFFFFFFFUL;
148,6 → 182,8
neorv32_rte_print_hw_config();
 
// configure RTE
neorv32_uart_printf("\n\nInitializing NEORV32 run-time environment (RTE)... ");
 
neorv32_rte_setup(); // this will install a full-detailed debug handler for all traps
 
int install_err = 0;
160,10 → 196,11
install_err += neorv32_rte_exception_install(RTE_TRAP_L_ACCESS, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_S_MISALIGNED, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_S_ACCESS, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_UENV_CALL, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MENV_CALL, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MTI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MSI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MTI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MEI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_0, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_1, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_2, global_trap_handler);
189,20 → 226,16
}
 
// test intro
neorv32_uart_printf("\n--- PROCESSOR/CPU TEST ---\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
neorv32_uart_printf("This test suite is intended to verify the default NEORV32 processor setup using the default testbench.\n\n");
neorv32_uart_printf("Starting tests...\n\n");
neorv32_uart_printf("\nStarting tests...\n\n");
 
// enable global interrupts
neorv32_cpu_eint();
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
 
// ----------------------------------------------------------
// List all accessible CSRs
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] List all accessible CSRs: ", cnt_test);
 
if ((UART_CT & (1 << UART_CT_SIM_MODE)) == 0) { // check if this is a simulation
257,24 → 290,26
 
 
// ----------------------------------------------------------
// CFU0 test (default HW)
// Test standard RISC-V performance counter [m]cycle[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU0 access test: ", cnt_test);
neorv32_uart_printf("[%i] Testing [m]instret[h] counters: ", cnt_test);
 
// cfu0 implemented?
if (neorv32_cfu0_available()) {
// check if counters are implemented
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_ZICNT)) {
cnt_test++;
 
// write test data
CFU0_REG_0 = 0x01234567;
CFU0_REG_1 = 0x76543210;
CFU0_REG_2 = 0xABCDABCD;
CFU0_REG_3 = 0xFFAAFFAA;
// get current cycle counter
volatile uint64_t cycle_csr_test = neorv32_cpu_get_cycle();
 
if ((CFU0_REG_0 == 0x01234567) && (CFU0_REG_1 == 0x76543210) &&
(CFU0_REG_2 == 0xABCDABCD) && (CFU0_REG_3 == 0xFFAAFFAA) && // correct read-back
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
 
// make sure cycle counter has incremented and there was no exception during access
if ((neorv32_cpu_get_cycle() > cycle_csr_test) &&
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
282,29 → 317,31
}
}
else {
neorv32_uart_printf("skipped (CFU0 not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// CFU1 test (default HW)
// Test standard RISC-V performance counter [m]instret[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU1 access test: ", cnt_test);
neorv32_uart_printf("[%i] Testing [m]cycle[h] counters: ", cnt_test);
 
// cfu0 implemented?
if (neorv32_cfu1_available()) {
// check if counters are implemented
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_ZICNT)) {
cnt_test++;
 
// write test data
CFU1_REG_0 = 0x22334455;
CFU1_REG_1 = 0x44782931;
CFU1_REG_2 = 0xDDAABBFF;
CFU1_REG_3 = 0xA0B0D0C0;
// get current instruction counter
volatile uint64_t instret_csr_test = neorv32_cpu_get_instret();
 
if ((CFU1_REG_0 == 0x22334455) && (CFU1_REG_1 == 0x44782931) &&
(CFU1_REG_2 == 0xDDAABBFF) && (CFU1_REG_3 == 0xA0B0D0C0) && // correct read-back
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
 
// make sure instruction counter has incremented and there was no exception during access
if ((neorv32_cpu_get_instret() > instret_csr_test) &&
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
312,12 → 349,12
}
}
else {
neorv32_uart_printf("skipped (CFU1 not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Bus timeout latency estimation
// Bus timeout latency estimation (very unprecise!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Estimating bus time-out latency: ", cnt_test);
324,12 → 361,12
cnt_test++;
 
// start timing
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
 
// this store access will timeout
MMR_UNREACHABLE = 0;
 
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE) - tmp_a;
tmp_a = neorv32_cpu_csr_read(CSR_MCYCLE);
 
// make sure there was a time-out
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
381,7 → 418,7
}
}
else {
neorv32_uart_printf("skipped (external memory interface not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
506,6 → 543,94
 
 
// ----------------------------------------------------------
// Test pending interrupt
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Pending IRQ test (from MTIME): ", cnt_test);
 
if (neorv32_mtime_available()) {
cnt_test++;
 
// disable global interrupts
neorv32_cpu_dint();
 
// force MTIME IRQ
neorv32_mtime_set_timecmp(0);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
// re-enable global interrupts
neorv32_cpu_eint();
 
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Test clearing pending interrupt (via mip CSR)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Clear pending IRQ (via mip CSR) test (from MTIME): ", cnt_test);
 
if (neorv32_mtime_available()) {
cnt_test++;
 
// disable global interrupts
neorv32_cpu_dint();
 
// force MTIME IRQ
neorv32_mtime_set_timecmp(0);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
 
if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CPU_MIP_MTIP)) { // make sure MTIP is pending
 
neorv32_cpu_csr_write(CSR_MIP, 0); // just clear all pending IRQs
neorv32_cpu_eint(); // re-enable global interrupts
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
neorv32_uart_printf("IRQ triggered! ");
test_fail();
}
}
else {
neorv32_uart_printf("MTIP not pending! ");
test_fail();
}
 
// re-enable global interrupts
neorv32_cpu_eint();
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Unaligned instruction address
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
699,10 → 824,10
 
 
// ----------------------------------------------------------
// Environment call
// Environment call from M-mode
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) exception test: ", cnt_test);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) from M-mode exception test: ", cnt_test);
cnt_test++;
 
asm volatile("ECALL");
716,6 → 841,37
 
 
// ----------------------------------------------------------
// Environment call from U-mode
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) from U-mode exception test: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_U_EXT)) {
 
cnt_test++;
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to misa not allowed for user-level programs
asm volatile("ECALL");
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_UENV_CALL) {
test_ok();
}
else {
test_fail();
}
 
}
else {
neorv32_uart_printf("skipped (not possible when U-EXT disabled)\n");
}
 
 
// ----------------------------------------------------------
// Machine timer interrupt (MTIME)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
746,11 → 902,75
neorv32_mtime_set_timecmp(-1);
}
else {
neorv32_uart_printf("skipped (WDT not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Machine software interrupt (MSI) via testbench
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] MSI (via testbench) interrupt test: ", cnt_test);
 
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
cnt_test++;
 
// trigger IRQ
sim_trigger_msi();
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MSI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
// ----------------------------------------------------------
// Machine external interrupt (MEI) via testbench
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] MEI (via testbench) interrupt test: ", cnt_test);
 
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
cnt_test++;
 
// trigger IRQ
sim_trigger_mei();
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MEI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
// ----------------------------------------------------------
// Fast interrupt channel 0 (WDT)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
783,7 → 1003,7
neorv32_wdt_disable();
}
else {
neorv32_uart_printf("skipped (WDT not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
829,7 → 1049,7
neorv32_gpio_port_set(0);
}
else {
neorv32_uart_printf("skipped (GPIO not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
887,7 → 1107,7
 
}
else {
neorv32_uart_printf("skipped (UART not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
926,7 → 1146,7
neorv32_spi_disable();
}
else {
neorv32_uart_printf("skipped (SPI not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
966,7 → 1186,7
neorv32_twi_disable();
}
else {
neorv32_uart_printf("skipped (TWI not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
996,7 → 1216,7
neorv32_mtime_set_timecmp(-1);
}
else {
neorv32_uart_printf("skipped (MTIME not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
1014,12 → 1234,18
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to mstatus not allowed for user mode programs
neorv32_cpu_csr_read(CSR_MSTATUS);
// access to misa not allowed for user-level programs
tmp_a = neorv32_cpu_csr_read(CSR_MISA);
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
if (tmp_a == 0) { // make sure user-level code CANNOT read machine-level CSR content!
test_ok();
}
else {
neorv32_uart_printf("SECURITY VIOLATION! ");
test_fail();
}
}
else {
test_fail();
1032,7 → 1258,7
 
 
// ----------------------------------------------------------
// Test RTE debug handler
// Test RTE debug trap handler
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] RTE (runtime environment) debug trap handler test: ", cnt_test);
1071,34 → 1297,16
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
cnt_test++;
 
// check min granulartiy
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
tmp_a = neorv32_cpu_csr_read(0x3b0);
// find out mininmal region size (granulartiy)
tmp_b = neorv32_cpu_pmp_get_granularity();
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((tmp_a >> i) & 1) == 0) {
break;
}
}
 
tmp_a = SYSINFO_DSPACE_BASE; // base address of protected region
neorv32_uart_printf("Creating protected page (NAPOT, [!X,!W,R], %u bytes) @ 0x%x: ", tmp_b, tmp_a);
 
tmp_b = 0;
for (j=i; j!=0; j--) {
tmp_b = tmp_b << 1;
tmp_b = tmp_b | 1;
}
tmp_c = tmp_a & (~tmp_b); // clear LSBs in base address
tmp_c = tmp_c | tmp_b; // set region size config
// configure
int pmp_return = neorv32_cpu_pmp_configure_region(0, tmp_a, tmp_b, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
 
neorv32_uart_printf("Creating protected page (NAPOT, [!X,!W,R], %u bytes) @ 0x%x (PMPADDR = 0x%x): ", (uint32_t)(1 << (i+1+2)), tmp_a, tmp_c);
 
neorv32_cpu_csr_write(CSR_PMPADDR0, tmp_c); // 64k area @ 0xFFFFA000
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
 
if ((neorv32_cpu_csr_read(CSR_PMPADDR0) == tmp_c) && (neorv32_cpu_csr_read(CSR_PMPCFG0) == 0b00011001) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
if ((pmp_return == 0) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
1220,7 → 1428,7
 
}
else {
neorv32_uart_printf("not implemented\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
1249,7 → 1457,7
}
}
else {
neorv32_uart_printf("skipped (A extension not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
1281,7 → 1489,7
}
}
else {
neorv32_uart_printf("skipped (A extension not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
1289,7 → 1497,6
}
 
 
 
// ----------------------------------------------------------
// Final test reports
// ----------------------------------------------------------
/hex_viewer/main.c
55,6 → 55,7
// Prototypes
void read_memory(void);
void write_memory(void);
void atomic_cas(void);
void dump_memory(void);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
 
103,10 → 104,11
// decode input and execute command
if (!strcmp(buffer, "help")) {
neorv32_uart_printf("Available commands:\n"
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" dump - dumpe several words from base address\n\n");
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" atomic - perform atomic compare-and-swap operation\n"
" dump - dumpe several words from base address\n");
}
 
else if (!strcmp(buffer, "read")) {
113,6 → 115,10
read_memory();
}
 
else if (!strcmp(buffer, "atomic")) {
atomic_cas();
}
 
else if (!strcmp(buffer, "write")) {
write_memory();
}
138,10 → 144,9
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_printf("Enter address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// perform read access
neorv32_uart_printf("\n[0x%x] = ", mem_address);
169,13 → 174,12
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_printf("Enter address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// enter data
neorv32_uart_printf("\nEnter data (8 hex chars): ");
neorv32_uart_printf("\nEnter data (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
197,6 → 201,45
 
 
/**********************************************************************//**
* Perform atomic compare-and-swap operation
**************************************************************************/
void atomic_cas(void) {
 
char terminal_buffer[16];
uint32_t mem_address, cas_expected, cas_desired;
 
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_A_EXT)) != 0) {
 
// enter memory address
neorv32_uart_printf("Enter memory address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter expected value
neorv32_uart_printf("\nEnter expected value @0x%x (8 hex chars): 0x", mem_address);
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
cas_expected = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter desired value
neorv32_uart_printf("\nEnter desired (new) value @0x%x (8 hex chars): 0x", mem_address);
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
cas_desired = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// try to execute atomic compare-and-swap
if (neorv32_cpu_atomic_cas(mem_address, cas_expected, cas_desired)) {
neorv32_uart_printf("\nAtomic-CAS: Failed!\n");
}
else {
neorv32_uart_printf("\nAtomic-CAS: Successful!\n");
}
}
else {
neorv32_uart_printf("Atomic operations not implemented/enabled!\n");
}
}
 
 
/**********************************************************************//**
* Read several words from memory base address
**************************************************************************/
void dump_memory(void) {
204,10 → 247,9
char terminal_buffer[16];
 
// enter base address
neorv32_uart_printf("Enter base address (8 hex chars): ");
neorv32_uart_printf("Enter base address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
neorv32_uart_printf("\nPress key to start dumping. Press any key to abort.\n");
 

powered by: WebSVN 2.1.0

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