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 45 to Rev 47
    Reverse comparison

Rev 45 → Rev 47

/bit_manipulation/main.c
1,5 → 1,5
// #################################################################################################
// # << NEORV32 - Bit manipulation 'B.Zbb' test program >> #
// # << NEORV32 - RISC-V Bit Manipulation 'B.Zbb' Extension Test Program >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
55,7 → 55,7
 
// Prototypes
uint32_t xorshift32(void);
uint32_t check_result(uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res);
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res);
void print_report(int num_err, int num_tests);
 
 
69,8 → 69,8
int main() {
 
uint32_t opa = 0, opb = 0, res_hw = 0, res_sw = 0;
int i = 0, err_cnt = 0;
const int num_tests = (int)NUM_TEST_CASES;
uint32_t i = 0, err_cnt = 0;
const uint32_t num_tests = (int)NUM_TEST_CASES;
 
// capture all exceptions and give debug info via UART
neorv32_rte_setup();
94,7 → 94,7
opa = xorshift32();
res_sw = riscv_emulate_clz(opa);
res_hw = riscv_intrinsic_clz(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
105,7 → 105,7
opa = xorshift32();
res_sw = riscv_emulate_ctz(opa);
res_hw = riscv_intrinsic_ctz(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
116,7 → 116,7
opa = xorshift32();
res_sw = riscv_emulate_cpop(opa);
res_hw = riscv_intrinsic_cpop(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
127,7 → 127,7
opa = xorshift32();
res_sw = riscv_emulate_sextb(opa);
res_hw = riscv_intrinsic_sextb(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
138,7 → 138,7
opa = xorshift32();
res_sw = riscv_emulate_sexth(opa);
res_hw = riscv_intrinsic_sexth(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
150,7 → 150,7
opb = xorshift32();
res_sw = riscv_emulate_min(opa, opb);
res_hw = riscv_intrinsic_min(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
162,7 → 162,7
opb = xorshift32();
res_sw = riscv_emulate_minu(opa, opb);
res_hw = riscv_intrinsic_minu(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
174,7 → 174,7
opb = xorshift32();
res_sw = riscv_emulate_max(opa, opb);
res_hw = riscv_intrinsic_max(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
186,7 → 186,7
opb = xorshift32();
res_sw = riscv_emulate_maxu(opa, opb);
res_hw = riscv_intrinsic_maxu(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
198,7 → 198,7
opb = xorshift32();
res_sw = riscv_emulate_pack(opa, opb);
res_hw = riscv_intrinsic_pack(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
210,7 → 210,7
opb = xorshift32();
res_sw = riscv_emulate_andn(opa, opb);
res_hw = riscv_intrinsic_andn(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
222,7 → 222,7
opb = xorshift32();
res_sw = riscv_emulate_orn(opa, opb);
res_hw = riscv_intrinsic_orn(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
234,7 → 234,7
opb = xorshift32();
res_sw = riscv_emulate_xnor(opa, opb);
res_hw = riscv_intrinsic_xnor(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
246,7 → 246,7
opb = xorshift32();
res_sw = riscv_emulate_rol(opa, opb);
res_hw = riscv_intrinsic_rol(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
258,7 → 258,7
opb = xorshift32();
res_sw = riscv_emulate_ror(opa, opb);
res_hw = riscv_intrinsic_ror(opa, opb);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
269,7 → 269,7
opa = xorshift32();
res_sw = riscv_emulate_ror(opa, 20);
res_hw = riscv_intrinsic_rori20(opa);
err_cnt += check_result(opa, opb, res_sw, res_hw);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
280,7 → 280,7
opa = xorshift32();
res_sw = riscv_emulate_orcb(opa);
res_hw = riscv_intrinsic_orcb(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
291,7 → 291,7
opa = xorshift32();
res_sw = riscv_emulate_rev8(opa);
res_hw = riscv_intrinsic_rev8(opa);
err_cnt += check_result(opa, 0, res_sw, res_hw);
err_cnt += check_result(i, opa, 0, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
322,6 → 322,7
/**********************************************************************//**
* Check results (reference (SW) vs actual hardware).
*
* @param[in] num Test case number
* @param[in] opa Operand 1
* @param[in] opb Operand 2
* @param[in] ref Software reference
328,10 → 329,10
* @param[in] res Actual results
* @return zero if results are equal.
**************************************************************************/
uint32_t check_result(uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
 
if (ref != res) {
neorv32_uart_printf("opa = 0x%x, opb = 0x%x : ref = 0x%x vs res = 0x%x ", opa, opb, ref, res);
neorv32_uart_printf("%u: opa = 0x%x, opb = 0x%x : ref = 0x%x vs res = 0x%x ", num, opa, opb, ref, res);
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
return 1;
}
/cpu_test/main.c
36,7 → 36,7
/**********************************************************************//**
* @file cpu_test/main.c
* @author Stephan Nolting
* @brief Simple CPU test program.
* @brief CPU/Processor test program.
**************************************************************************/
 
#include <neorv32.h>
51,8 → 51,8
#define BAUD_RATE 19200
//** Reachable unaligned address */
#define ADDR_UNALIGNED 0x00000002
//** Unreachable aligned address */
#define ADDR_UNREACHABLE 0xFFFFFF00
//** Unreachable word-aligned address */
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//* external memory base address */
#define EXT_MEM_BASE 0xF0000000
/**@}*/
59,8 → 59,7
 
 
// Prototypes
void sim_trigger_msi(void);
void sim_trigger_mei(void);
void sim_irq_trigger(uint32_t sel);
void global_trap_handler(void);
void test_ok(void);
void test_fail(void);
96,24 → 95,6
 
 
/**********************************************************************//**
* 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.
*
140,7 → 121,7
return 0;
#endif
 
neorv32_uart_printf("\n<< PROCESSOR/CPU TEST >>\n");
neorv32_uart_printf("\n<< CPU/PROCESSOR TEST >>\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
 
// check if we came from hardware reset
149,7 → 130,7
neorv32_uart_printf("yes\n");
}
else {
neorv32_uart_printf("unknown (mcause != TRAP_CODE_RESET)\n");
neorv32_uart_printf("unknown\n");
}
 
// check available hardware extensions and compare with compiler flags
208,20 → 189,28
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);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_3, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_4, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_5, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_6, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_7, global_trap_handler);
 
if (install_err) {
neorv32_uart_printf("RTE error (%i)!\n", install_err);
neorv32_uart_printf("RTE install error (%i)!\n", install_err);
return 0;
}
 
// enable interrupt sources
install_err = neorv32_cpu_irq_enable(CSR_MIE_MSIE); // activate software interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_MTIE); // activate timer interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_MEIE); // activate external interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ0E); // activate fast interrupt channel 0
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ1E); // activate fast interrupt channel 1
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ2E); // activate fast interrupt channel 2
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ3E); // activate fast interrupt channel 3
install_err = neorv32_cpu_irq_enable(CSR_MIE_MSIE); // machine software interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_MTIE); // machine timer interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_MEIE); // machine external interrupt
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ0E); // fast interrupt channel 0
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ1E); // fast interrupt channel 1
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ2E); // fast interrupt channel 2
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ3E); // fast interrupt channel 3
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ4E); // fast interrupt channel 4
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ5E); // fast interrupt channel 5
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ6E); // fast interrupt channel 6
install_err += neorv32_cpu_irq_enable(CSR_MIE_FIRQ7E); // fast interrupt channel 7
 
if (install_err) {
neorv32_uart_printf("IRQ enable error (%i)!\n", install_err);
472,7 → 461,7
 
 
// ----------------------------------------------------------
// Test FENCE.I instruction (clear & reload i-cache)
// Test FENCE.I instruction (instruction buffer / i-cache clear & reload)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Testing FENCE.I operation: ", cnt_test);
662,7 → 651,7
}
}
else {
neorv32_uart_printf("skipped (not possible when C extension is enabled)\n");
neorv32_uart_printf("skipped (n.a. with C-ext)\n");
}
 
 
738,7 → 727,7
}
}
else {
neorv32_uart_printf("skipped (not possible when C-EXT disabled)\n");
neorv32_uart_printf("skipped (n.a. with C-ext)\n");
}
 
 
874,7 → 863,7
 
}
else {
neorv32_uart_printf("skipped (not possible when U-EXT disabled)\n");
neorv32_uart_printf("skipped (n.a. without U-ext)\n");
}
 
 
919,7 → 908,7
cnt_test++;
 
// trigger IRQ
sim_trigger_msi();
sim_irq_trigger(1 << CSR_MIE_MSIE);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
947,7 → 936,7
cnt_test++;
 
// trigger IRQ
sim_trigger_mei();
sim_irq_trigger(1 << CSR_MIE_MEIE);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
969,14 → 958,14
// Fast interrupt channel 0 (WDT)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ0 (fast IRQ0) interrupt test (via WDT): ", cnt_test);
neorv32_uart_printf("[%i] FIRQ0 (fast interrupt 0) test (via WDT): ", cnt_test);
 
if (neorv32_wdt_available()) {
cnt_test++;
 
// configure WDT
neorv32_wdt_setup(CLK_PRSC_2, 0); // lowest clock prescaler, trigger IRQ on timeout
neorv32_wdt_reset(); // reset watchdog
neorv32_wdt_setup(CLK_PRSC_4096, 0, 1); // highest clock prescaler, trigger IRQ on timeout, lock access
WDT_CT = 0; // try to deactivate WDT (should fail as access is loced)
neorv32_wdt_force(); // force watchdog into action
 
// wait some time for the IRQ to arrive the CPU
1002,7 → 991,7
// Fast interrupt channel 1 (GPIO)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ1 (fast IRQ1) interrupt test (via GPIO): ", cnt_test);
neorv32_uart_printf("[%i] FIRQ1 (fast interrupt 1) test (via GPIO): ", cnt_test);
 
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
if (neorv32_gpio_available()) {
1048,7 → 1037,7
// Fast interrupt channel 2 (UART)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ2 (fast IRQ2) interrupt test (via UART): ", cnt_test);
neorv32_uart_printf("[%i] FIRQ2 (fast interrupt 2) test (via UART): ", cnt_test);
 
if (neorv32_uart_available()) {
cnt_test++;
1098,7 → 1087,7
// Fast interrupt channel 3 (SPI)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ3 (fast IRQ3) interrupt test (via SPI): ", cnt_test);
neorv32_uart_printf("[%i] FIRQ3 (fast interrupt 3) test (via SPI): ", cnt_test);
 
if (neorv32_spi_available()) {
cnt_test++;
1133,7 → 1122,7
// Fast interrupt channel 3 (TWI)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ3 (fast IRQ3) interrupt test (via TWI): ", cnt_test);
neorv32_uart_printf("[%i] FIRQ3 (fast interrupt 3) test (via TWI): ", cnt_test);
 
if (neorv32_twi_available()) {
cnt_test++;
1166,6 → 1155,42
 
 
// ----------------------------------------------------------
// Fast interrupt channel 4..7 (SoC fast IRQ)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ4..7 (SoC fast interrupt 0..3, via testbench) test: ", cnt_test);
 
cnt_test++;
 
// trigger all SoC Fast interrupts at once
neorv32_cpu_dint(); // do not fire yet!
sim_irq_trigger((1 << CSR_MIE_FIRQ4E) | (1 << CSR_MIE_FIRQ5E) | (1 << CSR_MIE_FIRQ6E) | (1 << CSR_MIE_FIRQ7E));
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
 
// make sure all SoC FIRQs have been triggered
tmp_a = (1 << CSR_MIP_FIRQ4P) | (1 << CSR_MIP_FIRQ5P) | (1 << CSR_MIP_FIRQ6P) | (1 << CSR_MIP_FIRQ7P);
if (neorv32_cpu_csr_read(CSR_MIP) == tmp_a) {
neorv32_cpu_eint(); // allow IRQs to fire again
asm volatile ("nop");
asm volatile ("nop"); // irq should kick in HERE
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_7) { // make sure FIRQ7 was last IRQ to be handled
test_ok();
}
else {
test_fail();
}
}
else {
test_fail();
}
 
neorv32_cpu_eint(); // re-enable IRQs globally
 
 
// ----------------------------------------------------------
// Test WFI ("sleep") instructions, wakeup via MTIME
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
1227,7 → 1252,7
 
}
else {
neorv32_uart_printf("skipped (not possible when U-EXT disabled)\n");
neorv32_uart_printf("skipped (n.a. without U-ext)\n");
}
 
 
1480,56 → 1505,25
 
 
// ----------------------------------------------------------
// Test AMO atomic operation - should raise illegal instruction exception
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Atomic AMOSWAP test (should raise illegal CMD exception): ", 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++;
 
// AMO operations are not implemented!
// this should cause an illegal instruction exception
asm volatile ("amoswap.w x0, x0, (x0)");
 
// atomic compare-and-swap
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
#else
neorv32_uart_printf("skipped (not implemented)\n");
#endif
 
 
// ----------------------------------------------------------
// HPM reports
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, -1); // stop all counters
neorv32_uart_printf("\n\n-- HPM reports (%u HPMs available) --\n", num_hpm_cnts_global);
neorv32_uart_printf("#IR - Total number of instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); // = HPM_0
neorv32_uart_printf("#CY - Total number of clock cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); // = HPM_2
neorv32_uart_printf("#03 - Retired compr. instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER3));
neorv32_uart_printf("#04 - I-fetch wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER4));
neorv32_uart_printf("#05 - I-issue wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER5));
neorv32_uart_printf("#06 - Multi-cycle ALU wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER6));
neorv32_uart_printf("#07 - Load operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER7));
neorv32_uart_printf("#08 - Store operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER8));
neorv32_uart_printf("#09 - Load/store wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER9));
neorv32_uart_printf("#10 - Unconditional jumps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER10));
neorv32_uart_printf("#11 - Conditional branches (all): %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER11));
neorv32_uart_printf("#12 - Conditional branches (taken): %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER12));
neorv32_uart_printf("#13 - Entered traps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER13));
neorv32_uart_printf("#14 - Illegal operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER14));
neorv32_uart_printf("#IR - Total number of instr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); // = HPM_0
//neorv32_uart_printf("#TM - Current system time: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_TIME)); // = HPM_1
neorv32_uart_printf("#CY - Total number of clk cyc.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); // = HPM_2
neorv32_uart_printf("#03 - Retired compr. instr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER3));
neorv32_uart_printf("#04 - I-fetch wait cyc.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER4));
neorv32_uart_printf("#05 - I-issue wait cyc.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER5));
neorv32_uart_printf("#06 - Multi-cyc. ALU wait cyc.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER6));
neorv32_uart_printf("#07 - Load operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER7));
neorv32_uart_printf("#08 - Store operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER8));
neorv32_uart_printf("#09 - Load/store wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER9));
neorv32_uart_printf("#10 - Unconditional jumps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER10));
neorv32_uart_printf("#11 - Cond. branches (all): %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER11));
neorv32_uart_printf("#12 - Cond. branches (taken): %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER12));
neorv32_uart_printf("#13 - Entered traps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER13));
neorv32_uart_printf("#14 - Illegal operations: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER14));
 
 
// ----------------------------------------------------------
1550,6 → 1544,17
 
 
/**********************************************************************//**
* Simulation-based function to trigger CPU interrupts (MSI, MEI, FIRQ4..7).
*
* @param[in] sel IRQ select mask (bit positions according to #NEORV32_CSR_MIE_enum).
**************************************************************************/
void sim_irq_trigger(uint32_t sel) {
 
*(IO_REG32 (0xFF000000)) = sel;
}
 
 
/**********************************************************************//**
* Trap handler for ALL exceptions/interrupts.
**************************************************************************/
void global_trap_handler(void) {
/demo_trng/main.c
36,7 → 36,7
/**********************************************************************//**
* @file demo_trng/main.c
* @author Stephan Nolting
* @brief TRNG demo program.
* @brief True random number generator demo program.
**************************************************************************/
 
#include <neorv32.h>
51,9 → 51,13
/**@}*/
 
 
// prototypes
void print_random_data(void);
void generate_histogram(void);
 
 
/**********************************************************************//**
* This program generates a simple dimming sequence for PWM channel 0,1,2.
* Simple true random number test/demo program.
*
* @note This program requires the UART and the TRNG to be synthesized.
*
61,14 → 65,6
**************************************************************************/
int main(void) {
 
uint8_t lucky_numbers_5of50[5];
uint8_t lucky_numbers_2of10[2];
 
int err;
uint8_t i, j, probe;
uint8_t trng_data;
unsigned int num_samples;
 
// check if UART unit is implemented at all
if (neorv32_uart_available() == 0) {
return 0;
102,7 → 98,7
// main menu
neorv32_uart_printf("\nCommands:\n"
" n: Print 8-bit random numbers (abort by pressing any key)\n"
" l: Print your lucky numbers\n");
" h: Generate and print histogram\n");
 
neorv32_uart_printf("CMD:> ");
char cmd = neorv32_uart_getc();
109,104 → 105,101
neorv32_uart_putc(cmd); // echo
neorv32_uart_printf("\n");
 
// output RND data
if (cmd == 'n') {
num_samples = 0;
while(1) {
err = neorv32_trng_get(&trng_data);
if (err) {
neorv32_uart_printf("\nTRNG error (%i)!\n", err);
break;
}
neorv32_uart_printf("%u ", (uint32_t)(trng_data));
num_samples++;
if (neorv32_uart_char_received()) { // abort when key pressed
neorv32_uart_printf("\nPrinted samples: %u", num_samples);
break;
}
}
print_random_data();
}
else if (cmd == 'h') {
generate_histogram();
}
else {
neorv32_uart_printf("Invalid command.\n");
}
}
 
// print lucky numbers
if (cmd == 'l') {
// reset arrays
for (i=0; i<5; i++) {
lucky_numbers_5of50[i] = 0;
}
lucky_numbers_2of10[0] = 0;
lucky_numbers_2of10[1] = 0;
return 0;
}
 
// get numbers
i = 0;
while (i<5) {
err = neorv32_trng_get(&trng_data);
if (err) {
neorv32_uart_printf("\nTRNG error (%i)!\n", err);
break;
}
// valid range?
if ((trng_data == 0) || (trng_data > 50)) {
continue;
}
// already sampled?
probe = 0;
for (j=0; j<5; j++) {
if (lucky_numbers_5of50[j] == trng_data) {
probe++;
}
}
if (probe) {
continue;
}
else {
lucky_numbers_5of50[i] = trng_data;
i++;
}
}
 
// get numbers part 2
i = 0;
while (i<2) {
err = neorv32_trng_get(&trng_data);
if (err) {
neorv32_uart_printf("\nTRNG error (%i)!\n", err);
break;
}
// valid range?
if ((trng_data == 0) || (trng_data > 10)) {
continue;
}
// already sampled?
probe = 0;
for (j=0; j<2; j++) {
if (lucky_numbers_2of10[j] == trng_data) {
probe++;
}
}
if (probe) {
continue;
}
else {
lucky_numbers_2of10[i] = trng_data;
i++;
}
}
/**********************************************************************//**
* Print random numbers until a key is pressed.
**************************************************************************/
void print_random_data(void) {
 
// output
neorv32_uart_printf("\n");
for (j=0; j<5; j++) {
if (i==4) {
neorv32_uart_printf("%u", (uint32_t)lucky_numbers_5of50[j]);
}
else {
neorv32_uart_printf("%u, ", (uint32_t)lucky_numbers_5of50[j]);
}
}
neorv32_uart_printf("\nLucky numbers: %u, %u\n", (uint32_t)lucky_numbers_2of10[0], (uint32_t)lucky_numbers_2of10[1]);
uint32_t num_samples = 0;
int err = 0;
uint8_t trng_data;
 
while(1) {
err = neorv32_trng_get(&trng_data);
if (err) {
neorv32_uart_printf("\nTRNG error!\n");
break;
}
neorv32_uart_printf("%u ", (uint32_t)(trng_data));
num_samples++;
if (neorv32_uart_char_received()) { // abort when key pressed
break;
}
}
neorv32_uart_printf("\nPrinted samples: %u\n", num_samples);
}
 
return 0;
 
/**********************************************************************//**
* Generate and print histogram. Samples random data until a key is pressed.
**************************************************************************/
void generate_histogram(void) {
 
uint32_t hist[256];
uint32_t i;
uint32_t cnt = 0;
int err = 0;
uint8_t trng_data;
 
neorv32_uart_printf("Press any key to start.\n");
 
while(neorv32_uart_char_received() == 0);
neorv32_uart_printf("Sampling... Press any key to stop.\n");
 
// clear histogram
for (i=0; i<256; i++) {
hist[i] = 0;
}
 
// sample random data
while(1) {
 
err = neorv32_trng_get(&trng_data);
hist[trng_data & 0xff]++;
cnt++;
 
if (err) {
neorv32_uart_printf("\nTRNG error!\n");
break;
}
 
if (neorv32_uart_char_received()) { // abort when key pressed
break;
}
 
if (cnt & 0x80000000UL) { // to prevent overflow
break;
}
}
 
// print histogram
neorv32_uart_printf("Histogram [random data value] : [# occurences]\n");
for (i=0; i<256; i++) {
neorv32_uart_printf("%u: %u\n", (uint32_t)i, hist[i]);
}
 
neorv32_uart_printf("\nSamples: %u\n", cnt);
 
// average
uint64_t average = 0;
for (i=0; i<256; i++) {
average += (uint64_t)hist[i] * i;
}
average = average / ((uint64_t)cnt);
neorv32_uart_printf("Average value: %u\n", (uint32_t)average);
}
 
/demo_wdt/main.c
75,7 → 75,6
// this is not required, but keeps us safe
neorv32_rte_setup();
 
 
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0);
 
90,25 → 89,23
neorv32_uart_print("Cause of last processor reset: ");
uint8_t wdt_cause = neorv32_wdt_get_cause();
 
if (wdt_cause == 1) {
if (wdt_cause == 0) {
neorv32_uart_print("External reset\n");
}
else if (wdt_cause == 2) {
neorv32_uart_print("Watchdog timeout\n");
else if (wdt_cause == 1) {
neorv32_uart_print("Watchdog\n");
}
else if (wdt_cause == 3) {
neorv32_uart_print("Watchdog access fault\n");
}
else {
neorv32_uart_print("Undefined\n");
}
 
 
// the watchod has a 20-bit counter, which trigger either an interrupt or a system reset
// the watchod has a 20-bit counter, which triggers either an interrupt or a system reset
// when overflowing
 
// init watchdog (watchdog timer increment = cpu_clock/64, trigger reset on overflow)
neorv32_wdt_setup(CLK_PRSC_64, 1);
// init watchdog (watchdog timer increment = cpu_clock/64, trigger reset on overflow, lock
// access so nobody can alter the configuration until next reset)
neorv32_wdt_setup(CLK_PRSC_64, 1, 1);
 
 
 

powered by: WebSVN 2.1.0

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