├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── Documentation.yml │ └── Processor.yml ├── .gitignore ├── CHANGELOG.md ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── Doxyfile ├── Makefile ├── README.md ├── attrs.adoc ├── datasheet │ ├── content.adoc │ ├── cpu.adoc │ ├── cpu_cfu.adoc │ ├── cpu_csr.adoc │ ├── cpu_dual_core.adoc │ ├── index.adoc │ ├── main.adoc │ ├── on_chip_debugger.adoc │ ├── overview.adoc │ ├── rationale.adoc │ ├── soc.adoc │ ├── soc_bootrom.adoc │ ├── soc_cfs.adoc │ ├── soc_clint.adoc │ ├── soc_dcache.adoc │ ├── soc_dma.adoc │ ├── soc_dmem.adoc │ ├── soc_gpio.adoc │ ├── soc_gptmr.adoc │ ├── soc_icache.adoc │ ├── soc_imem.adoc │ ├── soc_neoled.adoc │ ├── soc_onewire.adoc │ ├── soc_pwm.adoc │ ├── soc_sdi.adoc │ ├── soc_slink.adoc │ ├── soc_spi.adoc │ ├── soc_sysinfo.adoc │ ├── soc_trng.adoc │ ├── soc_twd.adoc │ ├── soc_twi.adoc │ ├── soc_uart.adoc │ ├── soc_wdt.adoc │ ├── soc_xbus.adoc │ ├── software.adoc │ ├── software_bootloader.adoc │ └── software_rte.adoc ├── doxygen_main.md ├── figures │ ├── .gitignore │ ├── README.md │ ├── address_space.png │ ├── eclipse.png │ ├── icon.png │ ├── neorv32_bus.png │ ├── neorv32_cpu.png │ ├── neorv32_logo.png │ ├── neorv32_logo_riscv.png │ ├── neorv32_logo_riscv_small.png │ ├── neorv32_logo_small.png │ ├── neorv32_logo_smcard.jpg │ ├── neorv32_ocd_complex.png │ ├── neorv32_processor.png │ ├── neorv32_test_setup.png │ ├── riscv_logo.png │ ├── riscv_logo_small.png │ ├── smp_system.png │ ├── vivado_ip_gui.png │ └── vivado_ip_soc.png ├── legal.adoc ├── neorv32-theme.yml ├── references │ ├── riscv-aclint-1.0-rc4.pdf │ ├── riscv-debug-specification.pdf │ ├── riscv-privileged.pdf │ └── riscv-unprivileged.pdf └── userguide │ ├── adding_custom_hw_modules.adoc │ ├── application_program_compilation.adoc │ ├── application_specific_configuration.adoc │ ├── building_the_documentation.adoc │ ├── content.adoc │ ├── debugging_with_ocd.adoc │ ├── eclipse_ide.adoc │ ├── executable_upload.adoc │ ├── free_rtos_support.adoc │ ├── general_hw_setup.adoc │ ├── general_sw_framework_setup.adoc │ ├── index.adoc │ ├── installing_an_executable.adoc │ ├── litex_support.adoc │ ├── main.adoc │ ├── micropython_port.adoc │ ├── neorv32_in_verilog.adoc │ ├── new_application_project.adoc │ ├── packaging_vivado.adoc │ ├── simulating_the_processor.adoc │ ├── sw_toolchain_setup.adoc │ ├── using_the_neorv32_bootloader.adoc │ └── zephyr_support.adoc ├── rtl ├── README.md ├── core │ ├── neorv32_application_image.vhd │ ├── neorv32_boot_rom.vhd │ ├── neorv32_bootloader_image.vhd │ ├── neorv32_bus.vhd │ ├── neorv32_cache.vhd │ ├── neorv32_cfs.vhd │ ├── neorv32_clint.vhd │ ├── neorv32_cpu.vhd │ ├── neorv32_cpu_alu.vhd │ ├── neorv32_cpu_control.vhd │ ├── neorv32_cpu_counters.vhd │ ├── neorv32_cpu_cp_bitmanip.vhd │ ├── neorv32_cpu_cp_cfu.vhd │ ├── neorv32_cpu_cp_cond.vhd │ ├── neorv32_cpu_cp_crypto.vhd │ ├── neorv32_cpu_cp_fpu.vhd │ ├── neorv32_cpu_cp_muldiv.vhd │ ├── neorv32_cpu_cp_shifter.vhd │ ├── neorv32_cpu_decompressor.vhd │ ├── neorv32_cpu_frontend.vhd │ ├── neorv32_cpu_lsu.vhd │ ├── neorv32_cpu_pmp.vhd │ ├── neorv32_cpu_regfile.vhd │ ├── neorv32_debug_auth.vhd │ ├── neorv32_debug_dm.vhd │ ├── neorv32_debug_dtm.vhd │ ├── neorv32_dma.vhd │ ├── neorv32_dmem.vhd │ ├── neorv32_fifo.vhd │ ├── neorv32_gpio.vhd │ ├── neorv32_gptmr.vhd │ ├── neorv32_imem.vhd │ ├── neorv32_neoled.vhd │ ├── neorv32_onewire.vhd │ ├── neorv32_package.vhd │ ├── neorv32_pwm.vhd │ ├── neorv32_sdi.vhd │ ├── neorv32_slink.vhd │ ├── neorv32_spi.vhd │ ├── neorv32_sys.vhd │ ├── neorv32_sysinfo.vhd │ ├── neorv32_top.vhd │ ├── neorv32_trng.vhd │ ├── neorv32_twd.vhd │ ├── neorv32_twi.vhd │ ├── neorv32_uart.vhd │ ├── neorv32_wdt.vhd │ └── neorv32_xbus.vhd ├── file_list_cpu.f ├── file_list_soc.f ├── generate_file_lists.sh ├── processor_templates │ ├── README.md │ ├── neorv32_ProcessorTop_Minimal.vhd │ ├── neorv32_ProcessorTop_MinimalBoot.vhd │ └── neorv32_ProcessorTop_UP5KDemo.vhd ├── system_integration │ ├── .gitignore │ ├── README.md │ ├── neorv32_litex_core_complex.vhd │ ├── neorv32_vivado_ip.tcl │ ├── neorv32_vivado_ip.vhd │ └── xbus2axi4_bridge.vhd └── test_setups │ ├── README.md │ ├── neorv32_test_setup_approm.vhd │ ├── neorv32_test_setup_bootloader.vhd │ └── neorv32_test_setup_on_chip_debugger.vhd ├── sim ├── ghdl.sh ├── neorv32_tb.vhd ├── sim_uart_rx.vhd ├── xbus_gateway.vhd └── xbus_memory.vhd └── sw ├── README.md ├── bootloader ├── README.md ├── config.h ├── hal │ ├── include │ │ ├── spi_flash.h │ │ ├── twi_flash.h │ │ └── uart.h │ └── source │ │ ├── spi_flash.c │ │ ├── twi_flash.c │ │ └── uart.c ├── main.c └── makefile ├── common ├── common.mk ├── crt0.S └── neorv32.ld ├── example ├── bus_explorer │ ├── main.c │ └── makefile ├── coremark │ ├── LICENSE.md │ ├── include │ │ ├── core_portme.h │ │ └── coremark.h │ ├── makefile │ └── source │ │ ├── core_list_join.c │ │ ├── core_main.c │ │ ├── core_matrix.c │ │ ├── core_portme.c │ │ ├── core_state.c │ │ ├── core_util.c │ │ ├── cvt.c │ │ └── ee_printf.c ├── demo_blink_led │ ├── main.c │ └── makefile ├── demo_cfs │ ├── main.c │ └── makefile ├── demo_cfu │ ├── main.c │ └── makefile ├── demo_clint │ ├── Makefile │ └── main.c ├── demo_dma │ ├── main.c │ └── makefile ├── demo_dual_core │ ├── Makefile │ ├── main.c │ ├── spinlock.c │ └── spinlock.h ├── demo_dual_core_primes │ ├── Makefile │ └── main.c ├── demo_dual_core_rte │ ├── Makefile │ ├── main.c │ ├── spinlock.c │ └── spinlock.h ├── demo_emulate_unaligned │ ├── main.c │ └── makefile ├── demo_gpio │ ├── Makefile │ └── main.c ├── demo_gptmr │ ├── main.c │ └── makefile ├── demo_hpm │ ├── main.c │ └── makefile ├── demo_neopixel │ ├── main.c │ └── makefile ├── demo_newlib │ ├── main.c │ └── makefile ├── demo_onewire │ ├── main.c │ ├── makefile │ └── onewire_aux.h ├── demo_pwm │ ├── main.c │ └── makefile ├── demo_sdi │ ├── main.c │ └── makefile ├── demo_slink │ ├── main.c │ └── makefile ├── demo_spi │ ├── main.c │ └── makefile ├── demo_spi_irq │ ├── drv │ │ ├── neorv32_spi_irq.c │ │ └── neorv32_spi_irq.h │ ├── main.c │ └── makefile ├── demo_trng │ ├── main.c │ └── makefile ├── demo_twd │ ├── main.c │ └── makefile ├── demo_twi │ ├── main.c │ └── makefile ├── demo_wdt │ ├── main.c │ └── makefile ├── dhrystone │ ├── LICENSE │ ├── README.md │ ├── dhry.h │ ├── dhry_1.c │ ├── dhry_2.c │ └── makefile ├── eclipse │ ├── .cproject │ ├── .gitignore │ ├── .project │ ├── README.md │ ├── eclipse_example Default.launch │ ├── main.c │ └── makefile ├── float_corner_test │ ├── README.md │ ├── main.c │ ├── makefile │ └── neorv32_zfinx_extension_intrinsics.h ├── floating_point_test │ ├── README.md │ ├── main.c │ ├── makefile │ └── neorv32_zfinx_extension_intrinsics.h ├── game_of_life │ ├── main.c │ └── makefile ├── hello_cpp │ ├── main.cpp │ └── makefile ├── hello_world │ ├── main.c │ └── makefile ├── makefile ├── performance_tests │ ├── I │ │ ├── README.md │ │ ├── main.c │ │ └── makefile │ ├── M │ │ ├── README.md │ │ ├── main.c │ │ └── makefile │ ├── Zfinx │ │ ├── README.md │ │ ├── main.c │ │ └── makefile │ ├── makefile │ └── run_performance.sh └── processor_check │ ├── README.md │ ├── main.c │ ├── makefile │ └── run_check.sh ├── image_gen ├── image_gen.c └── uart_upload.sh ├── lib ├── README.md ├── include │ ├── neorv32.h │ ├── neorv32_aux.h │ ├── neorv32_cfs.h │ ├── neorv32_clint.h │ ├── neorv32_cpu.h │ ├── neorv32_cpu_cfu.h │ ├── neorv32_cpu_csr.h │ ├── neorv32_dma.h │ ├── neorv32_gpio.h │ ├── neorv32_gptmr.h │ ├── neorv32_intrinsics.h │ ├── neorv32_neoled.h │ ├── neorv32_onewire.h │ ├── neorv32_pwm.h │ ├── neorv32_rte.h │ ├── neorv32_sdi.h │ ├── neorv32_slink.h │ ├── neorv32_smp.h │ ├── neorv32_spi.h │ ├── neorv32_sysinfo.h │ ├── neorv32_trng.h │ ├── neorv32_twd.h │ ├── neorv32_twi.h │ ├── neorv32_uart.h │ └── neorv32_wdt.h └── source │ ├── neorv32_aux.c │ ├── neorv32_cfs.c │ ├── neorv32_clint.c │ ├── neorv32_cpu.c │ ├── neorv32_cpu_cfu.c │ ├── neorv32_dma.c │ ├── neorv32_gpio.c │ ├── neorv32_gptmr.c │ ├── neorv32_neoled.c │ ├── neorv32_newlib.c │ ├── neorv32_onewire.c │ ├── neorv32_pwm.c │ ├── neorv32_rte.c │ ├── neorv32_sdi.c │ ├── neorv32_slink.c │ ├── neorv32_smp.c │ ├── neorv32_spi.c │ ├── neorv32_trng.c │ ├── neorv32_twd.c │ ├── neorv32_twi.c │ ├── neorv32_uart.c │ └── neorv32_wdt.c ├── ocd-firmware ├── .gitignore ├── README.md ├── debug_rom.ld ├── makefile └── park_loop.S ├── openocd ├── README.md ├── authentication.cfg ├── interface.cfg ├── openocd_neorv32.cfg ├── openocd_neorv32.dual_core.cfg └── target.cfg └── svd ├── README.md └── neorv32.svd /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Environment:** 23 | - OS 24 | - GCC Version (RISC-V and native) 25 | - Libraries used (clib, newlib, ...) 26 | 27 | **Hardware:** 28 | - Hardware version (x.x.x.x) 29 | - Implemented CPU extensions, peripherals, ... 30 | - Hardware modifications 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/Documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'docs/**' 7 | - '.github/workflows/Documentation.yml' 8 | pull_request: 9 | paths: 10 | - 'docs/**' 11 | - '.github/workflows/Documentation.yml' 12 | workflow_dispatch: 13 | 14 | jobs: 15 | 16 | doxygen: 17 | runs-on: ubuntu-22.04 18 | name: 'SW Framework' 19 | 20 | steps: 21 | 22 | - name: '🧰 Repository Checkout' 23 | uses: actions/checkout@v4 24 | 25 | - name: '🛠️ Modifying Doxyfile' 26 | run: | 27 | ls -al ./docs 28 | sed -i 's/$(PWD)\/../$(GITHUB_WORKSPACE)/g' ./docs/Doxyfile 29 | 30 | - name: '📚 Generate Doxygen Documentation' 31 | uses: mattnotmitt/doxygen-action@v1.2.1 32 | with: 33 | working-directory: '.' 34 | doxyfile-path: 'docs/Doxyfile' 35 | 36 | - name: '📤 Upload Artifact' 37 | uses: actions/upload-artifact@v4 38 | with: 39 | name: NEORV32-Doxygen 40 | path: doxygen_build/html 41 | 42 | 43 | asciidoctor: 44 | runs-on: ubuntu-22.04 45 | name: 'Datasheet' 46 | 47 | steps: 48 | 49 | - name: '🧰 Repository Checkout' 50 | uses: actions/checkout@v4 51 | with: 52 | fetch-depth: 0 53 | 54 | - name: '📚 Build Datasheet and User Guide (PDF and HTML)' 55 | run: make -C docs container 56 | 57 | - name: '📤 Upload Artifact: HTML' 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: NEORV32 61 | path: docs/public 62 | 63 | 64 | deploy: 65 | if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/')) 66 | needs: 67 | - doxygen 68 | - asciidoctor 69 | runs-on: ubuntu-22.04 70 | name: 'Deploy to Releases and Pages' 71 | 72 | steps: 73 | 74 | - name: '🧰 Repository Checkout' 75 | uses: actions/checkout@v4 76 | 77 | - name: '📥 Download Artifacts' 78 | uses: actions/download-artifact@v4 79 | 80 | - name: '🛠️ Organize public subdir and create a tarball' 81 | run: | 82 | mv NEORV32 public 83 | mv public/pdf ./ 84 | mv NEORV32-Doxygen public/sw 85 | tar zvcf NEORV32-SITE-nightly.tar.gz -C public . 86 | cd pdf 87 | mv NEORV32.pdf NEORV32-nightly.pdf 88 | mv NEORV32_UserGuide.pdf NEORV32_UserGuide-nightly.pdf 89 | 90 | # Tagged: create a pre-release or a release (semver) 91 | # Untagged: update the assets of pre-release 'nightly' 92 | - name: '📦 Deploy to GitHub-Releases' 93 | env: 94 | GITHUB_TOKEN: ${{ github.token }} 95 | run: | 96 | gh release upload nightly NEORV32-SITE-nightly.tar.gz pdf/NEORV32*nightly.pdf --clobber 97 | 98 | - name: '🚀 Deploy to GitHub-Pages' 99 | run: | 100 | cd public 101 | git init 102 | cp ../.git/config ./.git/config 103 | touch .nojekyll 104 | git add . 105 | git config --local user.email "push@gha" 106 | git config --local user.name "GHA" 107 | git commit -am 'update ${{ github.sha }}' 108 | git push -u origin +HEAD:gh-pages 109 | -------------------------------------------------------------------------------- /.github/workflows/Processor.yml: -------------------------------------------------------------------------------- 1 | name: Processor 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'rtl/**' 7 | - 'sw/**' 8 | - 'sim/**' 9 | - '.github/workflows/Processor.yml' 10 | pull_request: 11 | paths: 12 | - 'rtl/**' 13 | - 'sw/**' 14 | - 'sim/**' 15 | - '.github/workflows/Processor.yml' 16 | workflow_dispatch: 17 | 18 | jobs: 19 | 20 | sim_default_tb: 21 | runs-on: ubuntu-latest 22 | name: 'processor simulation' 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | example: 27 | - processor_check 28 | - hello_world 29 | 30 | steps: 31 | 32 | - name: '🧰 Repository Checkout' 33 | uses: actions/checkout@v4 34 | 35 | - name: '📦 Install xPack RISC-V GCC' 36 | run: | 37 | wget -q https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-2/xpack-riscv-none-elf-gcc-14.2.0-2-linux-x64.tar.gz 38 | mkdir $GITHUB_WORKSPACE/riscv-gcc 39 | tar -xzf xpack-riscv-none-elf-gcc-14.2.0-2-linux-x64.tar.gz -C $GITHUB_WORKSPACE/riscv-gcc 40 | echo $GITHUB_WORKSPACE/riscv-gcc/xpack-riscv-none-elf-gcc-14.2.0-2/bin >> $GITHUB_PATH 41 | 42 | - name: '📦 Install GHDL' 43 | uses: ghdl/setup-ghdl@v1 44 | with: 45 | version: nightly 46 | backend: mcode 47 | 48 | - name: '🔍 Check tools' 49 | run: | 50 | riscv-none-elf-gcc -v 51 | ghdl -v 52 | 53 | - name: '⚙️ Build Software Framework Tests' 54 | run: | 55 | make RISCV_PREFIX=riscv-none-elf- -C sw/example/processor_check check 56 | make RISCV_PREFIX=riscv-none-elf- -C sw/example clean_all exe 57 | make RISCV_PREFIX=riscv-none-elf- -C sw/bootloader clean_all info bootloader 58 | 59 | - name: '🚧 Compile executable and run simulation' 60 | run: | 61 | make -C sw/example/${{ matrix.example }} \ 62 | RISCV_PREFIX=riscv-none-elf- \ 63 | USER_FLAGS+="-DUART0_SIM_MODE -DUART1_SIM_MODE" \ 64 | clean_all \ 65 | info \ 66 | all \ 67 | sim-check 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # generated app files 2 | *.bin 3 | *.coe 4 | *.mem 5 | *.mif 6 | *.o 7 | *.elf 8 | *.asm 9 | *.out 10 | *.hex 11 | *_image.vhd 12 | build/ 13 | 14 | # keep default VHDL memory images 15 | !rtl/core/*_image.vhd 16 | 17 | # logs 18 | *.gdb_history 19 | *.log 20 | 21 | # host executables 22 | sw/image_gen/image_gen 23 | *.exe 24 | *.cf 25 | 26 | # temporary files and folders 27 | *.bak 28 | *.tmp 29 | ~* 30 | 31 | # generated documentation stuff 32 | /docs/doxygen_build/ 33 | /docs/public/ 34 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you are using this project, please cite it as below." 3 | authors: 4 | - family-names: "Nolting" 5 | given-names: "Stephan" 6 | - family-names: "All The Awesome Contributors" 7 | given-names: "" 8 | title: "The NEORV32 RISC-V Processor" 9 | doi: 10.5281/zenodo.13872735 10 | url: "https://github.com/stnolting/neorv32" 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | If you have any questions, bug reports, ideas or if you want to 4 | give some kind of feedback, feel free to open a [new issue](https://github.com/stnolting/neorv32/issues/new/choose) 5 | or start a new [discussion](https://github.com/stnolting/neorv32/discussions). Also look out for issues and pull requests labeled with 6 | [![help-wanted](https://img.shields.io/badge/-help%20wanted-brightgreen)](https://github.com/stnolting/neorv32/labels/help%20wanted) and 7 | [![good-first-issue](https://img.shields.io/badge/-good%20first%20issue-purple)](https://github.com/stnolting/neorv32/labels/good%20first%20issue); 8 | the latter one might be a good starting point for newcomers and beginners 9 | 10 | > [!NOTE] 11 | > Please note that we have a [Code of Conduct](https://github.com/stnolting/neorv32/blob/main/CODE_OF_CONDUCT.md). 12 | Please follow it in all your interactions with this project. 13 | 14 | ### Contributing Process 15 | 16 | Here is a simple guide line if you'd like to contribute code modifications to this project: 17 | 18 | 1. [Fork](https://github.com/stnolting/neorv32/fork) this repository and clone the fork: `git clone https://github.com/stnolting/neorv32.git` 19 | 2. In your local copy, create a feature branch: `git checkout -b awesome_new_feature_branch` 20 | 3. Create a new _remote_ for the upstream repo: `git remote add upstream https://github.com/stnolting/neorv32` 21 | 4. Commit your modifications: `git commit -m "Awesome new feature!"` 22 | 5. Push to the branch: `git push origin awesome_new_feature_branch` 23 | 6. Create a new [pull request](https://github.com/stnolting/neorv32/pulls); please make sure that your feature branch is up-to-date 24 | with the project's `main` branch; we will review your request as soon as possible! 25 | 7. If you like, discuss / show-case your work on the project's [discussion board](https://github.com/stnolting/neorv32/discussions). 26 | 27 | If your merge request modifies the code base in a significant way (something more than just a typo fix) please also update 28 | the version identifier (increment the least-significant number) and add an according change log entry 29 | (see [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/main/CHANGELOG.md) for more information). 30 | 31 | > [!TIP] 32 | > If possible, use [labels](https://github.com/stnolting/neorv32/labels) 33 | to categorize your issue, discussion thread or merge request. 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) NEORV32 contributors. 4 | Copyright (c) 2020-2025, Stephan Nolting. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | .DEFAULT_GOAL := help 2 | 3 | PUBLIC_DIR = public 4 | PUBLIC_IMG_DIR = $(PUBLIC_DIR)/img 5 | 6 | DOXYGEN_IMG_DIR = doxygen_build/html/docs/figures 7 | 8 | all: pdf html ug-pdf ug-html 9 | 10 | # Public folder 11 | $(PUBLIC_DIR): 12 | @mkdir -p $(PUBLIC_DIR) 13 | 14 | # Copy images for datasheet and ug html 15 | $(PUBLIC_IMG_DIR): $(PUBLIC_DIR) 16 | @mkdir -p $@ 17 | cp -vr figures/* $@ 18 | 19 | # Copy images for doxygen 20 | $(DOXYGEN_IMG_DIR): 21 | @mkdir -p $@ 22 | cp -vr figures/* $@ 23 | 24 | # Generate PDF datasheet 25 | pdf: $(PUBLIC_DIR) 26 | [ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \ 27 | asciidoctor-pdf $$REVNUMBER \ 28 | -a allow-uri-read \ 29 | -a pdf-theme=neorv32-theme.yml \ 30 | -r asciidoctor-diagram \ 31 | datasheet/main.adoc \ 32 | --out-file $(PUBLIC_DIR)/pdf/NEORV32.pdf 33 | 34 | # Generate HTML datasheet 35 | html: $(PUBLIC_IMG_DIR) $(PUBLIC_DIR) 36 | [ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \ 37 | asciidoctor $$REVNUMBER \ 38 | -r asciidoctor-diagram \ 39 | datasheet/index.adoc \ 40 | --out-file $(PUBLIC_DIR)/index.html 41 | 42 | # Generate PDF user guide 43 | ug-pdf: $(PUBLIC_DIR) 44 | [ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \ 45 | asciidoctor-pdf $$REVNUMBER \ 46 | -a allow-uri-read \ 47 | -a pdf-theme=neorv32-theme.yml \ 48 | -r asciidoctor-diagram \ 49 | userguide/main.adoc \ 50 | --out-file $(PUBLIC_DIR)/pdf/NEORV32_UserGuide.pdf 51 | 52 | # Generate HTML user guide 53 | ug-html: $(PUBLIC_IMG_DIR) $(PUBLIC_DIR) 54 | [ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \ 55 | asciidoctor $$REVNUMBER \ 56 | -r asciidoctor-diagram \ 57 | userguide/index.adoc \ 58 | --out-file $(PUBLIC_DIR)/ug/index.html 59 | 60 | # Generate DOXYGEN software documentation 61 | doxygen: $(DOXYGEN_IMG_DIR) 62 | doxygen Doxyfile 63 | 64 | # Generate revnumber.txt for overriding the revnumber attribute in 'pdf' and/or 'html' 65 | revnumber: 66 | if [ `git tag -l | grep nightly` ]; then git tag -d nightly; fi 67 | git describe --long --tags | sed 's#\([^-]*-g\)#r\1#;' > revnumber.txt 68 | cat revnumber.txt 69 | 70 | # Build 'pdf' and 'html' in an 'asciidoctor-wavedrom' container 71 | container: revnumber 72 | docker run --rm -v /$(shell pwd)://documents/ btdi/asciidoctor make all 73 | 74 | clean: 75 | @rm -rf $(PUBLIC_IMG_DIR) 76 | @rm -rf $(PUBLIC_DIR) 77 | @rm -rf doxygen_build 78 | @rm -f revnumber.txt 79 | 80 | # Help 81 | help: 82 | @echo "Targets:" 83 | @echo " all - build datasheet and user guide as pdf and HTML file" 84 | @echo " help - show this text" 85 | @echo " pdf - build datasheet as pdf file (public/pdf/NEORV32.pdf)" 86 | @echo " html - build datasheet as HTML page (public/index.html)" 87 | @echo " ug-pdf - build user guide as pdf file (public/pdf/NEORV32_UserGuide.pdf)" 88 | @echo " ug-html - build user guide as HTML page (public/ug/index.html)" 89 | @echo " doxygen - build software documentation as HTML page (doxygen_build/html/index.html)" 90 | @echo " revnumber - for overriding the revnumber attribute in 'pdf' and/or 'html'" 91 | @echo " container - Build 'pdf' and 'html' in an 'asciidoctor-wavedrom' container" 92 | @echo " clean - delete output files and directories" 93 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## Project Documentation 2 | 3 | ### > [`datasheet`](datasheet) 4 | 5 | AsciiDoc sources for the NEORV32 data sheet. The online version of the data sheet is 6 | available at [https://stnolting.github.io/neorv32](https://stnolting.github.io/neorv32). 7 | 8 | ### > [`figures`](figures) 9 | 10 | Figures and images used by the data sheet, user guide and the webpage(s). The according 11 | license(s) are listed in `license.md`. 12 | 13 | ### > [`references`](references) 14 | 15 | Reference material like RISC-V and Wishbone specifications. 16 | 17 | ### > [`sources`](sources) 18 | 19 | Various sources for the images in `figures/`. 20 | 21 | ### > [`userguide`](userguide) 22 | 23 | AsciiDoc sources for the NEORV32 user guide. The online version of the user guide is 24 | available at [https://stnolting.github.io/neorv32/ug](https://stnolting.github.io/neorv32/ug). 25 | -------------------------------------------------------------------------------- /docs/attrs.adoc: -------------------------------------------------------------------------------- 1 | :author: The NEORV32 Community and Stephan Nolting 2 | :email: stnolting@gmail.com 3 | :keywords: neorv32, risc-v, riscv, rv32, fpga, soft-core, vhdl, microcontroller, cpu, soc, processor, gcc, openocd, gdb, verilog, rtl, asip, asic 4 | :description: A size-optimized, customizable and highly extensible MCU-class 32-bit RISC-V soft-core CPU and microcontroller-like SoC written in platform-independent VHDL. 5 | :revnumber: v1.11.6 6 | :icons: font 7 | :source-highlighter: highlight.js 8 | :imagesdir: ../figures 9 | :toc: macro 10 | :doctype: book 11 | :sectnums: 12 | :stem: 13 | :reproducible: 14 | :listing-caption: Listing 15 | :toclevels: 3 16 | :title-logo-image: ../figures/neorv32_logo_riscv.png 17 | :favicon: img/icon.png 18 | -------------------------------------------------------------------------------- /docs/datasheet/content.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | // #################################################################################################################### 3 | 4 | <<< 5 | include::overview.adoc[] 6 | 7 | <<< 8 | include::soc.adoc[] 9 | 10 | <<< 11 | include::cpu.adoc[] 12 | 13 | <<< 14 | include::software.adoc[] 15 | 16 | <<< 17 | include::on_chip_debugger.adoc[] 18 | 19 | <<< 20 | include::../legal.adoc[] 21 | -------------------------------------------------------------------------------- /docs/datasheet/index.adoc: -------------------------------------------------------------------------------- 1 | = The NEORV32 RISC-V Processor - Datasheet 2 | include::../attrs.adoc[] 3 | :title: [Datasheet] The NEORV32 RISC-V Processor 4 | :icons: font 5 | :imagesdir: img 6 | :toc: left 7 | :title-logo-image: neorv32_logo_riscv.png[pdfwidth=6.25in,align=center] 8 | :favicon: img/icon.png 9 | 10 | image::neorv32_logo.png[align=center,link="https://github.com/stnolting/neorv32"] 11 | 12 | image::riscv_logo.png[width=350,align=center,link="https://riscv.org/"] 13 | 14 | [.text-center] 15 | https://github.com/stnolting/neorv32[image:https://img.shields.io/badge/GitHub-stnolting%2Fneorv32-ffbd00?style=flat-square&logo=github&[title='homepage']] 16 | https://github.com/stnolting/neorv32/blob/main/LICENSE[image:https://img.shields.io/github/license/stnolting/neorv32?longCache=true&style=flat-square[title='license']] 17 | https://github.com/stnolting/neorv32/releases/tag/nightly[image:https://img.shields.io/badge/data%20sheet-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor[title='datasheet (pdf)']] 18 | https://github.com/stnolting/neorv32/releases/tag/nightly[image:https://img.shields.io/badge/user%20guide-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor[title='userguide (pdf)']] 19 | https://stnolting.github.io/neorv32/ug[image:https://img.shields.io/badge/-HTML-ffbd00?longCache=true&style=flat-square[title='userguide (html)']] 20 | https://stnolting.github.io/neorv32/sw/files.html[image:https://img.shields.io/badge/doxygen-HTML-ffbd00?longCache=true&style=flat-square&logo=Doxygen[title='doxygen']] + 21 | https://github.com/stnolting/neorv32/releases[image:https://img.shields.io/github/v/release/stnolting/neorv32?longCache=true&style=flat-square&logo=GitHub[title='release']] 22 | https://github.com/stnolting/neorv32/releases[image:https://img.shields.io/github/commits-since/stnolting/neorv32/latest?longCache=true&style=flat-square&logo=GitHub[title='release-commits']] 23 | 24 | include::content.adoc[] 25 | -------------------------------------------------------------------------------- /docs/datasheet/main.adoc: -------------------------------------------------------------------------------- 1 | = The NEORV32 RISC-V Processor - Datasheet 2 | include::../attrs.adoc[] 3 | 4 | 5 | <<< 6 | // #################################################################################################################### 7 | .**Documentation** 8 | [TIP] 9 | The online documentation of the project (a.k.a. the **data sheet**) is available on GitHub-pages: https://stnolting.github.io/neorv32/ + 10 | + 11 | The online documentation of the **software framework** is also available on GitHub-pages: https://stnolting.github.io/neorv32/sw/files.html 12 | 13 | 14 | <<< 15 | // #################################################################################################################### 16 | toc::[] 17 | 18 | include::content.adoc[] 19 | -------------------------------------------------------------------------------- /docs/datasheet/soc_bootrom.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | ==== Bootloader ROM (BOOTROM) 4 | 5 | [cols="<3,<3,<4"] 6 | [grid="none"] 7 | |======================= 8 | | Hardware source files: | neorv32_boot_rom.vhd | default platform-agnostic bootloader ROM 9 | | | neorv32_bootloader_image.vhd | initialization image (a VHDL package) 10 | | Software driver files: | none | _implicitly used_ 11 | | Top entity ports: | none | 12 | | Configuration generics: | `BOOT_MODE_SELECT` | implement BOOTROM when `BOOT_MODE_SELECT` = 0; see <<_boot_configuration>> 13 | | CPU interrupts: | none | 14 | |======================= 15 | 16 | 17 | **Overview** 18 | 19 | The boot ROM contains the executable image of the default NEORV32 <<_bootloader>>. When the 20 | <<_boot_configuration>> is set to _bootloader_ mode (0) via the `BOOT_MODE_SELECT` generic, the 21 | boot ROM is automatically enabled and the CPU boot address is adjusted to the base address of the boot ROM. 22 | Note that the entire boot ROM is read-only. 23 | 24 | .Bootloader Image 25 | [IMPORTANT] 26 | The bootloader ROM is initialized during synthesis with the default bootloader image 27 | (`rtl/core/neorv32_bootloader_image.vhd`). The physical size of the ROM is automatically 28 | adjusted to the next power of two of the image size. However, note that the BOOTROM is 29 | constrained to a maximum size of 64kB. 30 | -------------------------------------------------------------------------------- /docs/datasheet/soc_dcache.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | <<< 3 | :sectnums: 4 | ==== Processor-Internal Data Cache (dCache) 5 | 6 | [cols="<3,<3,<4"] 7 | [grid="none"] 8 | |======================= 9 | | Hardware source files: | neorv32_cache.vhd | Generic cache module 10 | | Software driver files: | none | 11 | | Top entity ports: | none | 12 | | Configuration generics: | `DCACHE_EN` | implement processor-internal, CPU-exclusive data cache (D$) when `true` 13 | | | `DCACHE_NUM_BLOCKS` | number of cache blocks ("cache lines"); has to be a power of two 14 | | | `CACHE_BLOCK_SIZE` | size of a cache block in bytes; has to be a power of two (global configuration for I$ and D$) 15 | | CPU interrupts: | none | 16 | |======================= 17 | 18 | 19 | **Overview** 20 | 21 | The processor features an optional CPU data cache. The cache is connected directly to the CPU's data access interface 22 | and provides full-transparent accesses. The cache is direct-mapped and uses "write-through" as write strategy. 23 | The cache uses <<_locked_bus_accesses_and_bursts>> to download cache blocks/lines from main memory. 24 | In the <<_dual_core_configuration>> each CPU core is equipped with a private data cache. 25 | 26 | The data cache is implemented if `DCACHE_EN` it _true_. The total cache memory size in bytes is defined by 27 | `DCACHE_NUM_BLOCKS x CACHE_BLOCK_SIZE`. `DCACHE_NUM_BLOCKS` defines the number of cache blocks (or "cache lines") 28 | and `CACHE_BLOCK_SIZE` defines the block size in bytes; note that this configuration is global for all caches. 29 | 30 | .Burst Transfers 31 | [IMPORTANT] 32 | If the cache is activated, this also means that cache block transfers are **always executed as burst transfers**. 33 | There is no possibility to execute the cache block transfers as single bus transactions. Therefore, all devices, 34 | memories and endpoints that can be accessed by the cache must also be able to process bursts. 35 | 36 | .Uncached Accesses 37 | [NOTE] 38 | The cache provides direct/uncached accesses to memory (bypassing the cache) in order to access memory-mapped IO (like the 39 | processor-internal IO/peripheral modules). All accesses that target the address range from `0xF0000000` to `0xFFFFFFFF` 40 | will bypass the cache. Hence, access will not be cached. See section <<_address_space>> for more information. Furthermore, 41 | the atomic memory operations of the <<_zaamo_isa_extension>> will always **bypass** the cache. 42 | 43 | .Manual Cache Flush/Clear/Reload and Memory Coherence 44 | [NOTE] 45 | By executing the `fence` instruction the data cache is flushed, cleared and reloaded. 46 | See section <<_memory_coherence>> for more information. 47 | 48 | .Cache Block Update Fault Handling 49 | [NOTE] 50 | If the cache encounters a bus error when uploading a modified block to main memory or when 51 | downloading a new block from main memory, the entire block is invalidated and a bus access 52 | error exception is raised. 53 | 54 | .Retrieve Cache Configuration from Software 55 | [TIP] 56 | Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register. 57 | -------------------------------------------------------------------------------- /docs/datasheet/soc_dmem.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | ==== Data Memory (DMEM) 4 | 5 | [cols="<3,<3,<4"] 6 | [grid="none"] 7 | |======================= 8 | | Hardware source files: | neorv32_dmem.vhd | default platform-agnostic data memory 9 | | Software driver files: | none | _implicitly used_ 10 | | Top entity ports: | none | 11 | | Configuration generics: | `DMEM_EN` | implement processor-internal DMEM when `true` 12 | | | `DMEM_SIZE` | DMEM size in bytes (use a power of 2) 13 | | | `DMEM_OUTREG_EN` | add DMEM output register stage 14 | | CPU interrupts: | none | 15 | |======================= 16 | 17 | 18 | **Overview** 19 | 20 | Implementation of the processor-internal data memory is enabled by the processor's `DMEM_EN` 21 | generic. The total memory size in bytes is defined via the `DMEM_SIZE` generic. Note that this 22 | size should be a power of two to optimize physical implementation. If the DMEM is implemented, 23 | it is mapped to base address `0x80000000` by default (see section <<_address_space>>). 24 | The DMEM is always implemented as true RAM. 25 | 26 | .Platform-Specific Memory Primitives 27 | [NOTE] 28 | If required, the default DMEM can be replaced by a platform-/technology-specific primitive to 29 | optimize area utilization, timing and power consumption. 30 | 31 | .Memory Size 32 | [NOTE] 33 | If the configured memory size (via the `DMEM_SIZE` generic) is not a power of two the actual memory 34 | size will be auto-adjusted to the next power of two (e.g. configuring a memory size of 60kB will result in a 35 | physical memory size of 64kB). 36 | 37 | .Output Register Stage 38 | [TIP] 39 | An optional output register stage can be enabled via `DMEM_OUTREG_EN`. For FPGA targets this might improve 40 | mapping/timing results. Note that this option will increase the read latency by one clock cycle. Write accesses 41 | are not affected by this at all. 42 | 43 | .Execute from RAM 44 | [TIP] 45 | The CPU is capable of executing code also from arbitrary data memory. 46 | -------------------------------------------------------------------------------- /docs/datasheet/soc_gptmr.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | ==== General Purpose Timer (GPTMR) 4 | 5 | [cols="<3,<3,<4"] 6 | [grid="none"] 7 | |======================= 8 | | Hardware source files: | neorv32_gptmr.vhd | 9 | | Software driver files: | neorv32_gptmr.c | link:https://stnolting.github.io/neorv32/sw/neorv32__gptmr_8c.html[Online software reference (Doxygen)] 10 | | | neorv32_gptmr.h | link:https://stnolting.github.io/neorv32/sw/neorv32__gptmr_8h.html[Online software reference (Doxygen)] 11 | | Top entity ports: | none | 12 | | Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true` 13 | | CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>) 14 | |======================= 15 | 16 | 17 | **Overview** 18 | 19 | The general purpose timer module implements a simple 32-bit interval timer. It is implemented if the processor's 20 | `IO_GPTMR_EN` top generic is set `true`. The timer provides a pre-scaled counter register that can trigger an interrupt 21 | when reaching a programmable threshold value. 22 | 23 | The GPTMR provides three interface registers : a control register (`CTRL`), a 32-bit counter register (`COUNT`) and a 24 | 32-bit threshold register (`THRES`). The timer is globally enabled by setting the `GPTMR_CTRL_EN` bit in the module's 25 | control register. When the timer is enabled the `COUNT` register will start incrementing from zero at a programmable 26 | rate that scales the main processor clock. this pre-scaler is configured via the three `GPTMR_CTRL_PRSCx` 27 | control register bits: 28 | 29 | .GPTMR prescaler configuration 30 | [cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"] 31 | [options="header",grid="rows"] 32 | |======================= 33 | | **`GPTMR_CTRL_PRSC[2:0]`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111` 34 | | Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096 35 | |======================= 36 | 37 | Whenever the counter register `COUNT` equals the programmable threshold value `THRES` the module's interrupt signal becomes 38 | pending (indicated by `GPTMR_CTRL_IRQ_PND` being set). In this case the `COUNT` register is automatically reset and restarts 39 | incrementing from zero. Note that a pending interrupt has to be cleared manually by writing a `1` to `GPTMR_CTRL_IRQ_CLR`. 40 | 41 | 42 | .Resetting the Counter 43 | [NOTE] 44 | Disabling the GPTMR will also clear the `COUNT` register. 45 | 46 | 47 | **Interrupt** 48 | 49 | The GPTRM provides a single interrupt line is triggered whenever `COUNT` equals `THRES`. Once triggered, the interrupt will 50 | stay pending until explicitly cleared by writing a 1 to `GPTMR_CTRL_IRQ_CLR`. 51 | 52 | 53 | **Register Map** 54 | 55 | .GPTMR register map (`struct NEORV32_GPTMR`) 56 | [cols="<4,<2,<4,^1,<7"] 57 | [options="header",grid="all"] 58 | |======================= 59 | | Address | Name [C] | Bit(s), Name [C] | R/W | Function 60 | .5+<| `0xfff10000` .5+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag 61 | <|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select 62 | <|`29:4` - ^| r/- <| _reserved_, read as zero 63 | <|`30` `GPTMR_CTRL_IRQ_CLR` ^| -/w <| Write `1` to clear timer-match interrupt; auto-clears 64 | <|`31` `GPTMR_CTRL_IRQ_PND` ^| r/- <| Timer-match interrupt pending 65 | | `0xfff10004` | `THRES` |`31:0` | r/w | Threshold value register 66 | | `0xfff10008` | `COUNT` |`31:0` | r/- | Counter register 67 | |======================= 68 | -------------------------------------------------------------------------------- /docs/datasheet/soc_icache.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | <<< 3 | :sectnums: 4 | ==== Processor-Internal Instruction Cache (iCache) 5 | 6 | [cols="<3,<3,<4"] 7 | [grid="none"] 8 | |======================= 9 | | Hardware source files: | neorv32_cache.vhd | Generic cache module 10 | | Software driver files: | none | 11 | | Top entity ports: | none | 12 | | Configuration generics: | `ICACHE_EN` | implement processor-internal, CPU-exclusive instruction cache (I$) when `true` 13 | | | `ICACHE_NUM_BLOCKS` | number of cache blocks ("cache lines"); has to be a power of two 14 | | | `CACHE_BLOCK_SIZE` | size of a cache block in bytes; has to be a power of two (global configuration for I$ and D$) 15 | | CPU interrupts: | none | 16 | |======================= 17 | 18 | 19 | **Overview** 20 | 21 | The processor features an optional CPU instruction cache. The cache is connected directly to the CPU's instruction 22 | fetch interface and provides full-transparent accesses. The cache is direct-mapped and read-only. 23 | The cache uses <<_locked_bus_accesses_and_bursts>> to download cache blocks/lines from main memory. 24 | In the <<_dual_core_configuration>> each CPU core is equipped with a private instruction cache. 25 | 26 | The instruction cache is implemented if `ICACHE_EN` it _true_. The total cache memory size in bytes is defined by 27 | `ICACHE_NUM_BLOCKS x CACHE_BLOCK_SIZE`. `ICACHE_NUM_BLOCKS` defines the number of cache blocks (or "cache lines") 28 | and `CACHE_BLOCK_SIZE` defines the block size in bytes; note that this configuration is global for all caches. 29 | 30 | .Burst Transfers 31 | [IMPORTANT] 32 | If the cache is activated, this also means that cache block transfers are **always executed as burst transfers**. 33 | There is no possibility to execute the cache block transfers as single bus transactions. Therefore, all devices, 34 | memories and endpoints that can be accessed by the cache must also be able to process bursts. 35 | 36 | .Uncached Accesses 37 | [NOTE] 38 | The cache provides direct/uncached accesses to memory (bypassing the cache) in order to access memory-mapped IO (like the 39 | processor-internal IO/peripheral modules). All accesses that target the address range from `0xF0000000` to `0xFFFFFFFF` 40 | will bypass the cache. Hence, access will not be cached. See section <<_address_space>> for more information. Furthermore, 41 | the atomic memory operations of the <<_zaamo_isa_extension>> will always **bypass** the cache. 42 | 43 | .Manual Cache Clear/Reload and Memory Coherence 44 | [NOTE] 45 | By executing the `fence.i` instruction the instruction cache is cleared and reloaded. 46 | See section <<_memory_coherence>> for more information. 47 | 48 | .Cache Block Update Fault Handling 49 | [NOTE] 50 | If the cache encounters a bus error when downloading a new block from main memory, the 51 | entire block is invalidated and a bus access error exception is raised. 52 | 53 | .Retrieve Cache Configuration from Software 54 | [TIP] 55 | Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register. 56 | -------------------------------------------------------------------------------- /docs/datasheet/soc_imem.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | ==== Instruction Memory (IMEM) 4 | 5 | [cols="<3,<3,<4"] 6 | [grid="none"] 7 | |======================= 8 | | Hardware source files: | neorv32_imem.vhd | default platform-agnostic instruction memory (RAM or ROM) 9 | | | neorv32_application_image.vhd | initialization image (a VHDL package) 10 | | Software driver files: | none | _implicitly used_ 11 | | Top entity ports: | none | 12 | | Configuration generics: | `IMEM_EN` | implement processor-internal IMEM when `true` 13 | | | `IMEM_SIZE` | IMEM size in bytes (use a power of 2) 14 | | | `IMEM_OUTREG_EN` | add IMEM output register stage 15 | | | `BOOT_MODE_SELECT` | implement IMEM as ROM when `BOOT_MODE_SELECT` = 2; see <<_boot_configuration>> 16 | | CPU interrupts: | none | 17 | |======================= 18 | 19 | 20 | **Overview** 21 | 22 | Implementation of the processor-internal instruction memory is enabled by the processor's 23 | `IMEM_EN` generic. The total memory size in bytes is defined via the `IMEM_SIZE` generic. 24 | Note that this size should be a power of two to optimize physical implementation. If enabled, 25 | the IMEM is mapped to base address `0x00000000` (see section <<_address_space>>). 26 | 27 | By default the IMEM is implemented as true RAM so the content can be modified during run time. This is 28 | required when using the <<_bootloader>> (or the <<_on_chip_debugger_ocd>>) so it can update the content of the IMEM at 29 | any time. 30 | 31 | Alternatively, the IMEM can be implemented as **pre-initialized read-only memory (ROM)**, so the processor can 32 | directly boot from it after reset. This option is configured via the `BOOT_MODE_SELECT` generic. See section 33 | <<_boot_configuration>> for more information. The initialization image is embedded into the bitstream during synthesis. 34 | The software framework provides an option to generate and override the default VHDL initialization file 35 | `rtl/core/neorv32_application_image.vhd`, which is automatically inserted into the IMEM (see <<_makefile_targets>>. 36 | If the IMEM is implemented as RAM (default), the memory block will not be initialized at all. 37 | 38 | .Platform-Specific Memory Primitives 39 | [NOTE] 40 | If required, the default IMEM can be replaced by a platform-/technology-specific primitive to 41 | optimize area utilization, timing and power consumption. 42 | 43 | .Memory Size 44 | [NOTE] 45 | If the configured memory size (via the `IMEM_SIZE` generic) is not a power of two the actual memory 46 | size will be auto-adjusted to the next power of two (e.g. configuring a memory size of 60kB will result in a 47 | physical memory size of 64kB). 48 | 49 | .Output Register Stage 50 | [TIP] 51 | An optional output register stage can be enabled via `IMEM_OUTREG_EN`. For FPGA targets this might improve 52 | mapping/timing results. Note that this option will increase the read latency by one clock cycle. Write accesses 53 | are not affected by this at all. 54 | 55 | .Read-Only Access 56 | [NOTE] 57 | If the IMEM is implemented as ROM any write attempt to it will raise a _store access fault_ exception. 58 | -------------------------------------------------------------------------------- /docs/doxygen_main.md: -------------------------------------------------------------------------------- 1 | ### NEORV32 Doxygen Reference 2 | 3 | Click on [**Files**](https://stnolting.github.io/neorv32/sw/files.html) to see the documentation 4 | of the software framework. 5 | -------------------------------------------------------------------------------- /docs/figures/.gitignore: -------------------------------------------------------------------------------- 1 | *.pptx 2 | -------------------------------------------------------------------------------- /docs/figures/README.md: -------------------------------------------------------------------------------- 1 | ## :copyright: Image License and Copyright Notifications 2 | 3 | Figures are own work if not otherwise stated; see the 4 | [project's license](https://github.com/stnolting/neorv32/blob/main/LICENSE). 5 | No copyright infringement intended. 6 | 7 | - `riscv_logo.png` and `riscv_logo_small.png` 8 | - source: https://riscv.org/risc-v-logo/ 9 | - license: https://riscv.org/about/risc-v-branding-guidelines/ 10 | 11 | - `neorv32_logo_smcard.jpg` 12 | - source: background image by https://pixabay.com 13 | - license: Pixabay license 14 | -------------------------------------------------------------------------------- /docs/figures/address_space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/address_space.png -------------------------------------------------------------------------------- /docs/figures/eclipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/eclipse.png -------------------------------------------------------------------------------- /docs/figures/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/icon.png -------------------------------------------------------------------------------- /docs/figures/neorv32_bus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_bus.png -------------------------------------------------------------------------------- /docs/figures/neorv32_cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_cpu.png -------------------------------------------------------------------------------- /docs/figures/neorv32_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_logo.png -------------------------------------------------------------------------------- /docs/figures/neorv32_logo_riscv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_logo_riscv.png -------------------------------------------------------------------------------- /docs/figures/neorv32_logo_riscv_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_logo_riscv_small.png -------------------------------------------------------------------------------- /docs/figures/neorv32_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_logo_small.png -------------------------------------------------------------------------------- /docs/figures/neorv32_logo_smcard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_logo_smcard.jpg -------------------------------------------------------------------------------- /docs/figures/neorv32_ocd_complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_ocd_complex.png -------------------------------------------------------------------------------- /docs/figures/neorv32_processor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_processor.png -------------------------------------------------------------------------------- /docs/figures/neorv32_test_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/neorv32_test_setup.png -------------------------------------------------------------------------------- /docs/figures/riscv_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/riscv_logo.png -------------------------------------------------------------------------------- /docs/figures/riscv_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/riscv_logo_small.png -------------------------------------------------------------------------------- /docs/figures/smp_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/smp_system.png -------------------------------------------------------------------------------- /docs/figures/vivado_ip_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/vivado_ip_gui.png -------------------------------------------------------------------------------- /docs/figures/vivado_ip_soc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/figures/vivado_ip_soc.png -------------------------------------------------------------------------------- /docs/neorv32-theme.yml: -------------------------------------------------------------------------------- 1 | extends: default 2 | page: 3 | margin: [0.8in, 0.67in, 0.75in, 0.67in] 4 | link: 5 | font-color: #edac00 6 | base: 7 | text-align: justify 8 | image: 9 | align: center 10 | caption: 11 | align: center 12 | running-content: 13 | start-at: toc 14 | header: 15 | height: 0.65in 16 | vertical-align: bottom 17 | image-vertical-align: bottom 18 | font-size: 11 19 | border-color: #000000 20 | border-width: 1 21 | recto: 22 | left: 23 | content: '*The https://github.com/stnolting/neorv32[NEORV32] RISC-V Processor*' 24 | right: 25 | content: '*Visit on https://github.com/stnolting/neorv32[GitHub]*' 26 | verso: 27 | left: 28 | content: '*The https://github.com/stnolting/neorv32[NEORV32] RISC-V Processor*' 29 | right: 30 | content: '*Visit on https://github.com/stnolting/neorv32[GitHub]*' 31 | footer: 32 | start-at: toc 33 | height: 0.75in 34 | font-size: 10 35 | border-color: #000000 36 | border-width: 1 37 | recto: 38 | left: 39 | content: '{page-number} / {page-count}' 40 | center: 41 | content: 'Copyright by Stephan Nolting. All rights reserved.' 42 | right: 43 | content: '{docdate}' 44 | verso: 45 | left: 46 | content: '{page-number} / {page-count}' 47 | center: 48 | content: 'Version {revnumber}' 49 | right: 50 | content: '{docdate}' 51 | -------------------------------------------------------------------------------- /docs/references/riscv-aclint-1.0-rc4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/references/riscv-aclint-1.0-rc4.pdf -------------------------------------------------------------------------------- /docs/references/riscv-debug-specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/references/riscv-debug-specification.pdf -------------------------------------------------------------------------------- /docs/references/riscv-privileged.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/references/riscv-privileged.pdf -------------------------------------------------------------------------------- /docs/references/riscv-unprivileged.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32/4133cab900fdecb68ee4e1fc63debab55d800052/docs/references/riscv-unprivileged.pdf -------------------------------------------------------------------------------- /docs/userguide/application_program_compilation.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Application Program Compilation 4 | 5 | This guide shows how to compile an example C-code application into a NEORV32 executable that 6 | can be uploaded via the bootloader or the on-chip debugger. 7 | 8 | [start=1] 9 | . Open a terminal console and navigate to one of the project's example programs. For instance, navigate to the 10 | simple `sw/example_demo_blink_led` example program. This program uses the NEORV32 GPIO module to display 11 | an 8-bit counter on the lowest eight bit of the `gpio_o` output port. 12 | . To compile the project and generate an executable simply execute: 13 | 14 | [source,bash] 15 | ---- 16 | neorv32/sw/example/demo_blink_led$ make clean_all exe 17 | ---- 18 | 19 | [start=3] 20 | . The `clean_all` target is used (instead of just `clean`) to ensure everything is re-build. 21 | . The `exe` target will compile and link the application sources together with all the included libraries. 22 | At the end an ELF file (`main.elf`) is generated. The _NEORV32 image generator_ (in `sw/image_gen`) 23 | takes this file and creates the final executable (`neorv32_exe.bin`). The makefile will show the resulting 24 | memory utilization and the executable size: 25 | 26 | [source,bash] 27 | ---- 28 | neorv32/sw/example/demo_blink_led$ make clean_all exe 29 | Memory utilization: 30 | text data bss dec hex filename 31 | 1004 0 0 1004 3ec main.elf 32 | Compiling ../../../sw/image_gen/image_gen 33 | Executable (neorv32_exe.bin) size in bytes: 34 | 1016 35 | ---- 36 | 37 | .Build Artifacts 38 | [NOTE] 39 | All _intermediate_ build artifacts (like object files and binaries) will be places into a (new) project-local 40 | folder named `build`. The _resulting_ build artifacts (like executable, the main ELF and all memory 41 | initialization/image files) will be placed in the root project folder. 42 | 43 | [start=5] 44 | . That's it. The `exe` target has created the actual executable `neorv32_exe.bin` in the current folder 45 | that is ready to be uploaded to the processor using the build-in bootloader. Alternatively, the ELF file can 46 | be uploaded using the on-chip debugger. -------------------------------------------------------------------------------- /docs/userguide/building_the_documentation.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Building the Documentation 4 | 5 | The documentation (datasheet + user guide) is written using `asciidoc`. The according source files 6 | can be found in `docs/...`. The documentation of the software framework is written _in-code_ using `doxygen`. 7 | 8 | A makefiles in the project's `docs` directory is provided to build all of the documentation as HTML pages 9 | or as PDF documents. 10 | 11 | [TIP] 12 | Pre-rendered PDFs are available online as _nightly pre-releases_: https://github.com/stnolting/neorv32/releases. 13 | The HTML-based documentation is also available online at the project's https://stnolting.github.io/neorv32/[GitHub Pages]. 14 | 15 | The makefile provides a help target to show all available build options and their according outputs. 16 | 17 | [source,bash] 18 | ---- 19 | neorv32/docs$ make help 20 | ---- 21 | 22 | .Example: Generate HTML documentation (data sheet) using `asciidoctor` 23 | [source,bash] 24 | ---- 25 | neorv32/docs$ make html 26 | ---- 27 | 28 | [TIP] 29 | If you don't have `asciidoctor` / `asciidoctor-pdf` installed, you can still generate all the documentation using 30 | a _docker container_ via `make container`. 31 | -------------------------------------------------------------------------------- /docs/userguide/content.adoc: -------------------------------------------------------------------------------- 1 | **Let's Get It Started!** 2 | 3 | This user guide uses the NEORV32 project _as is_ from the official `neorv32` repository. 4 | To make your first NEORV32 project run, follow the guides from the upcoming sections. It is recommended to 5 | follow these guides step by step and eventually in the presented order. 6 | 7 | [TIP] 8 | This guide uses the minimalist and platform/toolchain agnostic SoC **test setups** from 9 | `rtl/test_setups` for illustration. You can use one of the provided test setups for 10 | your first FPGA tests. + 11 | + 12 | For more sophisticated example setups have a look at the 13 | https://github.com/stnolting/neorv32-setups[neorv32-setups] repository, 14 | which provides **SoC setups** for various FPGAs, boards and toolchains. 15 | 16 | **Quick Links** 17 | 18 | * <<_software_toolchain_setup, Toolchain>>, <<_general_hardware_setup, hardware>> and <<_general_software_framework_setup, general software framework>> setup 19 | * <<_application_program_compilation, compile>> an application and <<_uploading_and_starting_of_a_binary_executable_image_via_uart, upload>> it or making it 20 | <<_installing_an_executable_directly_into_memory, persistent>> in internal memory 21 | * setup a new <<_setup_of_a_new_application_program_project, application project>> 22 | * <<_application_specific_processor_configuration, optimizing>> the core for your application 23 | * add <<_adding_custom_hardware_modules, custom hardware extensions>> 24 | * <<_using_the_neorv32_bootloader>> 25 | * generate an AMD Vivado <<_packaging_the_processor_as_vivado_ip_block, IP block>> 26 | * <<_simulating_the_processor, simulate>> the processor and <<_building_the_documentation, build the documentation>> 27 | * RTOS support for <<_zephyr_rtos_support, Zephyr>> and <<_freertos_support, FreeRTOS>> 28 | * build SoCs using <<_litex_soc_builder_support, LiteX>> 29 | * run Python code using the <<_micropython_port>> 30 | * in-system <<_debugging_using_the_on_chip_debugger, debugging>> of the whole processor 31 | * <<_neorv32_in_verilog>> - an all-Verilog "version" of the processor 32 | * use the <<_eclipse_ide>> to develop and debug code for the NEORV32 33 | 34 | include::sw_toolchain_setup.adoc[] 35 | 36 | include::general_hw_setup.adoc[] 37 | 38 | include::general_sw_framework_setup.adoc[] 39 | 40 | include::application_program_compilation.adoc[] 41 | 42 | include::executable_upload.adoc[] 43 | 44 | include::installing_an_executable.adoc[] 45 | 46 | include::new_application_project.adoc[] 47 | 48 | include::application_specific_configuration.adoc[] 49 | 50 | include::adding_custom_hw_modules.adoc[] 51 | 52 | include::using_the_neorv32_bootloader.adoc[] 53 | 54 | include::packaging_vivado.adoc[] 55 | 56 | include::simulating_the_processor.adoc[] 57 | 58 | include::building_the_documentation.adoc[] 59 | 60 | include::zephyr_support.adoc[] 61 | 62 | include::free_rtos_support.adoc[] 63 | 64 | include::litex_support.adoc[] 65 | 66 | include::micropython_port.adoc[] 67 | 68 | include::debugging_with_ocd.adoc[] 69 | 70 | include::neorv32_in_verilog.adoc[] 71 | 72 | include::eclipse_ide.adoc[] 73 | 74 | include::../legal.adoc[] 75 | -------------------------------------------------------------------------------- /docs/userguide/free_rtos_support.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == FreeRTOS Support 4 | 5 | A NEORV32-specific port and a simple demo for FreeRTOS (https://github.com/FreeRTOS/FreeRTOS) are 6 | available in a separate repository on GitHub: https://github.com/stnolting/neorv32-freertos 7 | -------------------------------------------------------------------------------- /docs/userguide/index.adoc: -------------------------------------------------------------------------------- 1 | = The NEORV32 RISC-V Processor - User Guide 2 | include::../attrs.adoc[] 3 | :title: [User Guide] The NEORV32 RISC-V Processor 4 | :icons: font 5 | :imagesdir: ../img 6 | :toc: left 7 | :title-logo-image: neorv32_logo_riscv.png[pdfwidth=6.25in,align=center] 8 | :favicon: ../img/icon.png 9 | 10 | image::neorv32_logo.png[align=center,link="https://github.com/stnolting/neorv32"] 11 | 12 | image::riscv_logo.png[width=350,align=center,link="https://riscv.org/"] 13 | 14 | [.text-center] 15 | https://github.com/stnolting/neorv32[image:https://img.shields.io/badge/GitHub-stnolting%2Fneorv32-ffbd00?style=flat-square&logo=github&[title='homepage']] 16 | https://github.com/stnolting/neorv32/blob/main/LICENSE[image:https://img.shields.io/github/license/stnolting/neorv32?longCache=true&style=flat-square[title='license']] 17 | https://github.com/stnolting/neorv32/releases/tag/nightly[image:https://img.shields.io/badge/data%20sheet-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor[title='datasheet (pdf)']] 18 | https://stnolting.github.io/neorv32[image:https://img.shields.io/badge/-HTML-ffbd00?longCache=true&style=flat-square[title='datasheet (html)']] 19 | https://github.com/stnolting/neorv32/releases/tag/nightly[image:https://img.shields.io/badge/user%20guide-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor[title='userguide (pdf)']] 20 | https://stnolting.github.io/neorv32/sw/files.html[image:https://img.shields.io/badge/doxygen-HTML-ffbd00?longCache=true&style=flat-square&logo=Doxygen[title='doxygen']] + 21 | https://github.com/stnolting/neorv32/releases[image:https://img.shields.io/github/v/release/stnolting/neorv32?longCache=true&style=flat-square&logo=GitHub[title='release']] 22 | https://github.com/stnolting/neorv32/releases[image:https://img.shields.io/github/commits-since/stnolting/neorv32/latest?longCache=true&style=flat-square&logo=GitHub[title='release-commits']] 23 | 24 | include::content.adoc[] 25 | -------------------------------------------------------------------------------- /docs/userguide/main.adoc: -------------------------------------------------------------------------------- 1 | = The NEORV32 RISC-V Processor - User Guide 2 | include::../attrs.adoc[] 3 | 4 | 5 | <<< 6 | // #################################################################################################################### 7 | .**Documentation** 8 | [TIP] 9 | The online documentation of the project (the **data sheet**) is available on GitHub-pages: https://stnolting.github.io/neorv32/ 10 | The online documentation of the **software framework** is also available on GitHub-pages: https://stnolting.github.io/neorv32/sw/files.html 11 | 12 | 13 | <<< 14 | // #################################################################################################################### 15 | toc::[] 16 | 17 | include::content.adoc[] 18 | -------------------------------------------------------------------------------- /docs/userguide/micropython_port.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == MicroPython Port 4 | 5 | A simple out-of-tree port of https://github.com/micropython/micropython[MicroPython] 6 | for the NEORV32 RISC-V Processor can be found in a separate repository: 7 | https://github.com/stnolting/neorv32-micropython 8 | 9 | .Work-In-Progress 10 | [NOTE] 11 | This port is still under development. Hence, it supports just some simple modules and 12 | methods yet. However, it is already fully operational. 13 | 14 | .MicroPython REPL Console 15 | [source, python] 16 | ---- 17 | MicroPython v1.25.0 on 2025-04-20; neorv32-default with neorv32 18 | Type "help()" for more information. 19 | >>> help("modules") 20 | __main__ collections machine sys 21 | array gc micropython time 22 | builtins io struct 23 | Plus any modules on the filesystem 24 | ---- 25 | 26 | .Basic build-in Modules 27 | [source, python] 28 | ---- 29 | >>> import machine 30 | >>> machine.info() 31 | NEORV32 version 1.11.2.9 32 | Clock: 150000000 Hz 33 | MISA: 0x40901105 34 | MXISA: 0x66006cd3 35 | SoC: 0x480ba97b 36 | >>> import time 37 | >>> time.localtime() 38 | (2025, 4, 20, 19, 52, 46, 6, 110) 39 | >>> import builtins 40 | >>> builtins.neorv32.help() 41 | neorv32 - helper functions: 42 | gpio_pin_set(pin, level) - Set GPIO.output [pin] to [level] 43 | gpio_pin_toggle(pin) - Toggle GPIO.output [pin] 44 | systick_set_callback(callback) - Call [callback] from SysTICK IRQ 45 | help() - Show this text 46 | ---- 47 | -------------------------------------------------------------------------------- /docs/userguide/neorv32_in_verilog.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == NEORV32 in Verilog 4 | 5 | If you are more of a Verilog fan or if your EDA toolchain does not support VHDL or mixed-language designs 6 | you can use an **all-Verilog** version of the processor provided by the 7 | https://github.com/stnolting/neorv32-verilog[`neorv32-verilog`] repository. 8 | 9 | [IMPORTANT] 10 | Note that this is **not a manual re-implementation of the core in Verilog** but rather an automated conversion. 11 | 12 | GHDL's synthesis feature is used to convert a pre-configured NEORV32 setup - including all peripherals, memories 13 | and memory images - into a single, un-optimized plain-Verilog module file without any (technology-specific) primitives. 14 | 15 | .GHDL Synthesis 16 | [TIP] 17 | More information regarding GHDL's synthesis option can be found at https://ghdl.github.io/ghdl/using/Synthesis.html. 18 | 19 | An intermediate VHDL wrapper is provided that can be used to configure the processor (using VHDL generics) and to 20 | customize the interface ports. After conversion, a single Verilog file is generated that contains the whole NEORV32 21 | processor. The original processor module hierarchy is preserved as well as most (all?) signal names, which allows 22 | easy inspection and debugging of simulation waveforms and synthesis results. 23 | 24 | .Example: interface of the resulting NEORV32 Verilog module (for a minimal SoC configuration) 25 | [source,verilog] 26 | ---- 27 | module neorv32_verilog_wrapper 28 | (input clk_i, 29 | input rstn_i, 30 | input uart0_rxd_i, 31 | output uart0_txd_o); 32 | ---- 33 | 34 | [TIP] 35 | For detailed information check out the `neorv32-verilog` repository at https://github.com/stnolting/neorv32-verilog. 36 | -------------------------------------------------------------------------------- /docs/userguide/new_application_project.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Setup of a New Application Program Project 4 | 5 | [start=1] 6 | . The easiest way of creating a _new_ software application project is to copy an _existing_ one. This will keep all 7 | file dependencies. For example you can copy `sw/example/demo_blink_led` to `sw/example/flux_capacitor`. 8 | . If you want to place you application somewhere outside `sw/example` you need to adapt the application's makefile. 9 | In the makefile you will find a variable that keeps the relative or absolute path to the NEORV32 repository home 10 | folder. Just modify this variable according to your new project's home location: 11 | 12 | [source,makefile] 13 | ---- 14 | # Relative or absolute path to the NEORV32 home folder (use default if not set by user) 15 | NEORV32_HOME ?= ../../.. 16 | ---- 17 | 18 | [start=3] 19 | . If your project contains additional source files outside of the project folder, you can add them to 20 | the `APP_SRC` variable: 21 | 22 | [source,makefile] 23 | ---- 24 | # User's application sources (add additional files here) 25 | APP_SRC = $(wildcard *.c) ../somewhere/some_file.c 26 | ---- 27 | 28 | [start=4] 29 | . You also can add a folder containing your application's include files to the 30 | `APP_INC` variable (do not forget the `-I` prefix): 31 | 32 | [source,makefile] 33 | ---- 34 | # User's application include folders (don't forget the '-I' before each entry) 35 | APP_INC = -I . -I ../somewhere/include_stuff_folder 36 | ---- 37 | -------------------------------------------------------------------------------- /docs/userguide/sw_toolchain_setup.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Software Toolchain Setup 4 | 5 | To compile (and debug) executables for the NEORV32 a RISC-V-compatible toolchain is required. 6 | By default, the project's software framework uses the GNU C Compiler RISC-V port "RISC-V GCC". 7 | Basically, there are two options to obtain such a toolchain: 8 | 9 | 1. Download and _build_ the RISC-V GNU toolchain by yourself. 10 | 2. Download and _install_ a **prebuilt** version of the toolchain. 11 | 12 | .Default GCC Prefix 13 | [NOTE] 14 | The default toolchain prefix for this project is **`riscv-none-elf-`** (`RISCV_PREFIX` variable). 15 | 16 | 17 | **Toolchain Requirements** 18 | 19 | [start=1] 20 | .The toolchain must be able to emit code for a 32-bit architecture (i.e. `mabi=rv32`). 21 | .An _embedded_ C standard library should be used (for example "Newlib"). 22 | 23 | .Library/ISA Considerations 24 | [IMPORTANT] 25 | Note that a toolchain build with `--with-arch=rv32imc` provides library code (like the C standard library) 26 | compiled entirely using compressed (`C`) and `mul`/`div` instructions (`M`). Hence, this pre-compiled library 27 | code CANNOT be executed (without emulation) on an architecture that does not support these ISA extensions. 28 | 29 | 30 | **Building the Toolchain from Scratch** 31 | 32 | The official RISC-V GCC GitHub repository (https://github.com/riscv-collab/riscv-gnu-toolchain) provides instructions 33 | for building the toolchain from scratch: 34 | 35 | .Preparing GCC build for `rv32i` (minimal ISA only in this example) 36 | [source,bash] 37 | ---- 38 | $ git clone https://github.com/riscv/riscv-gnu-toolchain 39 | $ cd riscv-gnu-toolchain 40 | $ riscv-gnu-toolchain$ ./configure --prefix=/opt/riscv --with-arch=rv32i --with-abi=ilp32 41 | $ riscv-gnu-toolchain$ make 42 | ---- 43 | 44 | 45 | **Downloading and Installing a Prebuilt Toolchain** 46 | 47 | Alternatively, a prebuilt toolchain can be used. Some OS package managers provide embedded RISC-V GCC toolchain. 48 | However, I can highly recommend the toolchain provided by the X-Pack project (MIT license): 49 | https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack 50 | 51 | 52 | **Toolchain Installation** 53 | 54 | To integrate the toolchain of choice into the NEORV32 software framework, the toolchain's binaries need 55 | to be added to the system path (e.g. `PATH` environment variable) so they can be used by a shell. Therefore, 56 | the absolute path to the toolchain's `bin` folder has to be appended to the `PATH` variable: 57 | 58 | [source,bash] 59 | ---- 60 | $ export PATH=$PATH:/opt/riscv/bin 61 | ---- 62 | 63 | .bashrc 64 | [TIP] 65 | This command can be added to `.bashrc` (or similar) to automatically add the RISC-V 66 | toolchain at every console start. 67 | 68 | To make sure everything works fine, navigate to an example project in the NEORV32 `sw/example` folder and 69 | execute the following command: 70 | 71 | [source,bash] 72 | ---- 73 | neorv32/sw/example/demo_blink_led$ make check 74 | ---- 75 | 76 | This will test all the tools required for generating NEORV32 executables. 77 | Everything is working fine if "Toolchain check OK" appears at the end of the log output. 78 | -------------------------------------------------------------------------------- /docs/userguide/using_the_neorv32_bootloader.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Using the NEORV32 Bootloader 4 | 5 | .Customization 6 | [NOTE] 7 | This section assumes the _default_ configuration of the NEORV32 bootloader. 8 | See the NEORV32 data sheet's bootloader section for more information. 9 | 10 | 11 | :sectnums: 12 | === Bootloader SPI Flash Requirements 13 | 14 | The bootloader can access an SPI-compatible flash via the processor's top entity SPI port. By default, the flash 15 | chip-select line is driven by `spi_csn_o(0)` and the SPI clock uses 1/8 of the processor's main clock as clock frequency. 16 | The SPI flash has to support single-byte read and write operations, 24-bit addresses and at least the following standard commands: 17 | 18 | * `0x02`: Program page (write byte) 19 | * `0x03`: Read data (byte) 20 | * `0x04`: Write disable (for volatile status register) 21 | * `0x05`: Read (first) status register 22 | * `0x06`: Write enable (for volatile status register) 23 | * `0xAB`: Wake-up from sleep mode (optional) 24 | * `0xD8`: Block erase (64kB) 25 | 26 | .SPI Flash Power Down Mode 27 | [NOTE] 28 | The bootloader will issue a "wake-up" command prior to using the SPI flash to ensure it is not 29 | in sleep mode / power-down mode (see https://github.com/stnolting/neorv32/pull/552). 30 | 31 | 32 | :sectnums: 33 | === Programming an External SPI Flash via the Bootloader 34 | 35 | The default processor-internal NEORV32 bootloader supports automatic booting from an external SPI flash. 36 | This guide shows how to write an executable to the SPI flash via the bootloader so it can be automatically 37 | fetched and executed after processor reset. For example, you can use a section of the FPGA bitstream 38 | configuration memory to store an application executable. 39 | 40 | [start=1] 41 | . At first, reset the NEORV32 processor and wait until the bootloader start screen appears in your terminal program. 42 | . Abort the auto boot sequence and start the user console by pressing any key. 43 | . Press `u` to upload the executable that you want to store to the external flash: 44 | 45 | [source] 46 | ---- 47 | CMD:> u 48 | Awaiting neorv32_exe.bin... 49 | ---- 50 | 51 | [start=4] 52 | . Send the binary in raw binary via your terminal program. When the upload is completed and "OK" 53 | appears, press `s` to trigger the programming of the flash:: 54 | 55 | [source] 56 | ---- 57 | CMD:> u 58 | Awaiting neorv32_exe.bin... OK 59 | CMD:> s 60 | Write 0x00001614 bytes to SPI flash @0x00400000 (y/n)? 61 | ---- 62 | 63 | [start=5] 64 | . The bootloader shows the size of the executable and the base address of the SPI flash where the 65 | executable will be stored. A prompt appears: type `y` to start the programming or type `n` to abort. 66 | 67 | [source] 68 | ---- 69 | CMD:> u 70 | Awaiting neorv32_exe.bin... OK 71 | CMD:> s 72 | Write 0x00001614 bytes to SPI flash @0x00400000 (y/n)? 73 | Flashing... OK 74 | CMD:> 75 | ---- 76 | 77 | [start=6] 78 | . If "OK" appears in the terminal line, the programming process was successful. Now you can use the 79 | auto boot sequence to automatically boot your application from the flash at system start-up without 80 | any user interaction. 81 | -------------------------------------------------------------------------------- /docs/userguide/zephyr_support.adoc: -------------------------------------------------------------------------------- 1 | <<< 2 | :sectnums: 3 | == Zephyr RTOS Support 4 | 5 | The NEORV32 processor is supported by upstream Zephyr RTOS: https://docs.zephyrproject.org/latest/boards/others/neorv32/doc/index.html 6 | 7 | [IMPORTANT] 8 | The absolute path to the NEORV32 executable image generator binary (`.../neorv32/sw/image_gen`) has to be added to the `PATH` variable 9 | so the Zephyr build system can generate executables and memory-initialization images. 10 | 11 | [NOTE] 12 | Zephyr OS port provided by GitHub user https://github.com/henrikbrixandersen[henrikbrixandersen] 13 | (see https://github.com/stnolting/neorv32/discussions/172). 14 | -------------------------------------------------------------------------------- /rtl/README.md: -------------------------------------------------------------------------------- 1 | ## Hardware RTL Sources 2 | 3 | ### > [`core`](core) 4 | 5 | This folder contains the core VHDL files for the NEORV32 CPU and the NEORV32 Processor. 6 | When creating a new synthesis/simulation project make sure to add all `*.vhd` files from this 7 | folder to a **new design library** called `neorv32`. 8 | 9 | > [!TIP] 10 | > Two file-list files (`*.f`) are provided that list all required rtl files for the CPU core and 11 | for the entire processor including their recommended compile order. 12 | See the online documentation for more information: 13 | https://stnolting.github.io/neorv32/#_file_list_files 14 | 15 | ### > [`processor_templates`](processor_templates) 16 | 17 | Contains pre-configured SoC templates that instantiate the processor's top entity from `core`. 18 | These templates can be instantiated directly within a FPGA-specific board wrapper. 19 | 20 | ### > [`system_integration`](system_integration) 21 | 22 | NEORV32 Processor wrappers dedicated for complex system integration: 23 | 24 | * LiteX SoC builder 25 | * Vivado IP integrator providing AXI4-lite and AXI4-stream interfaces 26 | 27 | > [!NOTE] 28 | > These pre-defined top entity wrappers can also be used for custom setups outside of LiteX and Vivado IP designs. 29 | 30 | ### > [`test_setups`](test_setups) 31 | 32 | Minimal processor test setups (FPGA- and board-independent) for checking out NEORV32. 33 | See the folder's README for more information. Note that these test setups are used in the 34 | [NEORV32 User Guide](https://stnolting.github.io/neorv32/ug). 35 | -------------------------------------------------------------------------------- /rtl/core/neorv32_boot_rom.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Bootloader ROM (BOOTROM) -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 5 | -- Copyright (c) NEORV32 contributors. -- 6 | -- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. -- 7 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 8 | -- SPDX-License-Identifier: BSD-3-Clause -- 9 | -- ================================================================================ -- 10 | 11 | library ieee; 12 | use ieee.std_logic_1164.all; 13 | use ieee.numeric_std.all; 14 | 15 | library neorv32; 16 | use neorv32.neorv32_package.all; 17 | use neorv32.neorv32_bootloader_image.all; -- this file is generated by the image generator 18 | 19 | entity neorv32_boot_rom is 20 | port ( 21 | clk_i : in std_ulogic; -- global clock line 22 | rstn_i : in std_ulogic; -- async reset, low-active 23 | bus_req_i : in bus_req_t; -- bus request 24 | bus_rsp_o : out bus_rsp_t -- bus response 25 | ); 26 | end neorv32_boot_rom; 27 | 28 | architecture neorv32_boot_rom_rtl of neorv32_boot_rom is 29 | 30 | -- determine physical ROM size in WORDS (expand to next power of two) -- 31 | constant boot_rom_size_index_c : natural := index_size_f((bootloader_init_size_c/4)); -- address with (words) 32 | constant boot_rom_size_c : natural range 0 to iodev_size_c := (2**boot_rom_size_index_c); -- physical size in words 33 | 34 | -- ROM initialized with executable code -- 35 | constant mem_rom_c : mem32_t(0 to boot_rom_size_c-1) := mem32_init_f(bootloader_init_image_c, boot_rom_size_c); 36 | 37 | -- local signals -- 38 | signal rden : std_ulogic; 39 | signal rdata : std_ulogic_vector(31 downto 0); 40 | 41 | begin 42 | 43 | -- Memory Access -------------------------------------------------------------------------- 44 | -- ------------------------------------------------------------------------------------------- 45 | mem_access: process(clk_i) 46 | begin 47 | if rising_edge(clk_i) then -- no reset to infer block RAM 48 | if (bus_req_i.stb = '1') then -- reduce switching activity when not accessed 49 | rdata <= mem_rom_c(to_integer(unsigned(bus_req_i.addr(boot_rom_size_index_c+1 downto 2)))); 50 | end if; 51 | end if; 52 | end process mem_access; 53 | 54 | 55 | -- Bus Feedback --------------------------------------------------------------------------- 56 | -- ------------------------------------------------------------------------------------------- 57 | bus_feedback: process(rstn_i, clk_i) 58 | begin 59 | if (rstn_i = '0') then 60 | rden <= '0'; 61 | elsif rising_edge(clk_i) then 62 | rden <= bus_req_i.stb and (not bus_req_i.rw); -- read-only 63 | end if; 64 | end process bus_feedback; 65 | 66 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); -- output gate 67 | bus_rsp_o.ack <= rden; 68 | bus_rsp_o.err <= '0'; -- no access error possible 69 | 70 | 71 | end neorv32_boot_rom_rtl; 72 | -------------------------------------------------------------------------------- /rtl/core/neorv32_cpu_cp_cond.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 CPU - Co-Processor: RISC-V Cond. Operations ('Zicond') ISA Extension -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 5 | -- Copyright (c) NEORV32 contributors. -- 6 | -- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. -- 7 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 8 | -- SPDX-License-Identifier: BSD-3-Clause -- 9 | -- ================================================================================ -- 10 | 11 | library ieee; 12 | use ieee.std_logic_1164.all; 13 | 14 | library neorv32; 15 | use neorv32.neorv32_package.all; 16 | 17 | entity neorv32_cpu_cp_cond is 18 | port ( 19 | -- global control -- 20 | clk_i : in std_ulogic; -- global clock, rising edge 21 | rstn_i : in std_ulogic; -- global reset, low-active, async 22 | ctrl_i : in ctrl_bus_t; -- main control bus 23 | -- data input -- 24 | rs1_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 1 25 | rs2_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 2 26 | -- result and status -- 27 | res_o : out std_ulogic_vector(XLEN-1 downto 0); -- operation result 28 | valid_o : out std_ulogic -- data output valid 29 | ); 30 | end neorv32_cpu_cp_cond; 31 | 32 | architecture neorv32_cpu_cp_cond_rtl of neorv32_cpu_cp_cond is 33 | 34 | constant zero_c : std_ulogic_vector(XLEN-1 downto 0) := (others => '0'); 35 | signal valid_cmd, rs2_zero, condition : std_ulogic; 36 | 37 | begin 38 | 39 | -- Valid Instruction? --------------------------------------------------------------------- 40 | -- ------------------------------------------------------------------------------------------- 41 | valid_cmd <= '1' when (ctrl_i.alu_cp_alu = '1') and (ctrl_i.ir_opcode(5) = '1') and 42 | (ctrl_i.ir_funct3(2) = '1') and (ctrl_i.ir_funct3(0) = '1') and 43 | (ctrl_i.ir_funct12(11 downto 5) = "0000111") else '0'; 44 | 45 | 46 | -- Conditional Output --------------------------------------------------------------------- 47 | -- ------------------------------------------------------------------------------------------- 48 | cond_out: process(rstn_i, clk_i) 49 | begin 50 | if (rstn_i = '0') then 51 | res_o <= (others => '0'); 52 | elsif rising_edge(clk_i) then 53 | if (valid_cmd = '1') and (condition = '1') then -- unit triggered and condition true 54 | res_o <= rs1_i; 55 | else 56 | res_o <= (others => '0'); 57 | end if; 58 | end if; 59 | end process cond_out; 60 | 61 | -- condition check -- 62 | rs2_zero <= '1' when (rs2_i = zero_c) else '0'; 63 | condition <= rs2_zero xnor ctrl_i.ir_funct3(1); -- equal zero / non equal zero 64 | 65 | -- processing done -- 66 | valid_o <= valid_cmd; 67 | 68 | 69 | end neorv32_cpu_cp_cond_rtl; 70 | -------------------------------------------------------------------------------- /rtl/core/neorv32_debug_auth.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 OCD - RISC-V-Compatible Authentication Module for the On-Chip Debugger -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- Note that this module (in its default state) just provides a very simple and -- 5 | -- UNSECURE authentication mechanism that is meant as an example to showcase the -- 6 | -- interface. Users should replace this module to implement a custom (and SECURE) -- 7 | -- authentication mechanism. -- 8 | -- -------------------------------------------------------------------------------- -- 9 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 10 | -- Copyright (c) NEORV32 contributors. -- 11 | -- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. -- 12 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 13 | -- SPDX-License-Identifier: BSD-3-Clause -- 14 | -- ================================================================================ -- 15 | 16 | library ieee; 17 | use ieee.std_logic_1164.all; 18 | 19 | entity neorv32_debug_auth is 20 | port ( 21 | -- global control -- 22 | clk_i : in std_ulogic; -- global clock 23 | rstn_i : in std_ulogic; -- global reset, low-active, asynchronous 24 | -- register interface -- 25 | we_i : in std_ulogic; -- wdata_i valid when high 26 | re_i : in std_ulogic; -- rdata_o has been consumed by the debugger when high 27 | wdata_i : in std_ulogic_vector(31 downto 0); -- write data (from debugger) 28 | rdata_o : out std_ulogic_vector(31 downto 0); -- read data (to debugger) 29 | -- status -- 30 | enable_i : in std_ulogic; -- authenticator enabled when high; reset & clear authentication when low 31 | busy_o : out std_ulogic; -- authenticator is busy when high; no further read/write accesses 32 | valid_o : out std_ulogic -- high when authentication passed; unlocks the on-chip debugger 33 | ); 34 | end neorv32_debug_auth; 35 | 36 | architecture neorv32_debug_auth_rtl of neorv32_debug_auth is 37 | 38 | signal authenticated_q : std_ulogic; 39 | 40 | begin 41 | 42 | -- Warn about Default Authenticator ------------------------------------------------------- 43 | -- ------------------------------------------------------------------------------------------- 44 | assert false report "[NEORV32] using DEFAULT on-chip debugger authenticator. Replace by custom module." severity warning; 45 | 46 | 47 | -- Exemplary Authentication Mechanism ----------------------------------------------------- 48 | -- ------------------------------------------------------------------------------------------- 49 | dm_controller: process(rstn_i, clk_i) 50 | begin 51 | if (rstn_i = '0') then 52 | authenticated_q <= '0'; 53 | elsif rising_edge(clk_i) then 54 | if (enable_i = '0') then 55 | authenticated_q <= '0'; -- clear authentication when disabled 56 | elsif (we_i = '1') then 57 | authenticated_q <= wdata_i(0); -- just write a "1" to authenticate 58 | end if; 59 | end if; 60 | end process dm_controller; 61 | 62 | -- authenticator busy -- 63 | busy_o <= '0'; -- this simple authenticator is always ready 64 | 65 | -- authentication passed -- 66 | valid_o <= authenticated_q; 67 | 68 | -- read data -- 69 | rdata_o <= (others => '0'); -- there is nothing to read here 70 | 71 | 72 | end neorv32_debug_auth_rtl; 73 | -------------------------------------------------------------------------------- /rtl/file_list_cpu.f: -------------------------------------------------------------------------------- 1 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_package.vhd 2 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_fifo.vhd 3 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_decompressor.vhd 4 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_frontend.vhd 5 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_control.vhd 6 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_counters.vhd 7 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_regfile.vhd 8 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_shifter.vhd 9 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_muldiv.vhd 10 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_bitmanip.vhd 11 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_fpu.vhd 12 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_cfu.vhd 13 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_cond.vhd 14 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_crypto.vhd 15 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_alu.vhd 16 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_lsu.vhd 17 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_pmp.vhd 18 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu.vhd 19 | -------------------------------------------------------------------------------- /rtl/file_list_soc.f: -------------------------------------------------------------------------------- 1 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_package.vhd 2 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_sys.vhd 3 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_fifo.vhd 4 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_decompressor.vhd 5 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_frontend.vhd 6 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_control.vhd 7 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_counters.vhd 8 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_regfile.vhd 9 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_shifter.vhd 10 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_muldiv.vhd 11 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_bitmanip.vhd 12 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_fpu.vhd 13 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_cfu.vhd 14 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_cond.vhd 15 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_cp_crypto.vhd 16 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_alu.vhd 17 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_lsu.vhd 18 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_pmp.vhd 19 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu.vhd 20 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cache.vhd 21 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_bus.vhd 22 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_dma.vhd 23 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_application_image.vhd 24 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_imem.vhd 25 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_dmem.vhd 26 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_xbus.vhd 27 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_bootloader_image.vhd 28 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_boot_rom.vhd 29 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cfs.vhd 30 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_sdi.vhd 31 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_gpio.vhd 32 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_wdt.vhd 33 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_clint.vhd 34 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_uart.vhd 35 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_spi.vhd 36 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_twi.vhd 37 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_twd.vhd 38 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_pwm.vhd 39 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_trng.vhd 40 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_neoled.vhd 41 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_gptmr.vhd 42 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_onewire.vhd 43 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_slink.vhd 44 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_sysinfo.vhd 45 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_debug_dtm.vhd 46 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_debug_auth.vhd 47 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_debug_dm.vhd 48 | NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_top.vhd 49 | -------------------------------------------------------------------------------- /rtl/generate_file_lists.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Generate file-list files for the CPU and the entire processor/SoC 4 | # using GHDL's elaborate option. 5 | 6 | set -e 7 | cd $(dirname "$0") 8 | 9 | # top entities 10 | CPU_TOP=neorv32_cpu 11 | SOC_TOP=neorv32_top 12 | 13 | # file-list files 14 | CPU_LIST=file_list_cpu.f 15 | SOC_LIST=file_list_soc.f 16 | 17 | # rtl path placeholder 18 | PLACEHOLDER="NEORV32_RTL_PATH_PLACEHOLDER" 19 | 20 | # temporary GHDL project 21 | mkdir -p ~build 22 | ghdl -i --work=neorv32 --workdir=~build core/*.vhd 23 | 24 | # CPU core only 25 | echo "Regenerating $CPU_LIST ..." 26 | ghdl --elab-order --work=neorv32 --workdir=~build $CPU_TOP > ~$CPU_LIST 27 | while IFS= read -r line; do 28 | echo "$PLACEHOLDER/$line" 29 | done < ~$CPU_LIST > $CPU_LIST 30 | 31 | # full processor/SoC 32 | echo "Regenerating $SOC_LIST ..." 33 | ghdl --elab-order --work=neorv32 --workdir=~build $SOC_TOP > ~$SOC_LIST 34 | while IFS= read -r line; do 35 | echo "$PLACEHOLDER/$line" 36 | done < ~$SOC_LIST > $SOC_LIST 37 | 38 | # clean-up temporaries 39 | rm -rf ~build ~$CPU_LIST ~$SOC_LIST 40 | -------------------------------------------------------------------------------- /rtl/processor_templates/README.md: -------------------------------------------------------------------------------- 1 | # SoC/Processor Templates 2 | 3 | This folder provides exemplary templates that wrap the processor top entity and provide a simplified 4 | set of configuration generics and IOs. These setups are intended to allow beginner an easy start by 5 | hiding much of the processor's configuration complexity. Furthermore, these setups are used by many 6 | of the provided [example setups](https://github.com/stnolting/neorv32-setups). 7 | 8 | Alternatively, you can directly instantiate the processor's top entity 9 | [`rtl/core/neorv32_top.vhd`](https://github.com/stnolting/neorv32/blob/main/rtl/core/neorv32_top.vhd) 10 | to have full access to _all_ features. 11 | 12 | ### > `neorv32_ProcessorTop_Minimal.vhd` 13 | 14 | This setup used the ["Direct Boot Configuration"](https://stnolting.github.io/neorv32/#_boot_configuration). 15 | Application software is installed directly into the processor-internal instruction memory (IMEM) during 16 | synthesis. This memory is implemented as ROM and these is no bootloader available. Hence, the executable 17 | remains unchangeable is executed right after reset. 18 | 19 | The setup only provides 3 PWM channels as IO. 20 | 21 | ### > `neorv32_ProcessorTop_MinimalBoot.vhd` 22 | 23 | This setup used the ["Indirect Boot Configuration"](https://stnolting.github.io/neorv32/#_boot_configuration). 24 | The NEORV32 bootloader is enabled in this setup allowing to upload new application software at any time 25 | via a UART connection. 26 | 27 | The setup provides 8 GPIO outputs and the UART communication lines as IO. 28 | 29 | ### > `neorv32_ProcessorTop_UP5KDemo.vhd` 30 | 31 | This is a more complex template that implements a small microcontroller-like NEORV32. 32 | It was originally designed for _UPDuino V3_ board, which features a Lattice iCE40up5k FPGA, but has 33 | also been ported to other boards that provide the same FPGA. 34 | -------------------------------------------------------------------------------- /rtl/system_integration/.gitignore: -------------------------------------------------------------------------------- 1 | neorv32_vivado_ip_work/* 2 | .Xil/* 3 | -------------------------------------------------------------------------------- /rtl/system_integration/README.md: -------------------------------------------------------------------------------- 1 | ## Processor System Integration 2 | 3 | ### > `neorv32_litex_core_complex.vhd` 4 | 5 | Pre-configured top entity wrapper for integration within the [LiteX](https://github.com/enjoy-digital/litex) 6 | SoC builder framework. This wrapper provides AXI4 and AXI4-Stream-compatible interfaces. 7 | 8 | > [!TIP] 9 | > See the user guide section [`core/mem`](https://stnolting.github.io/neorv32/ug/#_litex_soc_builder_support) 10 | for more information. 11 | 12 | > [!NOTE] 13 | > The provided top entity wrapper can also be used for custom (AXI) setups outside of Vivado IP block designs. 14 | 15 | 16 | ### > `neorv32_vivado_ip.vhd` 17 | 18 | Processor top entity with optional AXI4 and AXI4-Stream interfaces. Dedicated for integration as custom 19 | IP block within AMD Vivado. Run the provided packaging script in the Vivado TCL shell to generate a NEORV32 20 | IP block: 21 | 22 | ```tcl 23 | source neorv32_vivado_ip.tcl 24 | ``` 25 | 26 | This wrapper uses the `xbus2axi4_bridge.vhd` to convert the processor's XBUS protocol into the AXI4 protocol. 27 | 28 | > [!TIP] 29 | > See the user guide's [UG: Packaging the Processor as Vivado IP Block](https://stnolting.github.io/neorv32/ug/#_packaging_the_processor_as_vivado_ip_block) 30 | section for more information and step-by-step instructions for generating a NEORV32 IP module. 31 | -------------------------------------------------------------------------------- /rtl/test_setups/neorv32_test_setup_approm.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 - Test Setup Using The Internal IMEM To Run Pre-Installed Executables -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 5 | -- Copyright (c) NEORV32 contributors. -- 6 | -- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. -- 7 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 8 | -- SPDX-License-Identifier: BSD-3-Clause -- 9 | -- ================================================================================ -- 10 | 11 | library ieee; 12 | use ieee.std_logic_1164.all; 13 | use ieee.numeric_std.all; 14 | 15 | library neorv32; 16 | use neorv32.neorv32_package.all; 17 | 18 | entity neorv32_test_setup_approm is 19 | generic ( 20 | -- adapt these for your setup -- 21 | CLOCK_FREQUENCY : natural := 100000000; -- clock frequency of clk_i in Hz 22 | IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes 23 | DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes 24 | ); 25 | port ( 26 | -- Global control -- 27 | clk_i : in std_ulogic; -- global clock, rising edge 28 | rstn_i : in std_ulogic; -- global reset, low-active, async 29 | -- GPIO -- 30 | gpio_o : out std_ulogic_vector(7 downto 0) -- parallel output 31 | ); 32 | end entity; 33 | 34 | architecture neorv32_test_setup_approm_rtl of neorv32_test_setup_approm is 35 | 36 | signal con_gpio_out : std_ulogic_vector(31 downto 0); 37 | 38 | begin 39 | 40 | -- The Core Of The Problem ---------------------------------------------------------------- 41 | -- ------------------------------------------------------------------------------------------- 42 | neorv32_top_inst: neorv32_top 43 | generic map ( 44 | -- Clocking -- 45 | CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz 46 | -- Boot Configuration -- 47 | BOOT_MODE_SELECT => 2, -- boot from pre-initialized IMEM 48 | -- RISC-V CPU Extensions -- 49 | RISCV_ISA_C => true, -- implement compressed extension? 50 | RISCV_ISA_M => true, -- implement mul/div extension? 51 | RISCV_ISA_Zicntr => true, -- implement base counters? 52 | -- Internal Instruction memory -- 53 | IMEM_EN => true, -- implement processor-internal instruction memory 54 | IMEM_SIZE => IMEM_SIZE, -- size of processor-internal instruction memory in bytes 55 | -- Internal Data memory -- 56 | DMEM_EN => true, -- implement processor-internal data memory 57 | DMEM_SIZE => DMEM_SIZE, -- size of processor-internal data memory in bytes 58 | -- Processor peripherals -- 59 | IO_GPIO_NUM => 8, -- number of GPIO input/output pairs (0..32) 60 | IO_CLINT_EN => true -- implement core local interruptor (CLINT)? 61 | ) 62 | port map ( 63 | -- Global control -- 64 | clk_i => clk_i, -- global clock, rising edge 65 | rstn_i => rstn_i, -- global reset, low-active, async 66 | -- GPIO (available if IO_GPIO_NUM > 0) -- 67 | gpio_o => con_gpio_out -- parallel output 68 | ); 69 | 70 | -- GPIO output -- 71 | gpio_o <= con_gpio_out(7 downto 0); 72 | 73 | 74 | end architecture; 75 | -------------------------------------------------------------------------------- /sim/ghdl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd $(dirname "$0") 6 | GHDL="${GHDL:-ghdl}" 7 | 8 | # Prepare UART SIM_MODE output files 9 | touch neorv32.uart0_sim_mode.out neorv32.uart1_sim_mode.out 10 | chmod 777 neorv32.uart0_sim_mode.out neorv32.uart1_sim_mode.out 11 | 12 | # Prepare testbench UART log files 13 | touch neorv32_tb.uart0_rx.out neorv32_tb.uart1_rx.out 14 | chmod 777 neorv32_tb.uart0_rx.out neorv32_tb.uart1_rx.out 15 | 16 | # GHDL build directory 17 | mkdir -p build 18 | 19 | # GHDL import 20 | find ../rtl/core ../sim -type f -name '*.vhd' -exec \ 21 | ghdl -i --std=08 --workdir=build --ieee=standard --work=neorv32 {} \; 22 | 23 | # GHDL analyze 24 | $GHDL -m --work=neorv32 --workdir=build --std=08 neorv32_tb 25 | 26 | # GHDL run parameters 27 | if [ -z "$1" ] 28 | then 29 | GHDL_RUN_ARGS="${@:---stop-time=10ms}" 30 | else 31 | # Let's pass down all the parameters to GHDL 32 | GHDL_RUN_ARGS=$@ 33 | fi 34 | echo "GHDL simulation run parameters: $GHDL_RUN_ARGS"; 35 | 36 | # GHDL run 37 | runcmd="$GHDL -r --work=neorv32 --workdir=build --std=08 neorv32_tb \ 38 | --max-stack-alloc=0 \ 39 | --ieee-asserts=disable \ 40 | --assert-level=error $GHDL_RUN_ARGS" 41 | 42 | if [ -n "$GHDL_DEVNULL" ]; then 43 | $runcmd >> /dev/null 44 | else 45 | $runcmd 46 | fi 47 | -------------------------------------------------------------------------------- /sim/sim_uart_rx.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 - Simulation UART Receiver (print to simulator console) -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 5 | -- Copyright (c) NEORV32 contributors. -- 6 | -- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. -- 7 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 8 | -- SPDX-License-Identifier: BSD-3-Clause -- 9 | -- ================================================================================ -- 10 | 11 | library ieee; 12 | use ieee.std_logic_1164.all; 13 | use ieee.numeric_std.all; 14 | use ieee.math_real.all; 15 | use std.textio.all; 16 | 17 | entity sim_uart_rx is 18 | generic ( 19 | NAME : string; -- receiver name (for log file) 20 | FCLK : real; -- clock speed of clk_i in Hz 21 | BAUD : real -- baud rate 22 | ); 23 | port ( 24 | clk : in std_ulogic; -- global clock 25 | rxd : in std_ulogic -- serial UART RX data 26 | ); 27 | end entity sim_uart_rx; 28 | 29 | architecture sim_uart_rx_rtl of sim_uart_rx is 30 | 31 | signal sync : std_ulogic_vector(4 downto 0) := (others => '1'); 32 | signal busy : std_ulogic := '0'; 33 | signal sreg : std_ulogic_vector(8 downto 0) := (others => '0'); 34 | signal baudcnt : real; 35 | signal bitcnt : natural; 36 | constant baud_val_c : real := FCLK / BAUD; 37 | file file_out : text open write_mode is "neorv32_tb." & NAME & "_rx.out"; 38 | 39 | begin 40 | 41 | sim_receiver: process(clk) 42 | variable c : integer; 43 | variable l : line; 44 | begin 45 | if rising_edge(clk) then 46 | -- synchronizer -- 47 | sync <= sync(3 downto 0) & rxd; 48 | -- arbiter -- 49 | if (busy = '0') then -- idle 50 | busy <= '0'; 51 | baudcnt <= round(0.5 * baud_val_c); 52 | bitcnt <= 9; 53 | if (sync(4 downto 1) = "1100") then -- start bit (falling edge) 54 | busy <= '1'; 55 | end if; 56 | else -- receiving 57 | 58 | if (baudcnt <= 0.0) then 59 | if (bitcnt = 1) then 60 | baudcnt <= round(0.5 * baud_val_c); 61 | else 62 | baudcnt <= round(baud_val_c); 63 | end if; 64 | 65 | if (bitcnt = 0) then 66 | busy <= '0'; -- done 67 | c := to_integer(unsigned(sreg(8 downto 1))); 68 | 69 | if (c < 32) or (c > 32+95) then -- non-printable character? 70 | report NAME & ".rx: (" & integer'image(c) & ")"; 71 | else 72 | report NAME & ".rx: " & character'val(c); 73 | end if; 74 | 75 | if (c = 10) then -- LF line break 76 | writeline(file_out, l); 77 | elsif (c /= 13) then -- no additional CR 78 | write(l, character'val(c)); 79 | end if; 80 | 81 | else 82 | sreg <= sync(4) & sreg(8 downto 1); 83 | bitcnt <= bitcnt - 1; 84 | end if; 85 | 86 | else 87 | baudcnt <= baudcnt - 1.0; 88 | end if; 89 | end if; 90 | end if; 91 | end process sim_receiver; 92 | 93 | end architecture sim_uart_rx_rtl; 94 | -------------------------------------------------------------------------------- /sw/README.md: -------------------------------------------------------------------------------- 1 | ## Software Framework 2 | 3 | This folder provides the core, hardware abstraction layer, drivers, etc. of the NEORV32 software framework. 4 | 5 | ### > [`bootloader`](bootloader) 6 | 7 | Source(s) of the default NEORV32 bootloader. 8 | A pre-built image is already installed into the rtl design via the `rtl/core/neorv32_bootloader_image.vhd` file. 9 | 10 | ### > [`common`](common) 11 | 12 | NEORV32-specific common files for all bootloader and application programs: 13 | linker script for executable generation and processor start-up code. 14 | 15 | ### > [`example`](example) 16 | Several example programs for testing and for getting started. 17 | 18 | ### > [`image_gen`](image_gen) 19 | 20 | This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL 21 | memory initialization files (for memory-persistent applications and for the bootloader). 22 | This program is automatically compiled using the native GCC when invoking one of the application compilation makefiles. 23 | 24 | ### > [`lib`](lib) 25 | 26 | Core libraries (sources and header files) and helper functions for using the processor peripherals and the CPU itself. 27 | 28 | ### > [`ocd-firmware`](ocd-firmware) 29 | 30 | Firmware (debugger "park loop") for the on-chip debugger. This folder is just for documenting the source code. 31 | Modifying the sources is not recommended as this could break the on-chip debugger. 32 | 33 | ### > [`openocd`](openocd) 34 | 35 | Configuration file for openOCD to connect to the NEORV32 on-chip debugger via JTAG. 36 | 37 | ### > [`svd`](svd) 38 | 39 | Contains a CMSIS-SVD compatible system view description file including _all_ peripherals. 40 | -------------------------------------------------------------------------------- /sw/bootloader/README.md: -------------------------------------------------------------------------------- 1 | ## NEORV32 Bootloader 2 | 3 | Use the `config.h` file to customize the bootloader configuration. 4 | Recompile and re-install the bootloader ROM image via `make bootloader`. 5 | 6 | #### Documentation 7 | 8 | * [Data Sheet: NEORV32 Bootloader](https://stnolting.github.io/neorv32/#_bootloader) 9 | * [User Guide: Customizing the internal bootloader](https://stnolting.github.io/neorv32/ug/#_customizing_the_internal_bootloader) 10 | * [User Guide: Programming an external SPI flash via the bootloader](https://stnolting.github.io/neorv32/ug/#_programming_an_external_spi_flash_via_the_bootloader) 11 | -------------------------------------------------------------------------------- /sw/bootloader/hal/include/spi_flash.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file spi_flash.h 11 | * @brief SPI flash driver. 12 | */ 13 | 14 | #ifndef SPI_FLASH_H 15 | #define SPI_FLASH_H 16 | 17 | #include 18 | 19 | int spi_flash_check(void); 20 | int spi_flash_read_word(uint32_t addr, uint32_t* rdata); 21 | int spi_flash_write_word(uint32_t addr, uint32_t wdata); 22 | int spi_flash_erase_sector(uint32_t addr); 23 | 24 | #endif // SPI_FLASH_H 25 | -------------------------------------------------------------------------------- /sw/bootloader/hal/include/twi_flash.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file twi_flash.h 11 | * @brief TWI flash driver. 12 | */ 13 | 14 | #ifndef TWI_FLASH_H 15 | #define TWI_FLASH_H 16 | 17 | #include 18 | 19 | int twi_flash_check(void); 20 | int twi_flash_read_word(uint32_t addr, uint32_t* rdata); 21 | int twi_flash_write_word(uint32_t addr, uint32_t wdata); 22 | void twi_flash_delay_twi_tick(int tick_count); 23 | 24 | #endif // TWI_FLASH_H 25 | -------------------------------------------------------------------------------- /sw/bootloader/hal/include/uart.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file uart.h 11 | * @brief Minimal UART0 driver. 12 | */ 13 | 14 | #ifndef UART_H 15 | #define UART_H 16 | 17 | #include 18 | 19 | char uart_getc(void); 20 | void uart_putc(char c); 21 | void uart_puts(const char *s); 22 | void uart_puth(uint32_t num); 23 | int uart_getw(uint32_t* rdata); 24 | 25 | #endif // UART_H 26 | -------------------------------------------------------------------------------- /sw/bootloader/hal/source/uart.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file uart.c 11 | * @brief Minimal UART0 driver. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | 20 | /**********************************************************************//** 21 | * Read single char from UART0. 22 | * 23 | * @return Received char. 24 | **************************************************************************/ 25 | char uart_getc(void) { 26 | 27 | #if (UART_EN != 0) 28 | if (neorv32_uart_available(NEORV32_UART0)) { 29 | return neorv32_uart_getc(NEORV32_UART0); 30 | } 31 | #endif 32 | return 0; 33 | } 34 | 35 | 36 | /**********************************************************************//** 37 | * Print single char via UART0. 38 | * 39 | * @note Converts LF ("\n") to CR+LF ("\r\n"). 40 | * 41 | * @param[in] c Character to print. 42 | **************************************************************************/ 43 | void uart_putc(char c) { 44 | 45 | #if (UART_EN != 0) 46 | if (neorv32_uart_available(NEORV32_UART0)) { 47 | if (c == '\n') { 48 | neorv32_uart_putc(NEORV32_UART0, '\r'); 49 | } 50 | neorv32_uart_putc(NEORV32_UART0, c); 51 | } 52 | #endif 53 | } 54 | 55 | 56 | /**********************************************************************//** 57 | * Print zero-terminated string via UART0. 58 | * 59 | * @param[in] s Pointer to string. 60 | **************************************************************************/ 61 | void uart_puts(const char *s) { 62 | 63 | #if (UART_EN != 0) 64 | char c = 0; 65 | while ((c = *s++)) { 66 | uart_putc(c); 67 | } 68 | #endif 69 | } 70 | 71 | 72 | /**********************************************************************//** 73 | * Print 32-bit number as 8-digit hexadecimal value with "0x" suffix via UART0. 74 | * 75 | * @param[in] num Number to print as hexadecimal. 76 | **************************************************************************/ 77 | void uart_puth(uint32_t num) { 78 | 79 | #if (UART_EN != 0) 80 | static const char hex_symbols[16] = "0123456789abcdef"; 81 | uart_putc('0'); 82 | uart_putc('x'); 83 | 84 | int i; 85 | for (i=28; i>=0; i-=4) { 86 | uart_putc(hex_symbols[(num >> i) & 0xf]); 87 | } 88 | #endif 89 | } 90 | 91 | 92 | /**********************************************************************//** 93 | * Read 32-bit binary word from UART0. 94 | * 95 | * @param[in,out] rdata Pointer for returned data (uint32_t). 96 | * @return 0 if success, != 0 if error 97 | **************************************************************************/ 98 | int uart_getw(uint32_t* rdata) { 99 | 100 | #if (UART_EN != 0) 101 | int i; 102 | subwords32_t tmp; 103 | for (i=0; i<4; i++) { 104 | tmp.uint8[i] = (uint8_t)uart_getc(); 105 | } 106 | *rdata = tmp.uint32; 107 | return 0; 108 | #else 109 | return 1; 110 | #endif 111 | } 112 | -------------------------------------------------------------------------------- /sw/bootloader/makefile: -------------------------------------------------------------------------------- 1 | # Bootloader (for BOOTROM) makefile. 2 | 3 | # Minimal RISC-V ISA (E!) only 4 | MARCH = rv32e_zicsr_zifencei 5 | MABI = ilp32e 6 | 7 | # Optimize for minimal size 8 | EFFORT = -Os 9 | 10 | # Hardware abstraction layer 11 | APP_SRC += $(wildcard ./*.c) $(wildcard ./hal/source/*.c) 12 | APP_INC += -I . -I ./hal/include 13 | 14 | # Adjust "rom" memory size and base for BOOTROM 15 | # Just use a minimal "ram" size that should be available on any platform configuration 16 | # Define MAKE_BOOTLOADER for SW library optimizations (reduces footprint) and enable link-time-optimization 17 | USER_FLAGS += \ 18 | -Wl,--defsym,__neorv32_rom_size=4k \ 19 | -Wl,--defsym,__neorv32_rom_base=0xFFE00000 \ 20 | -Wl,--defsym,__neorv32_ram_size=256 \ 21 | -DMAKE_BOOTLOADER \ 22 | -flto 23 | 24 | # Include the main NEORV32 makefile 25 | NEORV32_HOME ?= ../.. 26 | include $(NEORV32_HOME)/sw/common/common.mk 27 | -------------------------------------------------------------------------------- /sw/example/bus_explorer/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/coremark/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32imc_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -O3 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += \ 18 | -Wl,--defsym,__neorv32_rom_size=64k \ 19 | -Wl,--defsym,__neorv32_rom_base=0x00000000 20 | 21 | # Adjust processor DMEM size 22 | USER_FLAGS += \ 23 | -Wl,--defsym,__neorv32_ram_size=16k \ 24 | -Wl,--defsym,__neorv32_ram_base=0x80000000 25 | 26 | # Adjust maximum heap size 27 | ##USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=8k 28 | 29 | # Additional sources 30 | APP_SRC += $(wildcard source/*.c) 31 | APP_INC += -I include 32 | 33 | # Set path to NEORV32 root directory 34 | NEORV32_HOME ?= ../../.. 35 | 36 | # Include the main NEORV32 makefile 37 | include $(NEORV32_HOME)/sw/common/common.mk 38 | -------------------------------------------------------------------------------- /sw/example/coremark/source/cvt.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | #include 17 | #define CVTBUFSIZE 80 18 | static char CVTBUF[CVTBUFSIZE]; 19 | 20 | static char * 21 | cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag) 22 | { 23 | int r2; 24 | double fi, fj; 25 | char * p, *p1; 26 | 27 | if (ndigits < 0) 28 | ndigits = 0; 29 | if (ndigits >= CVTBUFSIZE - 1) 30 | ndigits = CVTBUFSIZE - 2; 31 | r2 = 0; 32 | *sign = 0; 33 | p = &buf[0]; 34 | if (arg < 0) 35 | { 36 | *sign = 1; 37 | arg = -arg; 38 | } 39 | arg = modf(arg, &fi); 40 | p1 = &buf[CVTBUFSIZE]; 41 | 42 | if (fi != 0) 43 | { 44 | p1 = &buf[CVTBUFSIZE]; 45 | while (fi != 0) 46 | { 47 | fj = modf(fi / 10, &fi); 48 | *--p1 = (int)((fj + .03) * 10) + '0'; 49 | r2++; 50 | } 51 | while (p1 < &buf[CVTBUFSIZE]) 52 | *p++ = *p1++; 53 | } 54 | else if (arg > 0) 55 | { 56 | while ((fj = arg * 10) < 1) 57 | { 58 | arg = fj; 59 | r2--; 60 | } 61 | } 62 | p1 = &buf[ndigits]; 63 | if (eflag == 0) 64 | p1 += r2; 65 | *decpt = r2; 66 | if (p1 < &buf[0]) 67 | { 68 | buf[0] = '\0'; 69 | return buf; 70 | } 71 | while (p <= p1 && p < &buf[CVTBUFSIZE]) 72 | { 73 | arg *= 10; 74 | arg = modf(arg, &fj); 75 | *p++ = (int)fj + '0'; 76 | } 77 | if (p1 >= &buf[CVTBUFSIZE]) 78 | { 79 | buf[CVTBUFSIZE - 1] = '\0'; 80 | return buf; 81 | } 82 | p = p1; 83 | *p1 += 5; 84 | while (*p1 > '9') 85 | { 86 | *p1 = '0'; 87 | if (p1 > buf) 88 | ++*--p1; 89 | else 90 | { 91 | *p1 = '1'; 92 | (*decpt)++; 93 | if (eflag == 0) 94 | { 95 | if (p > buf) 96 | *p = '0'; 97 | p++; 98 | } 99 | } 100 | } 101 | *p = '\0'; 102 | return buf; 103 | } 104 | 105 | char * 106 | ecvt(double arg, int ndigits, int *decpt, int *sign) 107 | { 108 | return cvt(arg, ndigits, decpt, sign, CVTBUF, 1); 109 | } 110 | 111 | char * 112 | ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) 113 | { 114 | return cvt(arg, ndigits, decpt, sign, buf, 1); 115 | } 116 | 117 | char * 118 | fcvt(double arg, int ndigits, int *decpt, int *sign) 119 | { 120 | return cvt(arg, ndigits, decpt, sign, CVTBUF, 0); 121 | } 122 | 123 | char * 124 | fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) 125 | { 126 | return cvt(arg, ndigits, decpt, sign, buf, 0); 127 | } 128 | -------------------------------------------------------------------------------- /sw/example/demo_blink_led/main.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | 10 | /**********************************************************************//** 11 | * @file demo_blink_led/main.c 12 | * @author Stephan Nolting 13 | * @brief Minimal blinking LED demo program using the lowest 8 bits of the GPIO.output port. 14 | **************************************************************************/ 15 | #include 16 | 17 | 18 | /**********************************************************************//** 19 | * Simple bus-wait helper. 20 | * 21 | * @param[in] time_ms Time in ms to wait (unsigned 32-bit). 22 | **************************************************************************/ 23 | void delay_ms(uint32_t time_ms) { 24 | neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms); 25 | } 26 | 27 | 28 | /**********************************************************************//** 29 | * Main function; shows an incrementing 8-bit counter on GPIO.output(7:0). 30 | * 31 | * @note This program requires the GPIO controller to be synthesized. 32 | * 33 | * @return Will never return. 34 | **************************************************************************/ 35 | int main() { 36 | 37 | // clear GPIO output (set all bits to 0) 38 | neorv32_gpio_port_set(0); 39 | 40 | int cnt = 0; 41 | 42 | while (1) { 43 | neorv32_gpio_port_set(cnt++ & 0xFF); // increment counter and mask for lowest 8 bit 44 | delay_ms(250); // wait 250ms using busy wait 45 | } 46 | 47 | // this should never be reached 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /sw/example/demo_blink_led/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_cfs/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_cfu/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_clint/Makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_dma/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core/Makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32ia_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core/spinlock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file spinlock.c 3 | * @brief Single simple spinlock based on atomic reservation-set operations. 4 | */ 5 | #include 6 | 7 | /**********************************************************************//** 8 | * Private spinlock locked variable. 9 | **************************************************************************/ 10 | static volatile uint32_t __spin_locked = 0; 11 | 12 | 13 | /**********************************************************************//** 14 | * Spinlock: set lock. 15 | * 16 | * @warning This function is blocking until the lock is acquired and set. 17 | **************************************************************************/ 18 | void spin_lock(void) { 19 | 20 | while(!__sync_bool_compare_and_swap(&__spin_locked, 0, -1)); // -> lr/sc 21 | } 22 | 23 | 24 | /**********************************************************************//** 25 | * Spinlock: remove lock. 26 | * 27 | * @warning This function is blocking until the lock is released. 28 | **************************************************************************/ 29 | void spin_unlock(void) { 30 | 31 | uint32_t failed = 1; 32 | while (failed) { 33 | neorv32_cpu_amolr((uint32_t)&__spin_locked); 34 | failed = neorv32_cpu_amosc((uint32_t)&__spin_locked, 0); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core/spinlock.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file spinlock.h 3 | * @brief Single simple spin-lock based on atomic memory operations. 4 | */ 5 | 6 | #ifndef spinlock_h 7 | #define spinlock_h 8 | 9 | void spin_lock(void); 10 | void spin_unlock(void); 11 | 12 | #endif // spinlock_h 13 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core_primes/Makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core_rte/Makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32ia_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core_rte/spinlock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file spinlock.c 3 | * @brief Single simple spinlock based on atomic memory operations. 4 | */ 5 | #include 6 | 7 | /**********************************************************************//** 8 | * Private spinlock locked variable. 9 | **************************************************************************/ 10 | static volatile uint32_t __spin_locked = 0; 11 | 12 | 13 | /**********************************************************************//** 14 | * Spinlock: set lock. 15 | * 16 | * @warning This function is blocking until the lock is acquired and set. 17 | **************************************************************************/ 18 | void spin_lock(void) { 19 | 20 | while(__sync_lock_test_and_set(&__spin_locked, -1)); // -> amoswap.w 21 | } 22 | 23 | 24 | /**********************************************************************//** 25 | * Spinlock: remove lock. 26 | **************************************************************************/ 27 | void spin_unlock(void) { 28 | 29 | //__sync_lock_release(&__spin_locked); // uses fence that is not required here 30 | __sync_lock_test_and_set(&__spin_locked, 0); // -> amoswap.w 31 | } 32 | -------------------------------------------------------------------------------- /sw/example/demo_dual_core_rte/spinlock.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file spinlock.h 3 | * @brief Single simple spin-lock based on atomic memory operations. 4 | */ 5 | 6 | #ifndef spinlock_h 7 | #define spinlock_h 8 | 9 | void spin_lock(void); 10 | void spin_unlock(void); 11 | 12 | #endif // spinlock_h 13 | -------------------------------------------------------------------------------- /sw/example/demo_emulate_unaligned/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_gpio/Makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32ia_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_gptmr/main.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | 10 | /**********************************************************************//** 11 | * @file demo_gptmr/main.c 12 | * @brief Simple GPTMR timer-match interrupt example. 13 | **************************************************************************/ 14 | 15 | #include 16 | 17 | 18 | /**********************************************************************//** 19 | * @name User configuration 20 | **************************************************************************/ 21 | /**@{*/ 22 | /** UART BAUD rate */ 23 | #define BAUD_RATE 19200 24 | /**@}*/ 25 | 26 | 27 | // Prototypes 28 | void gptmr_firq_handler(void); 29 | 30 | 31 | /**********************************************************************//** 32 | * This program blinks an LED at GPIO.output(0) at 1Hz using the general purpose timer interrupt. 33 | * 34 | * @note This program requires the GPTMR unit to be synthesized (and UART0 and GPIO). 35 | * 36 | * @return Should not return. 37 | **************************************************************************/ 38 | int main() { 39 | 40 | // setup NEORV32 runtime environment (for trap handling) 41 | neorv32_rte_setup(); 42 | 43 | // setup UART at default baud rate, no interrupts 44 | neorv32_uart0_setup(BAUD_RATE, 0); 45 | 46 | 47 | // check if GPTMR unit is implemented at all 48 | if (neorv32_gptmr_available() == 0) { 49 | neorv32_uart0_puts("ERROR! General purpose timer not implemented!\n"); 50 | return 1; 51 | } 52 | 53 | // Intro 54 | neorv32_uart0_puts("General purpose timer (GPTMR) demo Program.\n" 55 | "Toggles GPIO.output(0) at 1Hz using the GPTMR timer-match interrupt.\n\n"); 56 | 57 | 58 | // clear GPIO output port 59 | neorv32_gpio_port_set(0); 60 | 61 | 62 | // install GPTMR interrupt handler 63 | neorv32_rte_handler_install(GPTMR_RTE_ID, gptmr_firq_handler); 64 | 65 | // configure timer for 0.5Hz ticks with clock divisor = 8 66 | neorv32_gptmr_setup(CLK_PRSC_8, neorv32_sysinfo_get_clk() / (8 * 2)); 67 | 68 | // enable interrupt 69 | neorv32_cpu_csr_set(CSR_MIE, 1 << GPTMR_FIRQ_ENABLE); // enable GPTMR FIRQ channel 70 | neorv32_cpu_csr_set(CSR_MSTATUS, 1 << CSR_MSTATUS_MIE); // enable machine-mode interrupts 71 | 72 | 73 | // go to sleep mode and wait for interrupt 74 | while(1) { 75 | neorv32_cpu_sleep(); 76 | } 77 | 78 | return 0; 79 | } 80 | 81 | 82 | /**********************************************************************//** 83 | * GPTMR FIRQ handler. 84 | * 85 | * @warning This function has to be of type "void xyz(void)" and must not use any interrupt attributes! 86 | **************************************************************************/ 87 | void gptmr_firq_handler(void) { 88 | 89 | neorv32_gptmr_irq_ack(); // clear pending timer-internal interrupt 90 | 91 | neorv32_uart0_putc('.'); // send tick symbol via UART0 92 | neorv32_gpio_pin_toggle(0); // toggle output port bit 0 93 | } 94 | -------------------------------------------------------------------------------- /sw/example/demo_gptmr/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_hpm/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_neopixel/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_newlib/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=4k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_onewire/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_pwm/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_sdi/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_slink/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_spi/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_spi_irq/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | APP_SRC += $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S) $(wildcard ./drv/*.c) 27 | APP_INC += -I . -I ./drv 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | include $(NEORV32_HOME)/sw/common/common.mk 33 | -------------------------------------------------------------------------------- /sw/example/demo_trng/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_twd/main.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | 10 | /**********************************************************************//** 11 | * @file demo_twd/main.c 12 | * @author Lukas Pajak 13 | * @brief TWD demo. 14 | **************************************************************************/ 15 | 16 | #include 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name User configuration 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** UART BAUD rate */ 25 | #define BAUD_RATE 19200 26 | /** TWD id */ 27 | #define TWD_DEVICE_ID 0x3f 28 | /**@}*/ 29 | 30 | 31 | // Prototypes 32 | void isr_twd(void); 33 | 34 | 35 | /**********************************************************************//** 36 | * This program provides a simple demo as TWD device. 37 | * A connected TWI Host is required. 38 | * 39 | * @note This program requires the UART to be synthesized. 40 | * 41 | **************************************************************************/ 42 | int main() { 43 | // capture all exceptions and give debug info via UART 44 | // also handles isr for TD 45 | neorv32_rte_setup(); 46 | 47 | // check if UART unit is implemented at all 48 | if (neorv32_uart0_available() == 0) { 49 | return 1; 50 | } 51 | 52 | // setup UART at default baud rate, no interrupts 53 | neorv32_uart0_setup(BAUD_RATE, 0); 54 | neorv32_uart0_printf("\n\n<< TWD status demo >>\n"); 55 | neorv32_uart0_printf(__DATE__ "\n"); 56 | neorv32_uart0_printf(__TIME__ "\n"); 57 | 58 | uint8_t status = 0x03; 59 | 60 | // check for TWD 61 | if (!neorv32_twd_available()) { 62 | neorv32_uart0_printf("TWD not available\n"); 63 | return 1; 64 | } else { 65 | neorv32_uart0_printf("TWD available with rx fifo depth of %i and tx fifo depth of %i\n", 66 | neorv32_twd_get_rx_fifo_depth(), neorv32_twd_get_tx_fifo_depth()); 67 | } 68 | 69 | // setup TWD 70 | neorv32_rte_handler_install(TWD_RTE_ID, isr_twd); 71 | neorv32_twd_set_tx_dummy(status); 72 | neorv32_twd_setup(TWD_DEVICE_ID, 0, 1, 0, 0, 1, 0); 73 | neorv32_cpu_csr_set(CSR_MIE, 74 | 1 << TWD_FIRQ_ENABLE); 75 | neorv32_cpu_csr_set(CSR_MSTATUS, 76 | 1 << CSR_MSTATUS_MIE); 77 | 78 | // Fill TX Fifo 79 | for (uint8_t i = 0; i < neorv32_twd_get_tx_fifo_depth(); i++) 80 | { 81 | neorv32_twd_put(i); 82 | } 83 | 84 | neorv32_uart0_printf("Listen now on %x\n", TWD_DEVICE_ID); 85 | neorv32_uart0_printf("Read should return %i data byte(s) once and %x when TX FIFO is empty.\n", neorv32_twd_get_tx_fifo_depth(), status); 86 | while (1) {} 87 | } 88 | 89 | /*** 90 | * ISR of TWD for read access 91 | */ 92 | void isr_twd(void) { 93 | uint8_t data = neorv32_twd_get(); 94 | neorv32_uart0_printf("Got %x\n", data); 95 | neorv32_twd_disable_tx_dummy(); 96 | neorv32_uart0_printf("Read should fail (or return 0xFF when in the same transaction) when TX FIFO is empty.\n"); 97 | neorv32_twd_put(data); 98 | } 99 | -------------------------------------------------------------------------------- /sw/example/demo_twd/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_twi/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/demo_wdt/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/dhrystone/LICENSE: -------------------------------------------------------------------------------- 1 | Original LICENSE from https://github.com/sifive/benchmark-dhrystone 2 | 3 | Dhrystone 4 | ------------------------------------------------------------------------------ 5 | There is no explicit license defined. They were originally 6 | written in ADA by Reinhold P. Weicker and translated to C by Rick Richardson . 7 | 8 | The source obtained from the following site: 9 | https://fossies.org/linux/privat/old/dhrystone-2.1.tar.gz 10 | -------------------------------------------------------------------------------- /sw/example/dhrystone/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/eclipse/.gitignore: -------------------------------------------------------------------------------- 1 | .settings/ 2 | -------------------------------------------------------------------------------- /sw/example/eclipse/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | eclipse_example 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 15 | full,incremental, 16 | 17 | 18 | 19 | 20 | 21 | org.eclipse.cdt.core.cnature 22 | org.eclipse.cdt.core.ccnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 25 | 26 | 27 | 28 | source 29 | 2 30 | $%7BPARENT-2-PROJECT_LOC%7D/lib/source 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /sw/example/eclipse/README.md: -------------------------------------------------------------------------------- 1 | # Eclipse Example Project 2 | 3 | Pre-configured example project that can be imported into Eclipse: 4 | 5 | * Open Eclipse. 6 | * Click on **File > Import**, expand **General** and select **Projects from Folder or Archive**. 7 | * Click **Next**. 8 | * Click on **Directory** and select _this_ folder (`path/to/neorv32/sw/example/eclipse`). 9 | * Click **Finish**. 10 | 11 | > [!TIP] 12 | > See the NEORV32 User Guide for more information: [UG: Eclipse IDE](https://stnolting.github.io/neorv32/ug/#_eclipse_ide) 13 | -------------------------------------------------------------------------------- /sw/example/eclipse/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // UART baud rate 5 | #define BAUD_RATE 19200 6 | 7 | // Setup the processor 8 | void platform_init(void) { 9 | neorv32_rte_setup(); 10 | neorv32_uart_setup(NEORV32_UART0, BAUD_RATE, 0); 11 | } 12 | 13 | // Simple busy-wait delay function 14 | void delay_ms(uint32_t time_ms) { 15 | neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms); 16 | } 17 | 18 | // Main function 19 | int main() { 20 | 21 | // initialize the platform 22 | platform_init(); 23 | 24 | // say hello 25 | while(1) { 26 | printf("Hello Eclipse!\r\n"); 27 | delay_ms(500); 28 | } 29 | 30 | // this should never be reached 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /sw/example/eclipse/makefile: -------------------------------------------------------------------------------- 1 | # Use this makefile to configure all relevant CPU / compiler options 2 | # as these cannot be set by Eclipse (since this is a makefile-based project). 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32imc_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols for Eclipse 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Additional sources 17 | APP_SRC += $(wildcard ./*.c) 18 | APP_INC += -I . 19 | 20 | # Adjust processor IMEM size and base address 21 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=20k 22 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_base=0x00000000 23 | 24 | # Adjust processor DMEM size and base address 25 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 26 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_base=0x80000000 27 | 28 | # Adjust maximum heap size 29 | USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=2k 30 | 31 | # Set path to NEORV32 root directory 32 | NEORV32_HOME ?= ../../.. 33 | 34 | # Include the main NEORV32 makefile 35 | include $(NEORV32_HOME)/sw/common/common.mk 36 | -------------------------------------------------------------------------------- /sw/example/float_corner_test/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/floating_point_test/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/game_of_life/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | APP_SRC += $(wildcard ./*.c) 27 | APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | -------------------------------------------------------------------------------- /sw/example/hello_cpp/main.cpp: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | 10 | /**********************************************************************//** 11 | * @file hello_cpp/main.cpp 12 | * @author Gideon Zweijtzer 13 | * @brief Simple 'hello world' type of demo with static C++ constructors 14 | **************************************************************************/ 15 | 16 | #include 17 | 18 | 19 | /**********************************************************************//** 20 | * @name User configuration 21 | **************************************************************************/ 22 | /**@{*/ 23 | /** UART BAUD rate */ 24 | #define BAUD_RATE 19200 25 | /**@}*/ 26 | 27 | /**********************************************************************//** 28 | * DemoClass: Just a simple C++ class that holds one constant and can 29 | * be asked to print it. 30 | * 31 | * @note This class will only successfully reveal its ID if the 32 | * constructors are called prior to the main function. 33 | **************************************************************************/ 34 | class DemoClass 35 | { 36 | const int identity; 37 | public: 38 | DemoClass(int id) : identity(id) { } 39 | 40 | void print_id(void) 41 | { 42 | // In order to demonstrate just how constructors are called pre-main, 43 | // it is not necessary to use the C++ type streams to print something. 44 | neorv32_uart0_printf("I am DemoClass with instance ID: %d\n", identity); 45 | } 46 | }; 47 | 48 | static DemoClass demo1(1); 49 | static DemoClass demo2(2); 50 | 51 | /**********************************************************************//** 52 | * Main function; prints some fancy stuff via UART. 53 | * 54 | * @note This program requires the UART interface to be synthesized. 55 | * 56 | * @return 0 if execution was successful 57 | **************************************************************************/ 58 | int main() { 59 | 60 | // capture all exceptions and give debug info via UART 61 | // this is not required, but keeps us safe 62 | neorv32_rte_setup(); 63 | 64 | // setup UART at default baud rate, no interrupts 65 | neorv32_uart0_setup(BAUD_RATE, 0); 66 | 67 | // print project logo via UART 68 | neorv32_aux_print_logo(); 69 | 70 | // say hello 71 | neorv32_uart0_printf("Hello C++! :)\n"); 72 | 73 | // print the IDs of the two statically declared instances of DemoClass 74 | demo1.print_id(); 75 | demo2.print_id(); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /sw/example/hello_cpp/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | 35 | # Use c++ compiler and define c++ standard 36 | override CC = $(RISCV_PREFIX)g++ 37 | USER_FLAGS += -std=c++11 38 | -------------------------------------------------------------------------------- /sw/example/hello_world/main.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | 10 | /**********************************************************************//** 11 | * @file hello_world/main.c 12 | * @author Stephan Nolting 13 | * @brief Classic 'hello world' demo program. 14 | **************************************************************************/ 15 | 16 | #include 17 | 18 | 19 | /**********************************************************************//** 20 | * @name User configuration 21 | **************************************************************************/ 22 | /**@{*/ 23 | /** UART BAUD rate */ 24 | #define BAUD_RATE 19200 25 | /**@}*/ 26 | 27 | 28 | 29 | /**********************************************************************//** 30 | * Main function; prints some fancy stuff via UART. 31 | * 32 | * @note This program requires the UART interface to be synthesized. 33 | * 34 | * @return 0 if execution was successful 35 | **************************************************************************/ 36 | int main() { 37 | 38 | // capture all exceptions and give debug info via UART 39 | // this is not required, but keeps us safe 40 | neorv32_rte_setup(); 41 | 42 | // setup UART at default baud rate, no interrupts 43 | neorv32_uart0_setup(BAUD_RATE, 0); 44 | 45 | // print project logo via UART 46 | neorv32_aux_print_logo(); 47 | 48 | // say hello 49 | neorv32_uart0_puts("Hello world! :)\n"); 50 | 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /sw/example/hello_world/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | MARCH = rv32i_zicsr_zifencei 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Adjust processor IMEM size 17 | USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k 18 | 19 | # Adjust processor DMEM size 20 | USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 21 | 22 | # Adjust maximum heap size 23 | #USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=1k 24 | 25 | # Additional sources 26 | #APP_SRC += $(wildcard ./*.c) 27 | #APP_INC += -I . 28 | 29 | # Set path to NEORV32 root directory 30 | NEORV32_HOME ?= ../../.. 31 | 32 | # Include the main NEORV32 makefile 33 | include $(NEORV32_HOME)/sw/common/common.mk 34 | 35 | sim-check: sim 36 | cat $(NEORV32_HOME)/sim/neorv32.uart0_sim_mode.out | grep "Hello world! :)" 37 | -------------------------------------------------------------------------------- /sw/example/makefile: -------------------------------------------------------------------------------- 1 | .SUFFIXES: 2 | .DEFAULT_GOAL := help 3 | 4 | TOPTARGETS := exe clean_all check info all 5 | 6 | SUBDIRS := $(wildcard */.) 7 | # ignore dummy folders (starting with '~') 8 | EXCLDIR := $(wildcard ~*/.) 9 | # ignore some of the default projects/examples 10 | EXCLDIR += eclipse/. dhrystone/. performance_tests/. float_corner_test/. 11 | SUBDIRS := $(filter-out $(EXCLDIR), $(SUBDIRS)) 12 | 13 | $(TOPTARGETS): $(SUBDIRS) 14 | $(SUBDIRS): 15 | @set -e 16 | @$(MAKE) -C $@ $(MAKECMDGOALS) 17 | 18 | .PHONY: $(TOPTARGETS) $(SUBDIRS) 19 | 20 | help: 21 | @echo "Build / clean up all projects" 22 | @echo "Targets:" 23 | @echo " help - show this text" 24 | @echo " check - check toolchain" 25 | @echo " info - show makefile configuration" 26 | @echo " exe - create executables from all projects" 27 | @echo " all - create executables and boot images from all projects" 28 | @echo " clean_all - clean up everything" 29 | -------------------------------------------------------------------------------- /sw/example/performance_tests/I/makefile: -------------------------------------------------------------------------------- 1 | # Modify this variable to fit your NEORV32 setup (neorv32 home folder) 2 | NEORV32_HOME ?= ../../../.. 3 | MARCH ?= rv32i_zicsr_zifencei 4 | GHDL_RUN_FLAGS ?= -gPERFORMANCE_OPTION=1 --stop-time=4500us 5 | override USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=128k 6 | override USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=16k 7 | 8 | include $(NEORV32_HOME)/sw/common/common.mk 9 | -------------------------------------------------------------------------------- /sw/example/performance_tests/M/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 M performance measurement test 2 | 3 | This code piece allows the measurement of the number of cycles of various I instructions. 4 | The possible instructions to test are: 5 | - mult : mul, mulh, mulhsu, mulhu 6 | - div : div, divu 7 | - rem : rem, remu 8 | 9 | The number of instructions run can be tuned by setting the following command line parameters: 10 | `USER_FLAGS+=-DinstLoop=1` This tunes the number loops run, default 1 11 | `USER_FLAGS+=-DinstCalls=256` This tunes the number of instructions called per inner loop, default 256. 12 | The instCalls variable impacts memory, as each instruction instance takes up memory. 13 | 14 | The limit the performance image size which instructions that can be tested can be controlled the following comand line parameters. The name of the parameter matches the list of instruction groups above: 15 | `USER_FLAGS+=-Drv32I_mult` 16 | `USER_FLAGS+=-Drv32I_div` 17 | `USER_FLAGS+=-Drv32I_rem` 18 | `USER_FLAGS+=-Drv32I_all` Run all instruction tests, the image will be large 19 | 20 | For less verbose output `USER_FLAGS+=-DSILENT_MODE=1` can be applied 21 | 22 | ## Example compile and run 23 | This will run all the M instruction suites 24 | 25 | ``` 26 | make USER_FLAGS+=-DRUN_CHECK USER_FLAGS+=-DUART0_SIM_MODE USER_FLAGS+=-Drv32M_all clean_all exe 27 | make sim 28 | ``` 29 | 30 | ## Exemplary Test Output 31 | 32 | ``` 33 | <<< M performance test >>> 34 | 35 | perform: for (i=0;i<1,i++) {256 instructions} 36 | 37 | mul tot. 1491 cyc 38 | 39 | total 1491 cyc 40 | 41 | mul rd,rs1,rs2 inst. 5 cyc 42 | 43 | mulh tot. 1524 cyc 44 | 45 | total 3015 cyc 46 | 47 | mulh rd,rs1,rs2 inst. 5 cyc 48 | 49 | mulhsu tot. 1491 cyc 50 | 51 | total 4506 cyc 52 | 53 | mulhsu rd,rs1,rs2 inst. 5 cyc 54 | 55 | mulhu tot. 1491 cyc 56 | 57 | total 5997 cyc 58 | 59 | mulhu rd,imm inst. 5 cyc 60 | 61 | div tot. 8963 cyc 62 | 63 | total 14960 cyc 64 | 65 | div rd,rs1,rs2 inst. 35 cyc 66 | 67 | divu tot. 8963 cyc 68 | 69 | total 23923 cyc 70 | 71 | divu rd,rs1,shamt inst. 35 cyc 72 | 73 | rem tot. 8963 cyc 74 | 75 | total 32886 cyc 76 | 77 | rem rd,rs1,rs2 inst. 35 cyc 78 | 79 | remu tot. 8963 cyc 80 | 81 | total 41849 cyc 82 | 83 | remu rd,rs1,rs2 inst. 35 cyc 84 | 85 | instructions tested: 8 86 | 87 | total 41849 cycles 88 | 89 | avg. inst. execute cyles 20.434 90 | ``` 91 | -------------------------------------------------------------------------------- /sw/example/performance_tests/M/makefile: -------------------------------------------------------------------------------- 1 | # Modify this variable to fit your NEORV32 setup (neorv32 home folder) 2 | NEORV32_HOME ?= ../../../.. 3 | MARCH ?= rv32im_zicsr_zifencei 4 | GHDL_RUN_FLAGS ?= -gPERFORMANCE_OPTION=1 --stop-time=1500us 5 | override USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=128k 6 | override USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=16k 7 | 8 | include $(NEORV32_HOME)/sw/common/common.mk 9 | -------------------------------------------------------------------------------- /sw/example/performance_tests/Zfinx/makefile: -------------------------------------------------------------------------------- 1 | # Modify this variable to fit your NEORV32 setup (neorv32 home folder) 2 | NEORV32_HOME ?= ../../../.. 3 | MARCH ?= rv32i_zicsr_zifencei_zfinx 4 | GHDL_RUN_FLAGS ?= -gPERFORMANCE_OPTION=1 --stop-time=4500us 5 | override USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=64k 6 | override USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=16k 7 | 8 | include $(NEORV32_HOME)/sw/common/common.mk 9 | -------------------------------------------------------------------------------- /sw/example/performance_tests/run_performance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd I 3 | make USER_FLAGS+=-DRUN_CHECK USER_FLAGS+=-DUART0_SIM_MODE USER_FLAGS+=-DSILENT_MODE USER_FLAGS+=-Drv32_all clean_all exe 4 | make sim 5 | cd .. 6 | cd M 7 | make USER_FLAGS+=-DRUN_CHECK USER_FLAGS+=-DUART0_SIM_MODE USER_FLAGS+=-DSILENT_MODE USER_FLAGS+=-Drv32_all clean_all exe 8 | make sim 9 | cd .. 10 | cd Zfinx 11 | make USER_FLAGS+=-DRUN_CHECK USER_FLAGS+=-DUART0_SIM_MODE USER_FLAGS+=-DSILENT_MODE USER_FLAGS+=-Drv32_all clean_all exe 12 | make sim 13 | cd .. 14 | 15 | -------------------------------------------------------------------------------- /sw/example/processor_check/README.md: -------------------------------------------------------------------------------- 1 | ## NEORV32 Processor/SoC Test Program 2 | 3 | In contrast to the `riscv-arch-test` test suite, which tests individual instructions and ISA mechanisms, this 4 | test program is intended to check the _higher-level_ functions of the CPU core and the SoC it is integrated within. 5 | These higher-level function tests include: 6 | 7 | * all CPU traps 8 | * SoC interrupts 9 | * NEORV32 software runtime environment 10 | * data and instruction memory layout (sections) 11 | * basic function tests of the peripheral/IO devices 12 | 13 | :information_source: This test program is meant to be run in simulation using the default testbench that enables 14 | all optional functions/modules/extensions. Running this program on real hardware is also possible but might 15 | cause unintended IO side effects (like triggering chip-external operations). 16 | -------------------------------------------------------------------------------- /sw/example/processor_check/makefile: -------------------------------------------------------------------------------- 1 | # Application makefile. 2 | # Use this makefile to configure all relevant CPU / compiler options. 3 | 4 | # Override the default CPU ISA 5 | override MARCH = rv32ima_zba_zbb_zbs_zbkb_zbkc_zbkx_zknd_zkne_zknh_zksh_zksed_zicsr_zfinx_zifencei_zicond 6 | 7 | # Override the default RISC-V GCC prefix 8 | #RISCV_PREFIX ?= riscv-none-elf- 9 | 10 | # Override default optimization goal 11 | EFFORT = -Os 12 | 13 | # Add extended debug symbols 14 | override USER_FLAGS += -ggdb -gdwarf-3 15 | 16 | # Enable link time optimization 17 | override USER_FLAGS += -flto 18 | 19 | # Adjust processor IMEM size 20 | override USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=32k 21 | 22 | # Adjust processor DMEM size 23 | override USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k 24 | 25 | # Adjust maximum heap size 26 | override USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3096 27 | 28 | # Simulation arguments 29 | override GHDL_RUN_FLAGS ?= --stop-time=15ms 30 | 31 | # Additional sources 32 | #APP_SRC += $(wildcard ./*.c) 33 | #APP_INC += -I . 34 | 35 | # Set path to NEORV32 root directory 36 | NEORV32_HOME ?= ../../.. 37 | 38 | # Include the main NEORV32 makefile 39 | include $(NEORV32_HOME)/sw/common/common.mk 40 | 41 | # Add test-specific makefile target 42 | sim-check: sim 43 | cat $(NEORV32_HOME)/sim/neorv32.uart0_sim_mode.out | grep "PROCESSOR TEST COMPLETED SUCCESSFULLY!" 44 | -------------------------------------------------------------------------------- /sw/example/processor_check/run_check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | echo "Starting processor check simulation..." 6 | make USER_FLAGS+="-DUART0_SIM_MODE -DUART1_SIM_MODE" hdl_lists clean_all all sim-check 7 | -------------------------------------------------------------------------------- /sw/image_gen/uart_upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Simple script to upload executable via bootloader 6 | 7 | if [ $# -ne 2 ] 8 | then 9 | printf "Upload and execute application image via serial port (UART) to the NEORV32 bootloader.\n" 10 | printf "Reset processor before starting the upload.\n\n" 11 | printf "Usage: sh uart_upload.sh \n" 12 | printf "Example: sh uart_upload.sh /dev/ttyS6 path/to/project/neorv32_exe.bin\n" 13 | exit 0 14 | fi 15 | 16 | # configure serial port 17 | stty -F "$1" 19200 -hup raw -echo -echoe -echok -echoctl -echoke -ixon cs8 -cstopb noflsh clocal cread 18 | 19 | # abort autoboot sequence 20 | printf " " > $1 # send any char that triggers no command 21 | 22 | # execute upload command and get response 23 | exec 3<$1 # redirect serial output to fd 3 24 | cat <&3 > uart_upload.response.tmp & # redirect serial output to file 25 | PID=$! # save pid to kill cat later 26 | printf "u" > $1 # send upload command to serial port 27 | sleep 0.5s # wait for bootloader response 28 | kill $PID # kill cat process 29 | 30 | exec 3<&- # free fd 3 31 | 32 | # check response 33 | if ! grep -Fq "Awaiting neorv32_exe.bin" uart_upload.response.tmp; 34 | then 35 | printf "Bootloader response error!\n" 36 | printf "Reset processor before starting the upload.\n" 37 | rm -f uart_upload.response.tmp 38 | exit 1 39 | fi 40 | 41 | # send executable and get response 42 | printf "Uploading executable..." 43 | exec 3<$1 # redirect serial output to fd 3 44 | cat <&3 > uart_upload.response.tmp & # redirect serial output to file 45 | PID=$! # save pid to kill cat later 46 | cat "$2" > "$1" # send executable to serial port 47 | sleep 3s # wait for bootloader response 48 | kill $PID # kill cat process 49 | 50 | exec 3<&- # free fd 3 51 | 52 | # check response 53 | if ! grep -Fq "OK" uart_upload.response.tmp; 54 | then 55 | printf " FAILED!\n" 56 | rm -f uart_upload.response.tmp 57 | exit 1 58 | else 59 | printf " OK\n" 60 | echo "Starting application..." 61 | printf "e" > $1 62 | rm -f uart_upload.response.tmp 63 | exit 0 64 | fi 65 | -------------------------------------------------------------------------------- /sw/lib/README.md: -------------------------------------------------------------------------------- 1 | ## NEORV32 Core Library 2 | 3 | This folder provides the hardware abstraction layer (HAL) libraries for the CPU itself and the individual processor modules (peripheral/IO devices). 4 | The `source` folder contains the actual C-code hardware driver functions (`*.c`) while the `include` folder provides the according header files (`*.h`). 5 | Application programs should only include the *main NEORV32 define file* `neorv32.h` - this file automatically includes all other header files: 6 | 7 | ```c 8 | #include 9 | ``` 10 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_aux.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_aux.h 11 | * @brief General auxiliary functions header file. 12 | */ 13 | 14 | #ifndef NEORV32_AUX_H 15 | #define NEORV32_AUX_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name Date and time struct 22 | **************************************************************************/ 23 | typedef struct { 24 | uint16_t year; /**< current year (absolute) */ 25 | uint8_t month; /**< 1..12 */ 26 | uint8_t day; /**< 1..31 */ 27 | uint8_t weekday; /**< 1..7 starting with Monday */ 28 | uint8_t hours; /**< 0..23 */ 29 | uint8_t minutes; /**< 0..59 */ 30 | uint8_t seconds; /**< 0..59 */ 31 | } date_t; 32 | 33 | 34 | /**********************************************************************//** 35 | * @name AUX prototypes 36 | **************************************************************************/ 37 | /**@{*/ 38 | void neorv32_aux_delay_ms(uint32_t clock_hz, uint32_t time_ms); 39 | uint64_t neorv32_aux_date2unixtime(date_t* date); 40 | void neorv32_aux_unixtime2date(uint64_t unixtime, date_t* date); 41 | uint64_t neorv32_aux_hexstr2uint64(char *buffer, unsigned int length); 42 | uint32_t neorv32_aux_xorshift32(void); 43 | void neorv32_aux_itoa(char *buffer, uint32_t num, uint32_t base); 44 | void neorv32_aux_print_hw_config(void); 45 | void neorv32_aux_print_hw_version(uint32_t impid); 46 | void neorv32_aux_print_about(void); 47 | void neorv32_aux_print_logo(void); 48 | void neorv32_aux_print_license(void); 49 | /**@}*/ 50 | 51 | 52 | #endif // NEORV32_AUX_H 53 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_cfs.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_cfs.h 11 | * @brief Custom Functions Subsystem (CFS) HW driver header file. 12 | * 13 | * @warning There are no "real" CFS driver functions available here, because these functions are defined by the actual hardware. 14 | * @warning The CFS designer has to provide the actual driver functions. 15 | */ 16 | 17 | #ifndef NEORV32_CFS_H 18 | #define NEORV32_CFS_H 19 | 20 | #include 21 | 22 | 23 | /**********************************************************************//** 24 | * @name IO Device: Custom Functions Subsystem (CFS) 25 | **************************************************************************/ 26 | /**@{*/ 27 | /** CFS module prototype */ 28 | typedef volatile struct __attribute__((packed,aligned(4))) { 29 | uint32_t REG[(64*1024)/4]; /**< CFS registers, user-defined */ 30 | } neorv32_cfs_t; 31 | 32 | /** CFS module hardware handle (#neorv32_cfs_t) */ 33 | #define NEORV32_CFS ((neorv32_cfs_t*) (NEORV32_CFS_BASE)) 34 | /**@}*/ 35 | 36 | 37 | /**********************************************************************//** 38 | * @name Prototypes 39 | **************************************************************************/ 40 | /**@{*/ 41 | int neorv32_cfs_available(void); 42 | /**@}*/ 43 | 44 | 45 | #endif // NEORV32_CFS_H 46 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_clint.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_clint.h 11 | * @brief Hardware Local Interruptor (CLINT) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_CLINT_H 15 | #define NEORV32_CLINT_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: Core Local Interruptor (CLINT) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** CLINT module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | uint32_t MSWI[4096]; /**< machine software interrupt for hart 0..4095 */ 27 | subwords64_t MTIMECMP[4095]; /**< machine timer compare interrupt for hart 0..4094; 64-bit */ 28 | subwords64_t MTIME; /**< global machine timer; 64-bit */ 29 | } neorv32_clint_t; 30 | 31 | /** CLINT module hardware handle (#neorv32_clint_t) */ 32 | #define NEORV32_CLINT ((neorv32_clint_t*) (NEORV32_CLINT_BASE)) 33 | /**@}*/ 34 | 35 | 36 | /**********************************************************************//** 37 | * @name Prototypes 38 | **************************************************************************/ 39 | /**@{*/ 40 | int neorv32_clint_available(void); 41 | void neorv32_clint_msi_set(int hart); 42 | void neorv32_clint_msi_clr(int hart); 43 | uint32_t neorv32_clint_msi_get(int hart); 44 | void neorv32_clint_time_set(uint64_t time); 45 | uint64_t neorv32_clint_time_get(void); 46 | void neorv32_clint_mtimecmp_set(uint64_t timecmp); 47 | uint64_t neorv32_clint_mtimecmp_get(void); 48 | void neorv32_clint_unixtime_set(uint64_t unixtime); 49 | uint64_t neorv32_clint_unixtime_get(void); 50 | /**@}*/ 51 | 52 | 53 | #endif // NEORV32_CLINT_H 54 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_cpu_cfu.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_cpu_cfu.h 11 | * @brief CPU Core custom functions unit HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_CPU_CFU_H 15 | #define NEORV32_CPU_CFU_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name Prototypes 22 | **************************************************************************/ 23 | int neorv32_cpu_cfu_available(void); 24 | 25 | 26 | /**********************************************************************//** 27 | * @name Low-level CFU custom instruction prototypes ("intrinsics"). 28 | * Note that each instruction provides a uint32_t return value. 29 | **************************************************************************/ 30 | /**@{*/ 31 | /** R3-type CFU custom instruction (CUSTOM-0 opcode) */ 32 | #define neorv32_cfu_r3_instr(funct7, funct3, rs1, rs2) CUSTOM_INSTR_R3_TYPE(funct7, rs2, rs1, funct3, 0b0001011) 33 | /** R4-type CFU custom instruction (CUSTOM-1 opcode) */ 34 | #define neorv32_cfu_r4_instr(funct3, rs1, rs2, rs3) CUSTOM_INSTR_R4_TYPE(rs3, rs2, rs1, funct3, 0b0101011) 35 | /**@}*/ 36 | 37 | 38 | #endif // NEORV32_CPU_CFU_H 39 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_gpio.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_gpio.h 11 | * @brief General purpose input/output port unit (GPIO) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_GPIO_H 15 | #define NEORV32_GPIO_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: General Purpose Input/Output Port Unit (GPIO) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** GPIO module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | const uint32_t PORT_IN; /**< parallel input port, read-only */ 27 | uint32_t PORT_OUT; /**< parallel output port */ 28 | const uint32_t reserved[2]; /**< reserved */ 29 | uint32_t IRQ_TYPE; /**< trigger type (#GPIO_TRIGGER_enum MSB) */ 30 | uint32_t IRQ_POLARITY; /**< trigger polarity (#GPIO_TRIGGER_enum LSB) */ 31 | uint32_t IRQ_ENABLE; /**< interrupt enable */ 32 | uint32_t IRQ_PENDING; /**< interrupt pending */ 33 | } neorv32_gpio_t; 34 | 35 | /** GPIO module hardware handle (#neorv32_gpio_t) */ 36 | #define NEORV32_GPIO ((neorv32_gpio_t*) (NEORV32_GPIO_BASE)) 37 | /**@}*/ 38 | 39 | 40 | /**********************************************************************//** 41 | * @name Trigger types 42 | **************************************************************************/ 43 | enum GPIO_TRIGGER_enum { 44 | GPIO_TRIG_LEVEL_LOW = 0b00, // low-level 45 | GPIO_TRIG_LEVEL_HIGH = 0b01, // high-level 46 | GPIO_TRIG_EDGE_FALLING = 0b10, // falling-edge 47 | GPIO_TRIG_EDGE_RISING = 0b11 // rising-edge 48 | }; 49 | 50 | 51 | /**********************************************************************//** 52 | * @name Prototypes 53 | **************************************************************************/ 54 | /**@{*/ 55 | int neorv32_gpio_available(void); 56 | void neorv32_gpio_pin_set(int pin, int value); 57 | void neorv32_gpio_pin_toggle(int pin); 58 | uint32_t neorv32_gpio_pin_get(int pin); 59 | void neorv32_gpio_port_set(uint32_t pin_mask); 60 | void neorv32_gpio_port_toggle(uint32_t pin_mask); 61 | uint32_t neorv32_gpio_port_get(void); 62 | void neorv32_gpio_irq_setup(int pin, int trigger); 63 | void neorv32_gpio_irq_enable(uint32_t pin_mask); 64 | void neorv32_gpio_irq_disable(uint32_t pin_mask); 65 | uint32_t neorv32_gpio_irq_get(void); 66 | void neorv32_gpio_irq_clr(uint32_t pin_mask); 67 | /**@}*/ 68 | 69 | 70 | #endif // NEORV32_GPIO_H 71 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_gptmr.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_gptmr.h 11 | * @brief General purpose timer (GPTMR) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_GPTMR_H 15 | #define NEORV32_GPTMR_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: General Purpose Timer (GPTMR) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** GPTMR module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | uint32_t CTRL; /**< offset 0: control register (#NEORV32_GPTMR_CTRL_enum) */ 27 | uint32_t THRES; /**< offset 4: threshold register */ 28 | const uint32_t COUNT; /**< offset 8: counter register, read-only */ 29 | } neorv32_gptmr_t; 30 | 31 | /** GPTMR module hardware handle (#neorv32_gptmr_t) */ 32 | #define NEORV32_GPTMR ((neorv32_gptmr_t*) (NEORV32_GPTMR_BASE)) 33 | 34 | /** GPTMR control register bits */ 35 | enum NEORV32_GPTMR_CTRL_enum { 36 | GPTMR_CTRL_EN = 0, /**< GPTMR control register(0) (r/w): GPTMR enable */ 37 | GPTMR_CTRL_PRSC0 = 1, /**< GPTMR control register(1) (r/w): Clock prescaler select bit 0 */ 38 | GPTMR_CTRL_PRSC1 = 2, /**< GPTMR control register(2) (r/w): Clock prescaler select bit 1 */ 39 | GPTMR_CTRL_PRSC2 = 3, /**< GPTMR control register(3) (r/w): Clock prescaler select bit 2 */ 40 | 41 | GPTMR_CTRL_IRQ_CLR = 30, /**< GPTMR control register(30) (-/w): Set to clear timer-match interrupt */ 42 | GPTMR_CTRL_IRQ_PND = 31, /**< GPTMR control register(31) (r/-): Timer-match interrupt pending */ 43 | }; 44 | /**@}*/ 45 | 46 | 47 | /**********************************************************************//** 48 | * @name Prototypes 49 | **************************************************************************/ 50 | /**@{*/ 51 | int neorv32_gptmr_available(void); 52 | void neorv32_gptmr_setup(int prsc, uint32_t threshold); 53 | void neorv32_gptmr_disable(void); 54 | void neorv32_gptmr_enable(void); 55 | void neorv32_gptmr_irq_ack(void); 56 | /**@}*/ 57 | 58 | 59 | #endif // NEORV32_GPTMR_H 60 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_pwm.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_pwm.h 11 | * @brief Pulse-Width Modulation Controller (PWM) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_PWM_H 15 | #define NEORV32_PWM_H 16 | 17 | #include 18 | #include 19 | 20 | 21 | /**********************************************************************//** 22 | * @name IO Device: Pulse Width Modulation Controller (PWM) 23 | **************************************************************************/ 24 | /**@{*/ 25 | /** PWM module prototype */ 26 | typedef volatile struct __attribute__((packed,aligned(4))) { 27 | uint32_t CHANNEL_CFG[16]; /**< offset 0..64: channel configuration 0..15 (#CHANNEL_CFG_enum) */ 28 | } neorv32_pwm_t; 29 | 30 | /** PWM module hardware handle (#neorv32_pwm_t) */ 31 | #define NEORV32_PWM ((neorv32_pwm_t*) (NEORV32_PWM_BASE)) 32 | 33 | /** PWM channel configuration bits */ 34 | enum CHANNEL_CFG_enum { 35 | PWM_CFG_DUTY_LSB = 0, /**< PWM configuration register(0) (r/w): Duty cycle (8-bit), LSB */ 36 | PWM_CFG_DUTY_MSB = 7, /**< PWM configuration register(7) (r/w): Duty cycle (8-bit), MSB */ 37 | PWM_CFG_CDIV_LSB = 8, /**< PWM configuration register(8) (r/w): Clock divider (10-bit), LSB */ 38 | PWM_CFG_CDIV_MSB = 17, /**< PWM configuration register(17) (r/w): Clock divider (10-bit), MSB */ 39 | 40 | PWM_CFG_POL = 27, /**< PWM configuration register(27) (r/w): Channel polarity, inverted when set */ 41 | PWM_CFG_PRSC_LSB = 28, /**< PWM configuration register(28) (r/w): Clock prescaler select (3-bit), LSB */ 42 | PWM_CFG_PRSC_MSB = 30, /**< PWM configuration register(30) (r/w): Clock prescaler select (3-bit), MSB */ 43 | PWM_CFG_EN = 31 /**< PWM configuration register(31) (r/w): channel enable */ 44 | }; 45 | /**@}*/ 46 | 47 | 48 | /**********************************************************************//** 49 | * @name Prototypes 50 | **************************************************************************/ 51 | /**@{*/ 52 | int neorv32_pwm_available(void); 53 | int neorv32_pmw_get_num_channels(void); 54 | void neorv32_pwm_ch_enable(int channel); 55 | void neorv32_pwm_ch_disable(int channel); 56 | void neorv32_pwm_ch_set_polarity(int channel, bool inverted); 57 | void neorv32_pwm_ch_set_clock(int channel, int prsc, int cdiv); 58 | void neorv32_pwm_ch_set_duty(int channel, int duty); 59 | /**@}*/ 60 | 61 | #endif // NEORV32_PWM_H 62 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_sdi.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_sdi.h 11 | * @brief Serial data interface controller (SPPI) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_SDI_H 15 | #define NEORV32_SDI_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: Serial Data Interface (SDI) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** SDI module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | uint32_t CTRL; /**< offset 0: control register (#NEORV32_SDI_CTRL_enum) */ 27 | uint32_t DATA; /**< offset 4: data register */ 28 | } neorv32_sdi_t; 29 | 30 | /** SDI module hardware handle (#neorv32_sdi_t) */ 31 | #define NEORV32_SDI ((neorv32_sdi_t*) (NEORV32_SDI_BASE)) 32 | 33 | /** SDI control register bits */ 34 | enum NEORV32_SDI_CTRL_enum { 35 | SDI_CTRL_EN = 0, /**< SDI control register(0) (r/w): SID module enable */ 36 | 37 | SDI_CTRL_FIFO_LSB = 4, /**< SDI control register(4) (r/-): log2 of SDI FIFO size, LSB */ 38 | SDI_CTRL_FIFO_MSB = 7, /**< SDI control register(7) (r/-): log2 of SDI FIFO size, MSB */ 39 | 40 | SDI_CTRL_IRQ_RX_AVAIL = 15, /**< SDI control register(15) (r/w): IRQ when RX FIFO not empty */ 41 | SDI_CTRL_IRQ_RX_HALF = 16, /**< SDI control register(16) (r/w): IRQ when RX FIFO at least half full */ 42 | SDI_CTRL_IRQ_RX_FULL = 17, /**< SDI control register(17) (r/w): IRQ when RX FIFO full */ 43 | SDI_CTRL_IRQ_TX_EMPTY = 18, /**< SDI control register(18) (r/w): IRQ when TX FIFO empty */ 44 | SDI_CTRL_IRQ_TX_NHALF = 19, /**< SDI control register(19) (r/w): IRQ when TX FIFO not at least half full */ 45 | 46 | SDI_CTRL_RX_AVAIL = 23, /**< SDI control register(23) (r/-): RX FIFO not empty */ 47 | SDI_CTRL_RX_HALF = 24, /**< SDI control register(24) (r/-): RX FIFO at least half full */ 48 | SDI_CTRL_RX_FULL = 25, /**< SDI control register(25) (r/-): RX FIFO full */ 49 | SDI_CTRL_TX_EMPTY = 26, /**< SDI control register(26) (r/-): TX FIFO empty */ 50 | SDI_CTRL_TX_NHALF = 27, /**< SDI control register(27) (r/-): TX FIFO not at least half full */ 51 | SDI_CTRL_TX_FULL = 28, /**< SDI control register(28) (r/-): TX FIFO full */ 52 | 53 | SDI_CTRL_CS_ACTIVE = 31 /**< SDI control register(31) (r/-): Chip-select is active when set */ 54 | }; 55 | /**@}*/ 56 | 57 | 58 | /**********************************************************************//** 59 | * @name Prototypes 60 | **************************************************************************/ 61 | /**@{*/ 62 | int neorv32_sdi_available(void); 63 | void neorv32_sdi_setup(uint32_t irq_mask); 64 | void neorv32_sdi_disable(void); 65 | void neorv32_sdi_enable(void); 66 | int neorv32_sdi_get_fifo_depth(void); 67 | int neorv32_sdi_put(uint8_t data); 68 | int neorv32_sdi_get(uint8_t* data); 69 | int neorv32_sdi_check_cs(void); 70 | /**@}*/ 71 | 72 | 73 | #endif // NEORV32_SDI_H 74 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_smp.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_smp.h 11 | * @brief Symmetric multiprocessing (SMP) library header file. 12 | */ 13 | 14 | #ifndef NEORV32_SMP_H 15 | #define NEORV32_SMP_H 16 | 17 | /**********************************************************************//** 18 | * @name Prototypes 19 | **************************************************************************/ 20 | /**@{*/ 21 | int neorv32_smp_launch(int (*entry_point)(void), uint8_t* stack_memory, size_t stack_size_bytes); 22 | /**@}*/ 23 | 24 | /**********************************************************************//** 25 | * Get core/hart ID of the CPU that is executing this function. 26 | * @return Core ID from mhartid CSR. 27 | **************************************************************************/ 28 | inline uint32_t __attribute__ ((always_inline)) neorv32_smp_whoami(void) { 29 | return neorv32_cpu_csr_read(CSR_MHARTID); 30 | } 31 | 32 | #endif // NEORV32_SMP_H 33 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_trng.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_trng.h 11 | * @brief True Random Number Generator (TRNG) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_TRNG_H 15 | #define NEORV32_TRNG_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: True Random Number Generator (TRNG) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** TRNG module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | uint32_t CTRL; /**< offset 0: control register (#NEORV32_TRNG_CTRL_enum) */ 27 | const uint32_t DATA; /**< offset 4: random data register (#NEORV32_TRNG_DATA_enum) */ 28 | } neorv32_trng_t; 29 | 30 | /** TRNG module hardware handle (#neorv32_trng_t) */ 31 | #define NEORV32_TRNG ((neorv32_trng_t*) (NEORV32_TRNG_BASE)) 32 | 33 | /** TRNG control register bits */ 34 | enum NEORV32_TRNG_CTRL_enum { 35 | TRNG_CTRL_EN = 0, /**< TRNG data register(0) (r/w): TRNG enable */ 36 | TRNG_CTRL_FIFO_CLR = 1, /**< TRNG data register(1) (-/w): Clear data FIFO (auto clears) */ 37 | TRNG_CTRL_FIFO_LSB = 2, /**< TRNG data register(2) (r/-): log2(FIFO size), LSB */ 38 | TRNG_CTRL_FIFO_MSB = 5, /**< TRNG data register(5) (r/-): log2(FIFO size), MSB */ 39 | TRNG_CTRL_SIM_MODE = 6, /**< TRNG data register(6) (r/-): PRNG mode (simulation mode) */ 40 | TRNG_CTRL_AVAIL = 7 /**< TRNG data register(7) (r/-): Random data available */ 41 | }; 42 | 43 | /** TRNG data register bits */ 44 | enum NEORV32_TRNG_DATA_enum { 45 | TRNG_DATA_LSB = 0, /**< TRNG control register(0) (r/-): Random data byte, bit 0 */ 46 | TRNG_DATA_MSB = 7 /**< TRNG control register(7) (r/-): Random data byte, bit 7 */ 47 | }; 48 | /**@}*/ 49 | 50 | 51 | /**********************************************************************//** 52 | * @name Prototypes 53 | **************************************************************************/ 54 | /**@{*/ 55 | int neorv32_trng_available(void); 56 | void neorv32_trng_enable(void); 57 | void neorv32_trng_disable(void); 58 | void neorv32_trng_fifo_clear(void); 59 | int neorv32_trng_get_fifo_depth(void); 60 | int neorv32_trng_get(uint8_t *data); 61 | int neorv32_trng_check_sim_mode(void); 62 | /**@}*/ 63 | 64 | 65 | #endif // NEORV32_TRNG_H 66 | -------------------------------------------------------------------------------- /sw/lib/include/neorv32_wdt.h: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_wdt.h 11 | * @brief Watchdog Timer (WDT) HW driver header file. 12 | */ 13 | 14 | #ifndef NEORV32_WDT_H 15 | #define NEORV32_WDT_H 16 | 17 | #include 18 | 19 | 20 | /**********************************************************************//** 21 | * @name IO Device: Watchdog Timer (WDT) 22 | **************************************************************************/ 23 | /**@{*/ 24 | /** WDT module prototype */ 25 | typedef volatile struct __attribute__((packed,aligned(4))) { 26 | uint32_t CTRL; /**< offset 0: control register (#NEORV32_WDT_CTRL_enum) */ 27 | uint32_t RESET; /**< offset 4: WDT reset trigger (write password to "feed" watchdog) */ 28 | } neorv32_wdt_t; 29 | 30 | /** WDT module hardware handle (#neorv32_wdt_t) */ 31 | #define NEORV32_WDT ((neorv32_wdt_t*) (NEORV32_WDT_BASE)) 32 | 33 | /** WDT control register bits */ 34 | enum NEORV32_WDT_CTRL_enum { 35 | WDT_CTRL_EN = 0, /**< WDT control register(0) (r/w): Watchdog enable */ 36 | WDT_CTRL_LOCK = 1, /**< WDT control register(1) (r/w): Lock write access to control register, clears on reset only */ 37 | WDT_CTRL_STRICT = 2, /**< WDT control register(2) (r/w): Force hardware reset if reset password is incorrect or if write attempt to locked CTRL register */ 38 | WDT_CTRL_RCAUSE_LO = 3, /**< WDT control register(3) (r/-): Cause of last system reset - low */ 39 | WDT_CTRL_RCAUSE_HI = 4, /**< WDT control register(4) (r/-): Cause of last system reset - high */ 40 | 41 | WDT_CTRL_TIMEOUT_LSB = 8, /**< WDT control register(8) (r/w): Timeout value, LSB */ 42 | WDT_CTRL_TIMEOUT_MSB = 31 /**< WDT control register(31) (r/w): Timeout value, MSB */ 43 | }; 44 | /**@}*/ 45 | 46 | 47 | /**********************************************************************//** 48 | * Reset Password 49 | **************************************************************************/ 50 | #define WDT_PASSWORD (0x709D1AB3) 51 | 52 | 53 | /**********************************************************************//** 54 | * Reset Cause 55 | **************************************************************************/ 56 | enum NEORV32_WDT_RCAUSE_enum { 57 | WDT_RCAUSE_EXT = 0b00, /**< Reset caused by external signal/pin */ 58 | WDT_RCAUSE_OCD = 0b01, /**< Reset caused by on-chip debugger */ 59 | WDT_RCAUSE_TMO = 0b10, /**< Reset caused by watchdog timer timeout */ 60 | WDT_RCAUSE_ACC = 0b11 /**< Reset caused by watchdog timer invalid access */ 61 | }; 62 | 63 | 64 | /**********************************************************************//** 65 | * @name Prototypes 66 | **************************************************************************/ 67 | /**@{*/ 68 | int neorv32_wdt_available(void); 69 | void neorv32_wdt_setup(uint32_t timeout, int lock, int strict); 70 | int neorv32_wdt_disable(void); 71 | void neorv32_wdt_feed(uint32_t password); 72 | void neorv32_wdt_force_hwreset(void); 73 | int neorv32_wdt_get_cause(void); 74 | /**@}*/ 75 | 76 | 77 | #endif // NEORV32_WDT_H 78 | -------------------------------------------------------------------------------- /sw/lib/source/neorv32_cfs.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_cfs.c 11 | * @brief Custom Functions Subsystem (CFS) HW driver source file. 12 | * 13 | * @warning There are no "real" CFS driver functions available here, because these functions are defined by the actual hardware. 14 | * @warning Hence, the CFS designer has to provide the actual driver functions. 15 | * 16 | * @note These functions should only be used if the CFS was synthesized (IO_CFS_EN = true). 17 | * 18 | * @see https://stnolting.github.io/neorv32/sw/files.html 19 | */ 20 | 21 | #include 22 | 23 | 24 | /**********************************************************************//** 25 | * Check if custom functions subsystem was synthesized. 26 | * 27 | * @return 0 if CFS was not synthesized, 1 if CFS is available. 28 | **************************************************************************/ 29 | int neorv32_cfs_available(void) { 30 | 31 | if (NEORV32_SYSINFO->SOC & (1 << SYSINFO_SOC_IO_CFS)) { 32 | return 1; 33 | } 34 | else { 35 | return 0; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /sw/lib/source/neorv32_cpu_cfu.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_cpu_cfu.c 11 | * @brief CPU Core custom functions unit HW driver source file. 12 | * 13 | * @see https://stnolting.github.io/neorv32/sw/files.html 14 | */ 15 | 16 | #include 17 | 18 | 19 | /**********************************************************************//** 20 | * Check if custom functions unit was synthesized. 21 | * 22 | * @return 0 if CFU was not synthesized, 1 if CFU is available. 23 | **************************************************************************/ 24 | int neorv32_cpu_cfu_available(void) { 25 | 26 | // this is an ISA extension - not a SoC module 27 | if (neorv32_cpu_csr_read(CSR_MXISA) & (1 << CSR_MXISA_ZXCFU)) { 28 | return 1; 29 | } 30 | else { 31 | return 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sw/lib/source/neorv32_gptmr.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_gptmr.c 11 | * @brief General purpose timer (GPTMR) HW driver source file. 12 | */ 13 | 14 | #include 15 | 16 | 17 | /**********************************************************************//** 18 | * Check if general purpose timer unit was synthesized. 19 | * 20 | * @return 0 if GPTMR was not synthesized, 1 if GPTMR is available. 21 | **************************************************************************/ 22 | int neorv32_gptmr_available(void) { 23 | 24 | if (NEORV32_SYSINFO->SOC & (1 << SYSINFO_SOC_IO_GPTMR)) { 25 | return 1; 26 | } 27 | else { 28 | return 0; 29 | } 30 | } 31 | 32 | 33 | /**********************************************************************//** 34 | * Reset, enable and configure general purpose timer. 35 | * 36 | * @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum. 37 | * @param[in] threshold Threshold value, counter will reset to zero when reaching this. 38 | **************************************************************************/ 39 | void neorv32_gptmr_setup(int prsc, uint32_t threshold) { 40 | 41 | NEORV32_GPTMR->CTRL = 0; // reset module 42 | NEORV32_GPTMR->THRES = threshold; 43 | 44 | uint32_t tmp = 0; 45 | tmp |= (uint32_t)(1 & 0x01) << GPTMR_CTRL_EN; 46 | tmp |= (uint32_t)(prsc & 0x07) << GPTMR_CTRL_PRSC0; 47 | NEORV32_GPTMR->CTRL = tmp; 48 | } 49 | 50 | 51 | /**********************************************************************//** 52 | * Disable general purpose timer. 53 | **************************************************************************/ 54 | void neorv32_gptmr_disable(void) { 55 | 56 | NEORV32_GPTMR->CTRL &= ~((uint32_t)(1 << GPTMR_CTRL_EN)); 57 | } 58 | 59 | 60 | /**********************************************************************//** 61 | * Enable general purpose timer. 62 | **************************************************************************/ 63 | void neorv32_gptmr_enable(void) { 64 | 65 | NEORV32_GPTMR->CTRL |= ((uint32_t)(1 << GPTMR_CTRL_EN)); 66 | } 67 | 68 | 69 | /**********************************************************************//** 70 | * Clear pending timer interrupt. 71 | **************************************************************************/ 72 | void neorv32_gptmr_irq_ack(void) { 73 | 74 | NEORV32_GPTMR->CTRL |= ((uint32_t)(1 << GPTMR_CTRL_IRQ_CLR)); 75 | } 76 | -------------------------------------------------------------------------------- /sw/lib/source/neorv32_smp.c: -------------------------------------------------------------------------------- 1 | // ================================================================================ // 2 | // The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 // 3 | // Copyright (c) NEORV32 contributors. // 4 | // Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. // 5 | // Licensed under the BSD-3-Clause license, see LICENSE for details. // 6 | // SPDX-License-Identifier: BSD-3-Clause // 7 | // ================================================================================ // 8 | 9 | /** 10 | * @file neorv32_smp.c 11 | * @brief Symmetric multiprocessing (SMP) library source file. 12 | */ 13 | 14 | #include 15 | 16 | /**********************************************************************//** 17 | * Configure and start SMP core 1. 18 | * 19 | * @warning This function can be executed on core 0 only. 20 | * 21 | * @param[in] entry_point Core's main function; must be of type "int entry_point(void)". 22 | * @param[in] stack_memory Pointer to beginning of core's stack memory array. 23 | * @param[in] stack_size_bytes Core's stack size in bytes. 24 | * @return 0 if launching succeeded, -1 if invalid hart ID or CLINT not available, -2 if core is not responding. 25 | **************************************************************************/ 26 | int neorv32_smp_launch(int (*entry_point)(void), uint8_t* stack_memory, size_t stack_size_bytes) { 27 | 28 | // sanity checks 29 | if ((neorv32_smp_whoami() != 0) || // this can be executed on core0 only 30 | (neorv32_sysinfo_get_numcores() < 2) || // core not available 31 | (neorv32_clint_available() == 0)) { // we need the CLINT 32 | return -1; 33 | } 34 | 35 | // align end of stack to 16-bytes according to the RISC-V ABI (#1021) 36 | uint32_t stack_end = ((uint32_t)stack_memory + (uint32_t)(stack_size_bytes-1)) & 0xfffffff0; 37 | 38 | // setup launch configuration in CLINT.MTIMECMP[hart_id] 39 | NEORV32_CLINT->MTIMECMP[1].uint32[0] = stack_end; // top of core's stack 40 | NEORV32_CLINT->MTIMECMP[1].uint32[1] = (uint32_t)entry_point; // entry point 41 | 42 | // start core by triggering its software interrupt 43 | neorv32_clint_msi_set(1); 44 | 45 | // wait for core start acknowledge 46 | int timeout = 2048; 47 | while (timeout--) { 48 | if (neorv32_clint_msi_get(1) == 0) { 49 | return 0; 50 | } 51 | } 52 | return -2; // core did not respond 53 | } 54 | -------------------------------------------------------------------------------- /sw/ocd-firmware/.gitignore: -------------------------------------------------------------------------------- 1 | *.vhd 2 | -------------------------------------------------------------------------------- /sw/ocd-firmware/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 On-Chip Debugger (OCD) - "Park Loop" Code (Firmware) 2 | 3 | This folder contains the source code for the *execution-based* on-chip debugger code ROM (firmware). 4 | `park_loop.S` contains the "park loop" that is executed when the CPU is in debug mode. This code 5 | is used to communicate with the *debug module (DM)* and is responsible for: 6 | 7 | * acknowledging halt requests 8 | * processing and acknowledging resume requests 9 | * processing and acknowledging "execute program buffer" requests 10 | * executing the program buffer (provided by the DM) 11 | * catching and acknowledging exceptions while in debug mode 12 | 13 | The park loop code is implemented as endless loop that polls the status register of 14 | the *debug memory (DM* module to check for requests from the DM and sets according flags in the 15 | status register to acknowledge these requests. 16 | 17 | :warning: Executing `make clean image` will **NOT** update the actual debugger code ROM that 18 | gets synthesized. The interface with the DM will break if there are any bugs in this code. 19 | However, if you wish to update the code ROM, copy the array content from `neorv32_application_image.vhd` 20 | to the `code_rom_c` constant in `rtl/core/neorv32_debug_dm.vhd`. 21 | -------------------------------------------------------------------------------- /sw/ocd-firmware/debug_rom.ld: -------------------------------------------------------------------------------- 1 | /* ================================================================================ */ 2 | /* NEORV32 CPU - RISC-V GCC Linker Script */ 3 | /* -------------------------------------------------------------------------------- */ 4 | /* "Park loop" code linking for execution-based on-chip debugger'S (OCD) code ROM. */ 5 | /* -------------------------------------------------------------------------------- */ 6 | /* The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 */ 7 | /* Copyright (c) NEORV32 contributors. */ 8 | /* Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. */ 9 | /* Licensed under the BSD-3-Clause license, see LICENSE for details. */ 10 | /* SPDX-License-Identifier: BSD-3-Clause */ 11 | /* ================================================================================ */ 12 | 13 | OUTPUT_FORMAT("elf32-littleriscv") 14 | OUTPUT_ARCH(riscv) 15 | ENTRY(_ocd_start) 16 | 17 | MEMORY 18 | { 19 | dm_code_rom (rx) : ORIGIN = 0xFFFFFE00, LENGTH = 128 20 | } 21 | 22 | SECTIONS 23 | { 24 | .text : 25 | { 26 | KEEP(*(.text.ocd)); 27 | } > dm_code_rom 28 | } 29 | -------------------------------------------------------------------------------- /sw/ocd-firmware/makefile: -------------------------------------------------------------------------------- 1 | override APP_SRC = park_loop.S 2 | override MARCH = rv32e_zicsr_zifencei 3 | override MABI = ilp32e 4 | override LD_SCRIPT = ./debug_rom.ld 5 | 6 | NEORV32_HOME ?= ../.. 7 | include $(NEORV32_HOME)/sw/common/common.mk 8 | -------------------------------------------------------------------------------- /sw/openocd/README.md: -------------------------------------------------------------------------------- 1 | ## NEORV32 OpenOCD Scripts 2 | 3 | * `openocd_neorv32.cfg` For the default **single-core** processor configuration 4 | * `openocd_neorv32.dual_core.cfg` For the **SMP dual-core** processor configuration 5 | 6 | ### Helper Scripts 7 | 8 | The _helper scripts_ are called by the main OpenOCD configuration files. 9 | Hence, these scripts are not meant for stand-alone operation. 10 | 11 | * `authentication.cfg` Authenticate debug access via the RISC-V DM authentication commands. 12 | Modify this file (but not the helper procedures) if you are using a 13 | **custom/non-default authenticator** processor hardware module. 14 | * `interface.cfg` Physical adapter configuration. Adjust this file to match your specific adapter board. 15 | * `target.cfg` CPU core(s) and GDB configuration. This file should not be altered. 16 | -------------------------------------------------------------------------------- /sw/openocd/authentication.cfg: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------- 2 | # Authenticator helper functions. Do not edit. 3 | # ------------------------------------------------------------------- 4 | 5 | # write 32-bit data word to authenticator data input 6 | proc authenticator_write {WDATA} { 7 | riscv authdata_write $WDATA 8 | } 9 | 10 | # read 32-bit data word from authenticator data output 11 | proc authenticator_read {} { 12 | return [riscv authdata_read] 13 | } 14 | 15 | # check if authentication was successful (bit 7 in dmstatus) 16 | proc authenticator_check {} { 17 | set DMSTATUS [riscv dmi_read 0x11] 18 | if { [expr {$DMSTATUS & (1<<7)}] } { 19 | echo "Authentication passed." 20 | } else { 21 | echo "AUTHENTICATION FAILED!" 22 | exit 23 | } 24 | } 25 | 26 | # --------------------------------------------------------- 27 | # Authentication process. 28 | # Adjust this for your custom/non-default authenticator. 29 | # --------------------------------------------------------- 30 | # read challenge 31 | set CHALLENGE [authenticator_read] 32 | # compute response (default authenticator module) 33 | set RESPONSE [expr {$CHALLENGE | 1}] 34 | # send response 35 | authenticator_write $RESPONSE 36 | # success? 37 | authenticator_check 38 | -------------------------------------------------------------------------------- /sw/openocd/interface.cfg: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------- 2 | # Physical interface configuration. 3 | # Adjust this file for your specific debug adapter. 4 | # ------------------------------------------------------------------- 5 | adapter driver ftdi 6 | ftdi vid_pid 0x0403 0x6010 7 | ftdi channel 0 8 | ftdi layout_init 0x0038 0x003b 9 | adapter speed 2000 10 | transport select jtag 11 | -------------------------------------------------------------------------------- /sw/openocd/openocd_neorv32.cfg: -------------------------------------------------------------------------------- 1 | # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 2 | # OpenOCD on-chip debugger configuration file for SINGLE-CORE configuration 3 | 4 | echo "*****************************************" 5 | echo "NEORV32 single-core openOCD configuration" 6 | echo "*****************************************" 7 | 8 | set PATH [ file dirname [ file normalize [ info script ] ] ] 9 | source [file join $PATH target.cfg] 10 | target_setup 1 11 | -------------------------------------------------------------------------------- /sw/openocd/openocd_neorv32.dual_core.cfg: -------------------------------------------------------------------------------- 1 | # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 2 | # OpenOCD on-chip debugger configuration file for DUAL-CORE SMP configuration 3 | 4 | echo "*******************************************" 5 | echo "NEORV32 SMP dual-core openOCD configuration" 6 | echo "*******************************************" 7 | 8 | set PATH [ file dirname [ file normalize [ info script ] ] ] 9 | source [file join $PATH target.cfg] 10 | target_setup 2 11 | -------------------------------------------------------------------------------- /sw/openocd/target.cfg: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------- 2 | # Target configuration and (session) initialization 3 | # Do not edits this file. 4 | # ------------------------------------------------------------------- 5 | proc target_setup { {NUM_CORES 1} } { 6 | 7 | # path of this file 8 | set PATH [ file dirname [ file normalize [ info script ] ] ] 9 | 10 | # configure physical interface 11 | source [file join $PATH interface.cfg] 12 | 13 | set CORENAME neorv32 14 | 15 | # configures JTAG tap 16 | jtag newtap $CORENAME cpu -irlen 5 17 | 18 | # attach core(s) 19 | if { $NUM_CORES == 1 } { 20 | set TARGETNAME $CORENAME.cpu 21 | target create $TARGETNAME riscv -chain-position $TARGETNAME 22 | } elseif { $NUM_CORES == 2 } { 23 | set TARGETNAME_0 $CORENAME.cpu0 24 | set TARGETNAME_1 $CORENAME.cpu1 25 | target create $TARGETNAME_0 riscv -chain-position $CORENAME.cpu -rtos hwthread 26 | target create $TARGETNAME_1 riscv -chain-position $CORENAME.cpu -coreid 1 27 | target smp $TARGETNAME_0 $TARGETNAME_1 28 | } else { 29 | echo "ERROR: Invalid NUM_CORE configuration!" 30 | } 31 | 32 | # GDB server configuration 33 | gdb report_data_abort enable 34 | gdb report_register_access_error enable 35 | 36 | # expose NEORV32-specific CSRs 37 | riscv expose_csrs 2048=cfureg0 38 | riscv expose_csrs 2049=cfureg1 39 | riscv expose_csrs 2050=cfureg2 40 | riscv expose_csrs 2051=cfureg3 41 | riscv expose_csrs 4032=mxisa 42 | 43 | # initialize target 44 | init 45 | 46 | # authenticate 47 | source [file join $PATH authentication.cfg] 48 | 49 | # reset and halt 50 | reset halt 51 | echo "Target RESET and HALTED. Ready for remote connections." 52 | } 53 | -------------------------------------------------------------------------------- /sw/svd/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 System View Description (SVD) File 2 | 3 | Manually created from `sw/lib/include/*. 4 | 5 | * Format: CMSIS-SVD 6 | * Copyright by ARM Ltd, Apache-2.0 License 7 | * Documentation: 8 | * https://www.keil.com/pack/doc/CMSIS/SVD/html/index.html 9 | * https://github.com/ARM-software/CMSIS 10 | * https://github.com/ARM-software/CMSIS_5 11 | --------------------------------------------------------------------------------