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 56 to Rev 57
    Reverse comparison

Rev 56 → Rev 57

/cpu_test/main.c
55,10 → 55,6
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//** external memory base address */
#define EXT_MEM_BASE (0xF0000000)
//** exclusive access to this address will always succeed */
#define ATOMIC_SUCCESS_ADDR (EXT_MEM_BASE + 0)
//** exclusive access to this address will always fail */
#define ATOMIC_FAILURE_ADDR (EXT_MEM_BASE + 4)
/**@}*/
 
 
78,7 → 74,10
/// Global numbe rof available HPMs
uint32_t num_hpm_cnts_global = 0;
 
/// Variable to test atomic accessess
uint32_t atomic_access_addr;
 
 
/**********************************************************************//**
* High-level CPU/processor test program.
*
837,12 → 836,20
if (neorv32_mtime_available()) {
cnt_test++;
 
// force MTIME IRQ
neorv32_mtime_set_timecmp(0);
// configure MTIME IRQ (and check overflow form low owrd to high word)
neorv32_mtime_set_timecmp(-1);
neorv32_mtime_set_time(0);
 
// wait some time for the IRQ to arrive the CPU
neorv32_cpu_csr_write(CSR_MIP, 0); // clear all pending IRQs
 
neorv32_mtime_set_timecmp(0x0000000100000000ULL);
neorv32_mtime_set_time( 0x00000000FFFFFFFEULL);
 
// wait some time for the IRQ to trigger and arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
1458,7 → 1465,7
 
 
// ------ EXECUTE: should fail ------
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] execute: ", cnt_test);
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] execute: ", cnt_test);
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
1483,7 → 1490,7
 
 
// ------ LOAD: should work ------
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] read: ", cnt_test);
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] read: ", cnt_test);
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
1508,7 → 1515,7
 
 
// ------ STORE: should fail ------
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] write: ", cnt_test);
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] write: ", cnt_test);
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
1563,34 → 1570,33
// Test atomic LR/SC operation - should succeed
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Atomic access (LR+SC) test (succeeding access): ", cnt_test);
neorv32_uart_printf("[%i] Atomic access (LR+SC succeeding access): ", cnt_test);
 
#ifdef __riscv_atomic
if (is_simulation) { // check if this is a simulation
// skip if A-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
 
// skip if A-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
cnt_test++;
 
cnt_test++;
neorv32_cpu_store_unsigned_word((uint32_t)&atomic_access_addr, 0x11223344);
 
neorv32_cpu_store_unsigned_word(ATOMIC_SUCCESS_ADDR, 0x11223344);
tmp_a = neorv32_cpu_load_reservate_word((uint32_t)&atomic_access_addr); // make reservation
asm volatile ("nop");
tmp_b = neorv32_cpu_store_conditional((uint32_t)&atomic_access_addr, 0x22446688);
 
// atomic compare-and-swap
if ((neorv32_cpu_atomic_cas((uint32_t)ATOMIC_SUCCESS_ADDR, 0x11223344, 0xAABBCCDD) == 0) && // status: success
(neorv32_cpu_load_unsigned_word(ATOMIC_SUCCESS_ADDR) == 0xAABBCCDD) && // data written correctly
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception triggered
test_ok();
}
else {
test_fail();
}
// atomic access
if ((tmp_b == 0) && // status: success
(tmp_a == 0x11223344) && // correct data read
(neorv32_cpu_load_unsigned_word((uint32_t)&atomic_access_addr) == 0x22446688) && // correct data write
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception triggered
test_ok();
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real HW)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
#else
neorv32_uart_printf("skipped (not implemented)\n");
1601,32 → 1607,67
// Test atomic LR/SC operation - should fail
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Atomic access (LR+SC) test (failing access): ", cnt_test);
neorv32_uart_printf("[%i] Atomic access (LR+SC failing access 1): ", cnt_test);
 
#ifdef __riscv_atomic
if (is_simulation) { // check if this is a simulation
// skip if A-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
 
// skip if A-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
cnt_test++;
 
cnt_test++;
neorv32_cpu_store_unsigned_word((uint32_t)&atomic_access_addr, 0xAABBCCDD);
 
neorv32_cpu_store_unsigned_word(ATOMIC_FAILURE_ADDR, 0x55667788);
// atomic access
tmp_a = neorv32_cpu_load_reservate_word((uint32_t)&atomic_access_addr); // make reservation
neorv32_cpu_store_unsigned_word((uint32_t)&atomic_access_addr, 0xDEADDEAD); // destroy reservation
tmp_b = neorv32_cpu_store_conditional((uint32_t)&atomic_access_addr, 0x22446688);
 
// atomic compare-and-swap
if ((neorv32_cpu_atomic_cas((uint32_t)ATOMIC_FAILURE_ADDR, 0x55667788, 0xEEFFDDBB) != 0) && // staus: failed
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception triggered
test_ok();
}
else {
test_fail();
}
if ((tmp_b != 0) && // status: fail
(tmp_a == 0xAABBCCDD) && // correct data read
(neorv32_cpu_load_unsigned_word((uint32_t)&atomic_access_addr) == 0xDEADDEAD)) { // correct data write
test_ok();
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
test_fail();
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
#else
neorv32_uart_printf("skipped (not implemented)\n");
#endif
 
 
// ----------------------------------------------------------
// Test atomic LR/SC operation - should fail
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Atomic access (LR+SC failing access 2): ", cnt_test);
 
#ifdef __riscv_atomic
// skip if A-mode is not implemented
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
 
cnt_test++;
 
neorv32_cpu_store_unsigned_word((uint32_t)&atomic_access_addr, 0x12341234);
 
// atomic access
tmp_a = neorv32_cpu_load_reservate_word((uint32_t)&atomic_access_addr); // make reservation
asm volatile ("ecall"); // destroy reservation via trap (simulate a context switch)
tmp_b = neorv32_cpu_store_conditional((uint32_t)&atomic_access_addr, 0xDEADBEEF);
 
if ((tmp_b != 0) && // status: fail
(tmp_a == 0x12341234) && // correct data read
(neorv32_cpu_load_unsigned_word((uint32_t)&atomic_access_addr) == 0x12341234)) { // correct data write
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real HW)\n");
}
#else
/hex_viewer/main.c
112,7 → 112,7
" 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"
" atomic - perform atomic LR/SC access\n"
" dump - dumpe several words from base address\n");
}
 
208,7 → 208,7
void atomic_cas(void) {
 
char terminal_buffer[16];
uint32_t mem_address, cas_expected, cas_desired;
uint32_t mem_address, rdata, wdata, status;
 
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_A_EXT)) != 0) {
 
217,22 → 217,22
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_printf("\nEnter 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));
wdata = (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) == 0) {
neorv32_uart_printf("\nAtomic-CAS: Successful!\n");
rdata = neorv32_cpu_load_reservate_word(mem_address); // make reservation
status = neorv32_cpu_store_conditional(mem_address, wdata);
 
// status
neorv32_uart_printf("\nOld data: 0x%x\n", rdata);
if (status == 0) {
neorv32_uart_printf("Atomic access successful!\n");
neorv32_uart_printf("New data: 0x%x\n", neorv32_cpu_load_unsigned_word(mem_address));
}
else {
neorv32_uart_printf("\nAtomic-CAS: Failed!\n");
neorv32_uart_printf("Atomic access failed!\n");
}
}
else {

powered by: WebSVN 2.1.0

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