From 80552ed75c26ab92af3a7f626382e361dddc0c76 Mon Sep 17 00:00:00 2001 From: NikLeberg Date: Tue, 8 Oct 2024 11:16:17 +0000 Subject: [PATCH] rtl/neorv32_wbp_gateway: fix fsm lockup #2 --- .devcontainer/.env | 12 +++ .gitignore | 1 + scripts/makefile.def | 2 + sw/makefile.sw | 11 +- sw/src/main.c | 101 ++++++++++++------- vhdl/neorv32_wbp_io/neorv32_wbp_gateway.vhdl | 5 +- 6 files changed, 91 insertions(+), 41 deletions(-) diff --git a/.devcontainer/.env b/.devcontainer/.env index d76248d..fee3b3e 100644 --- a/.devcontainer/.env +++ b/.devcontainer/.env @@ -146,3 +146,15 @@ function nvc_bash () { docker run $nvc_args ghcr.io/nikleberg/nvc $* } export -f nvc_bash + +# AI code assistant tool. +function aider () { + aider_args="--hostname aider -e GEMINI_API_KEY=AIzaSyAnGLUx_O9uVU4J2d-D72ARGKmk1h6lbrQ $(get_common_args)" + docker run $aider_args paulgauthier/aider-full --model gemini/gemini-1.5-pro-latest $* +} +export -f aider +function aider_bash () { + aider_args="--hostname aider -e GEMINI_API_KEY=AIzaSyAnGLUx_O9uVU4J2d-D72ARGKmk1h6lbrQ --entrypoint bash $(get_common_args)" + docker run $aider_args paulgauthier/aider-full $* +} +export -f aider_bash diff --git a/.gitignore b/.gitignore index 3599872..abbbe9d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ sw/*.mif # ignore build artifacts of hardware build/* !build/makefile +.aider* diff --git a/scripts/makefile.def b/scripts/makefile.def index 88bb648..6f615ad 100644 --- a/scripts/makefile.def +++ b/scripts/makefile.def @@ -6,6 +6,8 @@ LIB_PATHS ?= ../vhdl ../lib/neorv32/rtl/core IGNORED_FILES += ../lib/neorv32/rtl/core/mem/neorv32_imem.legacy.vhd IGNORED_FILES += ../lib/neorv32/rtl/core/mem/neorv32_dmem.legacy.vhd IGNORED_FILES += ../vhdl/vga/tb/vga_tb.vhdl +IGNORED_FILES += ../vhdl/tilelink/tilelink_ul_xbar.vhdl +IGNORED_FILES += ../vhdl/tilelink/tilelink_ul_xbar_compl.vhdl export LIBS export LIB_PATHS diff --git a/sw/makefile.sw b/sw/makefile.sw index 0b8f293..3e14bfc 100644 --- a/sw/makefile.sw +++ b/sw/makefile.sw @@ -7,6 +7,9 @@ RISCV_PREFIX = riscv32-unknown-elf- # CPU architecture MARCH = rv32ia_zicsr +# Count of CPU HARTS +NUM_HARTS = 4 + # FreeRTOS kernel home folder FREERTOS_HOME = ../lib/FreeRTOS-Kernel @@ -15,10 +18,16 @@ USER_FLAGS := $(CLI_FLAGS) USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16K USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=32M USER_FLAGS += -Wl,--defsym,__neorv32_stack_size=8K -USER_FLAGS += -Wl,--defsym,__neorv32_num_harts=4 +USER_FLAGS += -Wl,--defsym,__neorv32_num_harts=$(NUM_HARTS) USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=4M USER_FLAGS += -Og +# Build in SMP mode if NUM_HARTS > 1. +ifneq (1,$(NUM_HARTS)) +USER_FLAGS += -DSMP +endif +USER_FLAGS += -DNUM_HARTS=$(NUM_HARTS) + # Change flags if we are building for the simulation. ifneq (,$(findstring SIMULATION,$(USER_FLAGS))) USER_FLAGS += -DUART0_SIM_MODE diff --git a/sw/src/main.c b/sw/src/main.c index a8bd978..a5f754a 100644 --- a/sw/src/main.c +++ b/sw/src/main.c @@ -9,16 +9,16 @@ * */ -#include -#include +// #include +// #include -#include #include "smp.h" +#include void vAssertCalled(void); void vApplicationIdleHook(void); -extern void freertos_risc_v_trap_handler(void); // FreeRTOS core +// extern void freertos_risc_v_trap_handler(void); // FreeRTOS core static void setup_port(void); static void blinky(void *args); static void delay_ms(uint32_t time_ms); @@ -35,23 +35,45 @@ static smp_mutex_t mutex = SMP_MUTEX_INIT; * @return will never return */ int main() { - // setup hardware and port software - setup_port(); - // create a simple task - xTaskCreate(blinky, "blinky", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); - // start the scheduler - vTaskStartScheduler(); - // will not get here unless something went horribly wrong - for (;;) { - neorv32_gpio_pin_toggle(1); - neorv32_gpio_pin_toggle(2); - delay_ms(100); + // install the freeRTOS kernel trap handler + // neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler); + // wake other harts with msi interrupt aka ipi + for (int i = 1; i < NUM_HARTS; ++i) { + smp_set_ipi_for_hart(i); } + + blinky(NULL); + + // // create a simple task + // xTaskCreate(blinky, "blinky", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); + // // start the scheduler + // vTaskStartScheduler(); + // // will not get here unless something went horribly wrong + // configASSERT(false) +} + +/** + * @brief Main function of secondary HARTS + * + * @return will never return + */ +int secondary_main() { + + blinky(NULL); + + // // install the freeRTOS kernel trap handler + // neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler); + // // create a simple task + // xTaskCreate(blinky, "blinky_secondary", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); + // // start the scheduler + // vTaskStartScheduler(); + // // will not get here unless something went horribly wrong + // configASSERT(false) } static void setup_port(void) { // install the freeRTOS kernel trap handler - neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler); + // neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler); // // the first HART is responsible to wake up all other cores // uint32_t hart_id = neorv32_cpu_csr_read(CSR_MHARTID); // if (hart_id == 0) { @@ -63,23 +85,23 @@ static void setup_port(void) { // } } -void vAssertCalled(void) { - /* Flash the lowest 2 LEDs to indicate that assert was hit - interrupts are - off here to prevent any further tick interrupts or context switches, so the - delay is implemented as a busy-wait loop instead of a peripheral timer. */ - taskDISABLE_INTERRUPTS(); - neorv32_gpio_port_set(0); - while (1) { - for (int i = 0; i < (configCPU_CLOCK_HZ / 100); i++) { - asm volatile("nop"); - } - neorv32_gpio_pin_toggle(0); - neorv32_gpio_pin_toggle(1); - } -} +// void vAssertCalled(void) { +// /* Flash the lowest 2 LEDs to indicate that assert was hit - interrupts are +// off here to prevent any further tick interrupts or context switches, so the +// delay is implemented as a busy-wait loop instead of a peripheral timer. */ +// taskDISABLE_INTERRUPTS(); +// neorv32_gpio_port_set(0); +// while (1) { +// for (int i = 0; i < (configCPU_CLOCK_HZ / 100); i++) { +// asm volatile("nop"); +// } +// neorv32_gpio_pin_toggle(0); +// neorv32_gpio_pin_toggle(1); +// } +// } void vApplicationIdleHook(void) { - // put CPU into sleep mote, it wakes up on any interrupt request + // put CPU into sleep mode, it wakes up on any interrupt request neorv32_cpu_sleep(); } @@ -87,13 +109,16 @@ static void blinky(void *args) { (void)args; uint32_t hart_id = neorv32_cpu_csr_read(CSR_MHARTID); for (;;) { - neorv32_gpio_pin_toggle(0); -#ifndef SIMULATION - vTaskDelay(pdMS_TO_TICKS(200)); -#else -#warning "Running blinky task with no delay!" - vTaskDelay(0); -#endif + smp_mutex_take(&mutex); + neorv32_gpio_pin_toggle(hart_id); + smp_mutex_give(&mutex); + delay_ms(100); + // #ifndef SIMULATION + // vTaskDelay(pdMS_TO_TICKS(200)); + // #else + // #warning "Running blinky task with no delay!" + // vTaskDelay(0); + // #endif } } diff --git a/vhdl/neorv32_wbp_io/neorv32_wbp_gateway.vhdl b/vhdl/neorv32_wbp_io/neorv32_wbp_gateway.vhdl index 12270b9..dc2f83d 100644 --- a/vhdl/neorv32_wbp_io/neorv32_wbp_gateway.vhdl +++ b/vhdl/neorv32_wbp_io/neorv32_wbp_gateway.vhdl @@ -24,6 +24,7 @@ -- 0.3, 2024-10-05, leuen4 -- delay BTB transactions also for error responses -- fix order of `rvsc.pending` reset +-- fix reset of `rvsc.expect_sc` -- ============================================================================= LIBRARY ieee; @@ -128,8 +129,8 @@ BEGIN -- invalid sc operation, either address missmatch or interrupted since lr rvsc.is_failure <= btb.stb AND rvsc.is_sc AND (rvsc.addr_match NAND rvsc.expect_sc); - rvsc.expect_sc_next <= '1' WHEN rvsc.is_lr = '1' ELSE - '0' WHEN btb.stb = '1' ELSE + rvsc.expect_sc_next <= '1' WHEN (rvsc.is_lr AND btb.stb) = '1' ELSE + '0' WHEN (btb.stb OR wbp_miso.err) = '1' ELSE rvsc.expect_sc; -- capture reserved address on lr operation