diff --git a/boards/riscv/neorv32/CMakeLists.txt b/boards/riscv/neorv32/CMakeLists.txt new file mode 100644 index 00000000000..ef15ed3fcc5 --- /dev/null +++ b/boards/riscv/neorv32/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if((CONFIG_BOARD_NEORV32) AND (CONFIG_BUILD_OUTPUT_BIN)) + # Generate NEORV32 image formats for initialising IMEM. + find_program(IMAGE_GEN image_gen) + + if(NOT ${IMAGE_GEN} STREQUAL IMAGE_GEN-NOTFOUND) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${IMAGE_GEN} + ARGS -app_bin + ${CONFIG_KERNEL_BIN_NAME}.bin + ${CONFIG_KERNEL_BIN_NAME}_exe.bin + ${PROJECT_BINARY_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + message(STATUS "neorv32 binary will be written to: ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}_exe.bin") + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${IMAGE_GEN} + ARGS -app_img + ${CONFIG_KERNEL_BIN_NAME}.bin + ${CONFIG_KERNEL_BIN_NAME}.vhd + ${PROJECT_BINARY_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + message(STATUS "neorv32 VHDL will be written to: ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.vhd") + else() + message(STATUS "The neorv32 image_gen utility was not found, neorv32 image files cannot be generated") + endif() +endif() diff --git a/boards/riscv/neorv32/Kconfig.board b/boards/riscv/neorv32/Kconfig.board new file mode 100644 index 00000000000..eee37f4a8c3 --- /dev/null +++ b/boards/riscv/neorv32/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NEORV32 + bool "NEORV32 Processor (SoC)" + depends on SOC_SERIES_NEORV32 diff --git a/boards/riscv/neorv32/Kconfig.defconfig b/boards/riscv/neorv32/Kconfig.defconfig new file mode 100644 index 00000000000..350255fb06a --- /dev/null +++ b/boards/riscv/neorv32/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NEORV32 + +config BOARD + default "neorv32" + +endif # BOARD_NEORV32 diff --git a/boards/riscv/neorv32/board.cmake b/boards/riscv/neorv32/board.cmake new file mode 100644 index 00000000000..b5088e8677e --- /dev/null +++ b/boards/riscv/neorv32/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd "--use-elf" "--cmd-reset-halt" "halt") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/riscv/neorv32/doc/index.rst b/boards/riscv/neorv32/doc/index.rst new file mode 100644 index 00000000000..3c7693ee685 --- /dev/null +++ b/boards/riscv/neorv32/doc/index.rst @@ -0,0 +1,184 @@ +.. _neorv32: + +NEORV32 +####### + +Overview +******** + +The NEORV32 is an open-source RISC-V compatible processor system intended as a +ready-to-go auxiliary processor within larger SoC designs or as a stand-alone +customizable microcontroller. + +.. figure:: ./neorv32_logo_transparent.png + :width: 813px + :align: center + :alt: NEORV32 + + NEORV32 (Credit: Stephan Nolting) + +For more information about the NEORV32, see the following websites: + +- `The NEORV32 RISC-V Processor GitHub`_ +- `The NEORV32 RISC-V Processor Datasheet`_ +- `The NEORV32 RISC-V Processor User Guide`_ + +Supported Features +================== + +The ``neorv32`` board configuration can be used a generic definition for NEORV32 +based boards. Customisation to fit custom NEORV32 implementations can be done +using :ref:`devicetree overlays `. + +Zephyr currently supports the following hardware features of the NEORV32 +Processor (SoC): + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| INTC | on-chip | interrupt controller | ++-----------+------------+-------------------------------------+ +| MTIME | on-chip | system timer | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio, non-interrupt | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ + +The default board configuration for the NEORV32 Processor (SoC) can be found in +the defconfig file: :file:`boards/riscv/neorv32/neorv32_defconfig`. + +System Clock +============ + +The default board configuration assumes a system clock of 100 MHz. The clock +frequency can be overridden by changing the ``clock-frequency`` property of the +``cpu0`` devicetree node. + +CPU +=== + +The default board configuration assumes the NEORV32 CPU implementation has the +following RISC-V ISA extensions enabled: + +- C (Compresses Instructions) +- M (Integer Multiplication and Division) +- Zicsr (Control and Status Register (CSR) Instructions) + +Internal Instruction Memory +=========================== + +The default board configuration assumes the NEORV32 SoC implementation has a 64k +byte internal instruction memory (IMEM) for code execution. The size of the +instruction memory can be overridden by changing the ``reg`` property of the +``imem`` devicetree node. + +Internal Data Memory +==================== + +The default board configuration assumes the NEORV32 SoC implementation has a 32k +byte internal data memory (DMEM). The size of the data memory can be overridden +by changing the ``reg`` property of the ``dmem`` devicetree node. + +Serial Port +=========== + +The default configuration assumes the NEORV32 SoC implements UART0 for use as +system console. + +.. note:: + + The default configuration uses a baud rate of 19200 to match that of the + standard NEORV32 bootloader. The baudrate can be changed by modifying the + ``current-speed`` property of the ``uart0`` devicetree node. + +Programming and Debugging +************************* + +First, configure the FPGA with the NEORV32 bitstream as described in the NEORV32 +user guide. + +Next, build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Console +===================== + +Use the following settings with your serial terminal of choice (minicom, putty, +etc.): + +- Speed: 19200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing via JTAG +================= + +Here is an example for building and flashing the :ref:`hello_world` application +for the NEORV32 via JTAG. Flashing via JTAG requires a NEORV32 SoC +implementation with the On-Chip Debugger (OCD) and bootloader enabled. + +.. note:: + + If the bootloader is not enabled, the internal instruction memory (IMEM) is + configured as ROM which cannot be modified via JTAG. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: neorv32 + :goals: flash + +After flashing, you should see message similar to the following in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-vn.n.nn *** + Hello World! neorv32 + +Note, however, that the application was not persisted in flash memory by the +above steps. It was merely written to internal block RAM in the FPGA. It will +revert to the application stored in the block RAM within the FPGA bitstream +the next time the FPGA is configured. + +The steps to persist the application within the FPGA bitstream are covered by +the NEORV32 user guide. If the :kconfig:`CONFIG_BUILD_OUTPUT_BIN` is enabled and +the NEORV32 ``image_gen`` binary is available, the build system will +automatically generate a :file:`zephyr.vhd` file suitable for initialising the +internal instruction memory of the NEORV32. + +Uploading via UART +================== + +If the :kconfig:`CONFIG_BUILD_OUTPUT_BIN` is enabled and the NEORV32 +``image_gen`` binary is available, the build system will automatically generate +a :file:`zephyr_exe.bin` file suitable for uploading to the NEORV32 via the +built-in bootloader as described in the NEORV32 user guide. + +Debugging via JTAG +================== + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: neorv32 + :goals: debug + +Step through the application in your debugger, and you should see a message +similar to the following in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-vn.n.nn *** + Hello World! neorv32 + +.. _The NEORV32 RISC-V Processor GitHub: + https://github.com/stnolting/neorv32 + +.. _The NEORV32 RISC-V Processor Datasheet: + https://stnolting.github.io/neorv32/ + +.. _The NEORV32 RISC-V Processor User Guide: + https://stnolting.github.io/neorv32/ug/ diff --git a/boards/riscv/neorv32/doc/neorv32_logo_transparent.png b/boards/riscv/neorv32/doc/neorv32_logo_transparent.png new file mode 100644 index 00000000000..8bf84fd9529 Binary files /dev/null and b/boards/riscv/neorv32/doc/neorv32_logo_transparent.png differ diff --git a/boards/riscv/neorv32/neorv32.dts b/boards/riscv/neorv32/neorv32.dts new file mode 100644 index 00000000000..aa9bf121679 --- /dev/null +++ b/boards/riscv/neorv32/neorv32.dts @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +/ { + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + }; + + chosen { + zephyr,flash = &imem; + zephyr,sram = &dmem; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-pipe = &uart0; + }; + + soc { + imem: memory@0 { + compatible = "soc-nv-flash", "mmio-sram"; + reg = <0x0 DT_SIZE_K(64)>; + }; + + bootrom: memory@ffff0000 { + compatible = "soc-nv-flash", "mmio-sram"; + reg = <0xffff0000 DT_SIZE_K(4)>; + }; + + dmem: memory@80000000 { + compatible = "mmio-sram"; + reg = <0x80000000 DT_SIZE_K(32)>; + }; + }; + + leds { + compatible = "gpio-leds"; + led0: led0 { + gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; + label = "LED_0"; + }; + + led1: led1 { + gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; + label = "LED_1"; + }; + + led2: led2 { + gpios = <&gpio 2 GPIO_ACTIVE_HIGH>; + label = "LED_2"; + }; + + led3: led3 { + gpios = <&gpio 3 GPIO_ACTIVE_HIGH>; + label = "LED_3"; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&uart0 { + status = "okay"; + current-speed = <19200>; +}; + +&gpio_lo { + status = "okay"; +}; + +&gpio_hi { + status = "okay"; +}; diff --git a/boards/riscv/neorv32/neorv32.yaml b/boards/riscv/neorv32/neorv32.yaml new file mode 100644 index 00000000000..7c5757e7a26 --- /dev/null +++ b/boards/riscv/neorv32/neorv32.yaml @@ -0,0 +1,11 @@ +identifier: neorv32 +name: NEORV32 Processor (SoC) +type: mcu +arch: riscv32 +toolchain: + - cross-compile + - zephyr +ram: 32 +flash: 64 +supported: + - gpio diff --git a/boards/riscv/neorv32/neorv32_1_6_1.conf b/boards/riscv/neorv32/neorv32_1_6_1.conf new file mode 100644 index 00000000000..877d6b335cb --- /dev/null +++ b/boards/riscv/neorv32/neorv32_1_6_1.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_NEORV32_V1_6_1=y diff --git a/boards/riscv/neorv32/neorv32_defconfig b/boards/riscv/neorv32/neorv32_defconfig new file mode 100644 index 00000000000..c0643542559 --- /dev/null +++ b/boards/riscv/neorv32/neorv32_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NEORV32=y +CONFIG_SOC_NEORV32_ISA_C=y +CONFIG_BOARD_NEORV32=y +CONFIG_RISCV_MACHINE_TIMER=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y diff --git a/boards/riscv/neorv32/revision.cmake b/boards/riscv/neorv32/revision.cmake new file mode 100644 index 00000000000..a09db094dbe --- /dev/null +++ b/boards/riscv/neorv32/revision.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +board_check_revision( + FORMAT MAJOR.MINOR.PATCH + DEFAULT_REVISION 1.6.1 +) diff --git a/boards/riscv/neorv32/support/neorv32.cfg b/boards/riscv/neorv32/support/neorv32.cfg new file mode 100644 index 00000000000..aed1aa6af6d --- /dev/null +++ b/boards/riscv/neorv32/support/neorv32.cfg @@ -0,0 +1,34 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME neorv32 +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 256 +} + +if { [info exists WORKAREAADDR] } { + set _WORKAREAADDR $WORKAREAADDR +} else { + set _WORKAREAADDR 0x80000000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x0cafe001 +} + +transport select jtag +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME + +$_TARGETNAME.0 configure -work-area-phys $_WORKAREAADDR -work-area-size $_WORKAREASIZE -work-area-backup 1 diff --git a/boards/riscv/neorv32/support/openocd.cfg b/boards/riscv/neorv32/support/openocd.cfg new file mode 100644 index 00000000000..a857c8ba7c1 --- /dev/null +++ b/boards/riscv/neorv32/support/openocd.cfg @@ -0,0 +1,17 @@ +# Copyright (c) 2021 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6010 +ftdi_channel 0 + +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + ftdi_serial $_ZEPHYR_BOARD_SERIAL +} + +ftdi_layout_init 0x0038 0x003b + +adapter speed 1000 +ftdi_layout_signal nTRST -ndata 0x0010 -noe 0x0040 + +source [find neorv32.cfg]