├── .github ├── dependabot.yml ├── generate-job-matrix.py ├── impl.dockerfile ├── sim.dockerfile └── workflows │ ├── Containers.yml │ └── Implementation.yml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── cologne_chip ├── .gitignore ├── GateMateA1-EVB │ ├── Makefile │ ├── README.md │ ├── neorv32_gatemate.ccf │ └── neorv32_gatemate.vhd └── README.md ├── gowineda ├── README.md ├── tang-nano-20k │ ├── README.md │ ├── create_project.tcl │ ├── import_neorv32.tcl │ ├── tang-nano-20k_test_setup_bootloader.cst │ └── test_setups │ │ └── neorv32_test_setup_bootloader.vhd ├── tang-nano-9k │ ├── .gitignore │ ├── README.md │ ├── create_project.tcl │ ├── import_neorv32.tcl │ └── tang-nano-9k_test_setup_bootloader.cst └── tools │ └── uart_upload.ps1 ├── osflow ├── .gitignore ├── Makefile ├── PnR_Bit.mk ├── README.md ├── board_tops │ ├── neorv32_Fomu_BoardTop_Minimal.vhd │ ├── neorv32_Fomu_BoardTop_MinimalBoot.vhd │ ├── neorv32_Fomu_BoardTop_MixedLanguage.vhd │ ├── neorv32_Fomu_BoardTop_UP5KDemo.vhd │ ├── neorv32_Fomu_MixedLanguage_ClkGen.v │ ├── neorv32_IceZumAlhambraII_BoardTop_MinimalBoot.vhd │ ├── neorv32_OrangeCrab_BoardTop_MinimalBoot.vhd │ ├── neorv32_ULX3S_BoardTop_MinimalBoot.vhd │ ├── neorv32_UPDuino-v3.0_BoardTop_MinimalBoot.vhd │ ├── neorv32_UPDuino-v3.0_BoardTop_UP5KDemo.vhd │ ├── neorv32_iCE40CW312_BoardTop_MinimalBoot.vhd │ ├── neorv32_iCEBreaker_BoardTop_MinimalBoot.vhd │ ├── neorv32_iCEBreaker_BoardTop_UP5KDemo.vhd │ ├── neorv32_iCESugar-v1.5_BoardTop_Minimal.vhd │ └── neorv32_iCESugar-v1.5_BoardTop_MinimalBoot.vhd ├── boards │ ├── Fomu.mk │ ├── IceZumAlhambraII.mk │ ├── OrangeCrab.mk │ ├── ULX3S.mk │ ├── UPDuino-v3.0.mk │ ├── iCE40CW312.mk │ ├── iCEBreaker.mk │ ├── iCESugar-v1.5.mk │ └── index.mk ├── common.mk ├── constraints │ ├── Fomu-evt2.pcf │ ├── Fomu-evt3.pcf │ ├── Fomu-hacker.pcf │ ├── Fomu-pvt.pcf │ ├── OrangeCrab.lpf │ └── ULX3S.lpf ├── devices │ ├── ecp5 │ │ └── ecp5_components.vhd │ └── ice40 │ │ ├── neorv32_dmem.ice40up_spram.vhd │ │ ├── neorv32_imem.ice40up_spram.vhd │ │ ├── sb_ice40_components.v │ │ └── sb_ice40_components.vhd ├── filesets.mk ├── synthesis.mk └── tools.mk ├── quartus ├── de0-nano-test-setup-avalonmm-wrapper │ ├── .gitignore │ ├── README.md │ ├── de0-nano-test-setup.qpf │ ├── de0-nano-test-setup.qsf │ ├── dmem_ram.qip │ ├── dmem_ram.vhd │ └── neorv32_test_setup_avalonmm.vhd ├── de0-nano-test-setup-qsys │ ├── .gitignore │ ├── README.md │ ├── User_Components.ipx │ ├── de0-nano-test-setup.qpf │ ├── de0-nano-test-setup.qsf │ ├── de0-nano-test-setup.sdc │ ├── figures │ │ └── neorv32_platform_designer.png │ ├── neorv32_ProcessorTop_Test.vhd │ └── neorv32_test_qsys.qsys ├── de0-nano-test-setup │ ├── .gitignore │ ├── README.md │ └── create_project.tcl ├── de10-nano-test-setup │ ├── .gitignore │ ├── README.md │ ├── constraints │ │ └── neorv32_test_setup_bootloader.sdc │ ├── create_project.tcl │ └── neorv32_test_setup_bootloader.vhd ├── neorv32_SystemTop_AvalonMM.vhd ├── neorv32_qsys_component │ ├── README.md │ ├── figures │ │ ├── gui_settings.png │ │ └── overview.png │ ├── neorv32_qsys.qip │ ├── neorv32_qsys.vhd │ └── neorv32_qsys_hw.tcl ├── on-chip-debugger-intel │ ├── .gitignore │ ├── README.md │ ├── compile_project.tcl │ ├── create_project.tcl │ ├── neorv32_debug_dtm.intel.vhd │ ├── neorv32_on_chip_debugger_intel_top.vhd │ └── openocd_neorv32_intel.cfg └── terasic-cyclone-V-gx-starter-kit-test-setup │ ├── README.md │ └── create_project.tcl ├── radiant ├── UPduino_v3 │ ├── .gitignore │ ├── README.md │ ├── neorv32_dmem.ice40up_spram.vhd │ ├── neorv32_imem.ice40up_spram.vhd │ ├── neorv32_upduino_v3.pdc │ ├── neorv32_upduino_v3.rdf │ ├── neorv32_upduino_v3_top.vhd │ └── source │ │ └── impl_1.xcf └── iCEBreaker │ ├── .gitignore │ ├── README.md │ ├── iCEBreaker.rdf │ ├── iCEBreaker1.sty │ ├── icebreaker.pdc │ ├── icebreaker_top.vhd │ ├── neorv32_dmem.ice40up_spram.vhd │ ├── neorv32_imem.ice40up_spram.vhd │ ├── source │ └── impl_1.xcf │ └── system_pll │ ├── rtl │ └── system_pll.v │ └── system_pll.ipx └── vivado ├── README.md ├── arty-a7-test-setup ├── .gitignore ├── README.md ├── arty_a7_test_setup.xdc └── create_project.tcl ├── nexys-a7-test-setup ├── .gitignore ├── README.md ├── create_project.tcl └── nexys_a7_test_setup.xdc └── z7-nano-test-setup ├── .gitignore ├── README.md ├── create_project.tcl ├── pin_constraints.xdc └── timings.xdc /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gitsubmodule 4 | directory: / 5 | commit-message: 6 | prefix: '[Dependabot]' 7 | schedule: 8 | interval: weekly 9 | time: '04:00' 10 | open-pull-requests-limit: 99 11 | -------------------------------------------------------------------------------- /.github/generate-job-matrix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | print('::set-output name=matrix::' + str([ 4 | { 5 | 'board': 'UPDuino-v3.0', 6 | 'design': 'MinimalBoot', 7 | 'bitstream': 'neorv32_UPDuino-v3.0_MinimalBoot.bit' 8 | }, { 9 | 'board': 'UPDuino-v3.0', 10 | 'design': 'UP5KDemo', 11 | 'bitstream': 'neorv32_UPDuino-v3.0_UP5KDemo.bit' 12 | }, { 13 | 'board': 'Fomu', 14 | 'design': 'Minimal', 15 | 'bitstream': 'neorv32_Fomu_pvt_Minimal.bit' 16 | }, { 17 | 'board': 'Fomu', 18 | 'design': 'MinimalBoot', 19 | 'bitstream': 'neorv32_Fomu_pvt_MinimalBoot.bit' 20 | }, { 21 | 'board': 'Fomu', 22 | 'design': 'MixedLanguage', 23 | 'bitstream': 'neorv32_Fomu_pvt_MixedLanguage.bit' 24 | }, { 25 | 'board': 'Fomu', 26 | 'design': 'UP5KDemo', 27 | 'bitstream': 'neorv32_Fomu_pvt_UP5KDemo.bit' 28 | }, { 29 | 'board': 'iCEBreaker', 30 | 'design': 'MinimalBoot', 31 | 'bitstream': 'neorv32_iCEBreaker_MinimalBoot.bit' 32 | }, { 33 | 'board': 'iCEBreaker', 34 | 'design': 'UP5KDemo', 35 | 'bitstream': 'neorv32_iCEBreaker_UP5KDemo.bit' 36 | }, { 37 | 'board': 'iCESugar-v1.5', 38 | 'design': 'Minimal', 39 | 'bitstream': 'neorv32_iCESugar-v1.5_Minimal.bit' 40 | }, { 41 | 'board': 'iCESugar-v1.5', 42 | 'design': 'MinimalBoot', 43 | 'bitstream': 'neorv32_iCESugar-v1.5_MinimalBoot.bit' 44 | }, { 45 | 'board': 'OrangeCrab', 46 | 'design': 'MinimalBoot', 47 | 'bitstream': 'neorv32_OrangeCrab_r02-25F_MinimalBoot.bit' 48 | }, { 49 | 'board': 'IceZumAlhambraII', 50 | 'design': 'MinimalBoot', 51 | 'bitstream': 'neorv32_IceZumAlhambraII_MinimalBoot.bit' 52 | }, { 53 | 'board': 'ULX3S', 54 | 'design': 'MinimalBoot', 55 | 'bitstream': 'neorv32_ULX3S_MinimalBoot.bit' 56 | }, { 57 | 'board': 'iCE40CW312', 58 | 'design': 'MinimalBoot', 59 | 'bitstream': 'neorv32_iCE40CW312_MinimalBoot.bit' 60 | }])) 61 | -------------------------------------------------------------------------------- /.github/impl.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/hdl/debian/bullseye/impl 2 | 3 | RUN apt-get update -qq \ 4 | && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ 5 | python3-pip \ 6 | && pip3 install wheel setuptools \ 7 | && pip3 install doit \ 8 | && apt-get autoclean && apt-get clean && apt-get -y autoremove \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | ENV GHDL_PLUGIN_MODULE=ghdl 12 | -------------------------------------------------------------------------------- /.github/sim.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/hdl/debian/bullseye/sim/osvb 2 | 3 | RUN apt-get update -qq \ 4 | && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ 5 | g++ \ 6 | git \ 7 | make \ 8 | python3-pip \ 9 | time \ 10 | && apt-get autoclean && apt-get clean && apt-get -y autoremove \ 11 | && rm -rf /var/lib/apt/lists/* \ 12 | && pip3 install wheel setuptools \ 13 | && pip3 install doit \ 14 | && mkdir -p /opt/riscv \ 15 | && curl -fsSL https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz | \ 16 | tar -xzf - -C /opt/riscv \ 17 | && ls -al /opt/riscv 18 | 19 | ENV PATH $PATH:/opt/riscv/xpack-riscv-none-elf-gcc-14.2.0-3/bin 20 | -------------------------------------------------------------------------------- /.github/workflows/Containers.yml: -------------------------------------------------------------------------------- 1 | name: Containers 2 | 3 | on: 4 | push: 5 | paths: 6 | - '.github/*.dockerfile' 7 | - '.github/workflows/Containers.yml' 8 | schedule: 9 | - cron: '0 0 * * 5' 10 | workflow_dispatch: 11 | 12 | jobs: 13 | 14 | Container: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | image: 20 | - impl 21 | - sim 22 | name: '🛳️ ${{ matrix.image }}' 23 | 24 | steps: 25 | 26 | - name: '🧰 Repository Checkout' 27 | uses: actions/checkout@v4 28 | 29 | - name: '⛴️ Build neorv32/${{ matrix.image }}' 30 | run: docker build -t ghcr.io/stnolting/neorv32/${{ matrix.image }} - < .github/${{ matrix.image }}.dockerfile 31 | 32 | - name: '🔑 Login to ghcr.io' 33 | if: github.event_name != 'pull_request' 34 | uses: docker/login-action@v3 35 | with: 36 | registry: ghcr.io 37 | username: gha 38 | password: ${{ secrets.PACKAGE_TOKEN }} 39 | 40 | - name: '🛰️ Push image to ghcr.io' 41 | run: docker push ghcr.io/stnolting/neorv32/${{ matrix.image }} 42 | -------------------------------------------------------------------------------- /.github/workflows/Implementation.yml: -------------------------------------------------------------------------------- 1 | name: Implementation 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: 7 | - cron: '0 0 * * 5' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | 12 | 13 | Matrix: 14 | runs-on: ubuntu-latest 15 | outputs: 16 | matrix: ${{ steps.generate.outputs.matrix }} 17 | 18 | steps: 19 | 20 | - name: '🧰 Repository Checkout' 21 | uses: actions/checkout@v4 22 | 23 | - name: '🔧 Generate examples matrix' 24 | id: generate 25 | run: ./.github/generate-job-matrix.py 26 | 27 | 28 | All-in-one: 29 | needs: Matrix 30 | runs-on: ubuntu-latest 31 | strategy: 32 | fail-fast: false 33 | matrix: 34 | include: ${{ fromJson(needs.Matrix.outputs.matrix) }} 35 | name: '🛳️ All-in-one | ${{ matrix.board }} · ${{ matrix.design }}' 36 | 37 | steps: 38 | 39 | - name: '🧰 Repository Checkout' 40 | uses: actions/checkout@v4 41 | with: 42 | fetch-depth: 0 43 | submodules: recursive 44 | 45 | - name: '🚧 Generate ${{ matrix.board }} ${{ matrix.design }} bitstream' 46 | uses: docker://ghcr.io/stnolting/neorv32/impl 47 | with: 48 | args: make -C osflow BOARD=${{ matrix.board }} ${{ matrix.design }} 49 | 50 | - name: '📤 Upload Artifact: ${{ matrix.board }} ${{ matrix.design }} bitstream and reports' 51 | uses: actions/upload-artifact@v4 52 | with: 53 | name: ${{ matrix.board }}-${{ matrix.design }} 54 | path: | 55 | osflow/${{ matrix.bitstream }} 56 | osflow/${{ matrix.board }}/*-report.txt 57 | 58 | 59 | # Windows: 60 | # needs: Matrix 61 | # runs-on: windows-latest 62 | # strategy: 63 | # fail-fast: false 64 | # matrix: 65 | # include: ${{ fromJson(needs.Matrix.outputs.matrix) }} 66 | # name: '🟦 MINGW64 | ${{ matrix.board }} · ${{ matrix.design }}' 67 | # defaults: 68 | # run: 69 | # shell: msys2 {0} 70 | # steps: 71 | # 72 | # - name: '🟦 Setup MSYS2' 73 | # uses: msys2/setup-msys2@v2 74 | # with: 75 | # msystem: MINGW64 76 | # update: true 77 | # install: make 78 | # pacboy: > 79 | # yosys:p 80 | # nextpnr:p 81 | # icestorm:p 82 | # prjtrellis:p 83 | # 84 | # - name: '⚙️ git config' 85 | # run: git config --global core.autocrlf input 86 | # shell: bash 87 | # 88 | # - name: '🧰 Checkout' 89 | # uses: actions/checkout@v4 90 | # with: 91 | # fetch-depth: 0 92 | # submodules: recursive 93 | # 94 | # - name: '🚧 Generate ${{ matrix.board }} ${{ matrix.design }} bitstream' 95 | # run: make -C osflow BOARD=${{ matrix.board }} ${{ matrix.design }} 96 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | **/bin 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "neorv32"] 2 | path = neorv32 3 | url = https://github.com/stnolting/neorv32 4 | ignore = dirty 5 | [submodule "constraints"] 6 | path = constraints 7 | url = https://github.com/hdl/constraints 8 | ignore = dirty 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [stnolting@gmail.com](mailto:stnolting@gmail.com). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Stephan Nolting 4 | 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 | -------------------------------------------------------------------------------- /cologne_chip/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.v 3 | *.id* 4 | *.net 5 | *.ref* 6 | *.pos 7 | *.pin 8 | *.cdf 9 | *.cfg 10 | *.prn 11 | *.txt 12 | *.pathes 13 | *_00* 14 | -------------------------------------------------------------------------------- /cologne_chip/GateMateA1-EVB/Makefile: -------------------------------------------------------------------------------- 1 | # Cologne Chip GateMate Makefile 2 | # (c) 2024 Cologne Chip, based on the original config.sh 3 | # (c) 2025 S. Nolting, adapted for neorv32-setups 4 | 5 | # ----------------------------------------------------------------------------- 6 | # project setup 7 | # ----------------------------------------------------------------------------- 8 | TOP = neorv32_gatemate 9 | VHDL_SRC = $(TOP).vhd 10 | GHDLFLAGS = --work=neorv32 --warn-no-binding -C --ieee=synopsys 11 | SYNFLAGS = -nomx8 12 | PRFLAGS = -ccf $(TOP).ccf -cCP +uCIO 13 | OFLFLAGS = -c dirtyJtag 14 | NETLIST = $(TOP).synth.v 15 | 16 | # ----------------------------------------------------------------------------- 17 | # cologne chip toolchain 18 | # ----------------------------------------------------------------------------- 19 | CCTOOLS = /opt/cc-toolchain 20 | YOSYS = $(CCTOOLS)/bin/yosys/yosys 21 | PR = $(CCTOOLS)/bin/p_r/p_r 22 | OFL = $(CCTOOLS)/bint/openFPGALoader/openFPGALoader 23 | 24 | # ----------------------------------------------------------------------------- 25 | # neorv32 sources 26 | # ----------------------------------------------------------------------------- 27 | NEORV32_HOME = ../../neorv32 28 | VHDL_SRC += $(NEORV32_HOME)/rtl/core/*.vhd 29 | 30 | # ----------------------------------------------------------------------------- 31 | # targets 32 | # ----------------------------------------------------------------------------- 33 | .PHONY: help 34 | .DEFAULT_GOAL := help 35 | 36 | all: clean synth impl 37 | 38 | info: 39 | $(YOSYS) -V 40 | $(PR) -h 41 | 42 | synth: $(VHDL_SRC) 43 | $(YOSYS) -ql synth.log -p 'ghdl $(GHDLFLAGS) $^ -e $(TOP); synth_gatemate -top $(TOP) $(SYNFLAGS) -vlog $(NETLIST)' 44 | 45 | impl: 46 | $(PR) -i $(NETLIST) -o $(TOP) $(PRFLAGS) > impl.log 47 | 48 | jtag: 49 | $(OFL) $(OFLFLAGS) $(TOP)_00.cfg 50 | 51 | clean: 52 | @rm -rf $(NETLIST) *.log *_00* *.id *.net *.pathes *.pos *.txt *.refcomp *.refparam *.refwire *.prn 53 | 54 | help: 55 | @echo "Cologne Chip GateMate Makefile" 56 | @echo "" 57 | @echo "Configuration:" 58 | @echo " TOP = $(TOP)" 59 | @echo " NETLIST = $(NETLIST)" 60 | @echo " CCTOOLS = $(CCTOOLS)" 61 | @echo " GHDLFLAGS = $(GHDLFLAGS)" 62 | @echo " SYNFLAGS = $(SYNFLAGS)" 63 | @echo " PRFLAGS = $(PRFLAGS)" 64 | @echo " OFLFLAGS = $(OFLFLAGS)" 65 | @echo "" 66 | @echo "Targets:" 67 | @echo " help - show this text" 68 | @echo " info - show toolchain version (Yosys and P_R)" 69 | @echo " clean - remove all build artifacts" 70 | @echo " synth - synthesize design (including technology mapping) and generate netlist" 71 | @echo " impl - implement design (place and route) and generate bitstream" 72 | @echo " jtag - upload bitstream via JTAG" 73 | @echo " all - clean + synth + impl" 74 | @echo "" 75 | -------------------------------------------------------------------------------- /cologne_chip/GateMateA1-EVB/neorv32_gatemate.ccf: -------------------------------------------------------------------------------- 1 | # Pin mapping for the Olimex GateMateA1-EVB(-2M) FPGA board 2 | 3 | # on-board clock generator, 10MHz 4 | Pin_in "clk_i" Loc = "IO_SB_A8"; 5 | 6 | # on-board user button, low-active 7 | Pin_in "rstn_i" Loc = "IO_SB_B7" | SCHMITT_TRIGGER=true; 8 | 9 | # on-board user LED, low-active 10 | Pin_out "led_o" Loc = "IO_SB_B6"; 11 | 12 | # on-board SPI flash (requires +uCIO PR flag) 13 | Pin_out "sck_o" Loc = "IO_WA_B8"; 14 | Pin_out "csn_o" Loc = "IO_WA_A8"; 15 | Pin_out "sdo_o" Loc = "IO_WA_B7"; 16 | Pin_in "sdi_i" Loc = "IO_WA_A7"; 17 | 18 | # PMOD connector 19 | Pin_out "txd_o" Loc = "IO_EA_A4"; # pin 1 20 | Pin_in "rxd_i" Loc = "IO_EA_B4" | SCHMITT_TRIGGER=true; # pin 7 21 | Pin_inout "scl_io" Loc = "IO_EA_A5"; # pin 2 22 | Pin_inout "sda_io" Loc = "IO_EA_B5"; # pin 8 23 | -------------------------------------------------------------------------------- /cologne_chip/GateMateA1-EVB/neorv32_gatemate.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 Setup for the Olimex GateMateA1-EVB-2M development board -- 3 | -- featuring the Cologne Chip GateMate CCGM1A1 FPGA. -- 4 | -- -------------------------------------------------------------------------------- -- 5 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 6 | -- Copyright (c) NEORV32 contributors. -- 7 | -- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. -- 8 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 9 | -- SPDX-License-Identifier: BSD-3-Clause -- 10 | -- ================================================================================ -- 11 | 12 | library ieee; 13 | use ieee.std_logic_1164.all; 14 | 15 | library neorv32; 16 | use neorv32.neorv32_package.all; 17 | 18 | entity neorv32_gatemate is 19 | port ( 20 | -- clock and reset -- 21 | clk_i : in std_ulogic; 22 | rstn_i : in std_ulogic; 23 | -- spi flash -- 24 | sck_o : out std_ulogic; 25 | csn_o : out std_ulogic; 26 | sdo_o : out std_ulogic; 27 | sdi_i : in std_ulogic; 28 | -- i2c host -- 29 | scl_io : inout std_logic; 30 | sda_io : inout std_logic; 31 | -- status led -- 32 | led_o : out std_ulogic; 33 | -- uart -- 34 | txd_o : out std_ulogic; 35 | rxd_i : in std_ulogic 36 | ); 37 | end entity; 38 | 39 | architecture neorv32_gatemate_rtl of neorv32_gatemate is 40 | 41 | component CC_PLL is 42 | generic ( 43 | REF_CLK : string; -- reference input in MHz 44 | OUT_CLK : string; -- pll output frequency in MHz 45 | PERF_MD : string; -- LOWPOWER, ECONOMY, SPEED 46 | LOW_JITTER : integer; -- 0: disable, 1: enable low jitter mode 47 | CI_FILTER_CONST : integer; -- optional CI filter constant 48 | CP_FILTER_CONST : integer -- optional CP filter constant 49 | ); 50 | port ( 51 | CLK_REF : in std_logic; 52 | USR_CLK_REF : in std_logic; 53 | CLK_FEEDBACK : in std_logic; 54 | USR_LOCKED_STDY_RST : in std_logic; 55 | USR_PLL_LOCKED_STDY : out std_logic; 56 | USR_PLL_LOCKED : out std_logic; 57 | CLK0 : out std_logic; 58 | CLK90 : out std_logic; 59 | CLK180 : out std_logic; 60 | CLK270 : out std_logic; 61 | CLK_REF_OUT : out std_logic 62 | ); 63 | end component; 64 | 65 | signal clk_sys : std_logic; 66 | signal con_gpio_out : std_ulogic_vector(31 downto 0); 67 | signal con_spi_csn : std_ulogic_vector(7 downto 0); 68 | signal twi_sda_i, twi_sda_o, twi_scl_i, twi_scl_o : std_ulogic; 69 | 70 | begin 71 | 72 | -- System PLL ----------------------------------------------------------------------------- 73 | -- ------------------------------------------------------------------------------------------- 74 | socket_pll: CC_PLL 75 | generic map ( 76 | REF_CLK => "10.0", 77 | OUT_CLK => "25.0", 78 | PERF_MD => "SPEED", 79 | LOW_JITTER => 1, 80 | CI_FILTER_CONST => 2, 81 | CP_FILTER_CONST => 4 82 | ) 83 | port map ( 84 | CLK_REF => clk_i, 85 | USR_CLK_REF => '0', 86 | CLK_FEEDBACK => '0', 87 | USR_LOCKED_STDY_RST => '0', 88 | USR_PLL_LOCKED_STDY => open, 89 | USR_PLL_LOCKED => open, 90 | CLK0 => clk_sys, 91 | CLK90 => open, 92 | CLK180 => open, 93 | CLK270 => open, 94 | CLK_REF_OUT => open 95 | ); 96 | 97 | -- The Core Of The Problem ---------------------------------------------------------------- 98 | -- ------------------------------------------------------------------------------------------- 99 | neorv32_top_inst: neorv32_top 100 | generic map ( 101 | -- Processor Clocking -- 102 | CLOCK_FREQUENCY => 25_000_000, -- core frequency in Hz 103 | BOOT_MODE_SELECT => 0, -- boot via build-in bootloader 104 | -- RISC-V CPU Extensions -- 105 | RISCV_ISA_C => true, 106 | RISCV_ISA_M => true, 107 | RISCV_ISA_Zicntr => true, 108 | -- Internal instruction memory -- 109 | IMEM_EN => true, 110 | IMEM_SIZE => 16*1024, 111 | -- Internal data memory -- 112 | DMEM_EN => true, 113 | DMEM_SIZE => 8*1024, 114 | -- Processor peripherals -- 115 | IO_GPIO_NUM => 1, 116 | IO_CLINT_EN => true, 117 | IO_UART0_EN => true, 118 | IO_SPI_EN => true, 119 | IO_TWI_EN => true 120 | ) 121 | port map ( 122 | -- Global control -- 123 | clk_i => std_ulogic(clk_sys), 124 | rstn_i => rstn_i, 125 | -- GPIO (available if IO_GPIO_NUM > 0) -- 126 | gpio_o => con_gpio_out, 127 | gpio_i => (others => '0'), 128 | -- primary UART0 (available if IO_UART0_EN = true) -- 129 | uart0_txd_o => txd_o, 130 | uart0_rxd_i => rxd_i, 131 | -- SPI (available if IO_SPI_EN = true) -- 132 | spi_clk_o => sck_o, 133 | spi_dat_o => sdo_o, 134 | spi_dat_i => sdi_i, 135 | spi_csn_o => con_spi_csn, 136 | -- TWI (available if IO_TWI_EN = true) -- 137 | twi_sda_i => twi_sda_i, 138 | twi_sda_o => twi_sda_o, 139 | twi_scl_i => twi_scl_i, 140 | twi_scl_o => twi_scl_o 141 | ); 142 | 143 | -- low-active status LED -- 144 | led_o <= not con_gpio_out(0); 145 | 146 | -- on-board SPI flash -- 147 | csn_o <= con_spi_csn(0); 148 | 149 | -- TWI tri-state drivers -- 150 | scl_io <= '0' when (twi_scl_o = '0') else 'Z'; 151 | sda_io <= '0' when (twi_sda_o = '0') else 'Z'; 152 | twi_scl_i <= std_ulogic(scl_io); 153 | twi_sda_i <= std_ulogic(sda_io); 154 | 155 | end architecture; 156 | -------------------------------------------------------------------------------- /cologne_chip/README.md: -------------------------------------------------------------------------------- 1 | ## Cologne Chip GateMate Setups 2 | 3 | #### Available Setups 4 | 5 | * [GateMateA1-EVB](GateMateA1-EVB) 6 | 7 | > [!TIP] 8 | > See the sub-folder(s) for more information. 9 | 10 | -------------------------------------------------------------------------------- /gowineda/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Gowin EDA Example Setups 2 | 3 | ## How To Run 4 | 5 | The `create_project.tcl` TCL script in the board subdirectories can be used for creating a complete Gowin EDA project and for running the implementation. 6 | If not already available, this script will create a `work` folder in those subdirectories. Assuming that `gw_sh` is on you path, you can run `gw_sh create_project.tcl`. You can also pass arguments like `gw_sh create_project.tcl --project-name myproject --project-path "~/Sources"`. 7 | 8 | Arguments do not work if you are already inside the Gowin shell (e.g. `% source create_project.tcl`), at least not as of version 1.9.9. You can set environment variables instead, like `set nrv_project_name myproject` and `set nrv_project_creation_path "~/Sources"`. Check the source code for all the flags. 9 | 10 | ### Creating from a shell 11 | 12 | Execute the Gowin shell `gw_sh create_project.tcl` from the board subdir. 13 | The project will be created. You can then open the project from the Gowin IDE to synthesise and route, and finally program the device with the Gowin Programmer. 14 | 15 | ### GUI 16 | 17 | As of version 1.9.9, trying to create the project from the Gowin IDE GUI will result in the script stopping as soon as the new project is created, so the project will be missing the VHDL and constraint files. A workaround is possible, explained below. 18 | 19 | 1. start the Gowin IDE 20 | 2. click on the TCL Console text box at the bottom, next to the "%" symbol 21 | 3. use the console to navigate to the board's folder. For example `cd somewhere/neord32-setups/gowineda/tang-nano-9k` 22 | 4. execute `source create_project.tcl` —this will create the actual project in the `work` directory. As of version 1.9.9, this will launch a new instance of the Gowin IDE, with the project open. 23 | 5. move over to the TCL console on the new Gowin IDE window that just opened 24 | 6. execute `set nrv_skip_creation true` 25 | 7. execute `source ../create_project.tcl` 26 | 8. execute `unset nrv_skip_creation` 27 | 9. at this point you can manually run the synthesis and routing, and program the device. 28 | 29 | ## Programming the Bitstream 30 | 31 | 1. open the Programmer by clicking on its icon in the toolbar. 32 | 2. select the appropriate cable and click save. 33 | * **note**: under Linux, you must not be running the `ftdi_sio` kernel module for some Gowin programmers to work (e.g. Tang Nano 9K's built-in BL702 microcontroller). To stop this module, run `sudo modprobe -r ftdi_sio`, and "query the cables" again on the programmer software. The port will change from "USB Debugger A/0/0/null" to something like "USB Debugger A/0/4177/null". To restore the board's serial port functionallity, add `ftdi_sio` again: run `sudo modprobe ftdi_sio`. There is no need to unplug the device from the USB port. 34 | 3. select the correct FPGA part number. 35 | 4. the .fs bitstream file should be automatically loaded, if not, click on the blank cell below the "FS file" header, and click the ellipsis (...). The file is at `work/impl/pnr/work.fs`. 36 | 5. adjust any other settings you want and click the "Program/Configue" icon. 37 | 6. at this point you should see the board flashing the LED number 1 (at the top) for a few seconds. Congratulations! This means the processor and bootloader are working. 38 | * **note**: under Linux, make sure you add the `ftdi_sio` kernel module again, to allow communication with the board. You should see two new serial ports if you run `ls /dev/ttyUSB*`. Use the highest numbered out of the two. 39 | 7. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration: 40 | 19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline) 41 | 8. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) 42 | and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources. -------------------------------------------------------------------------------- /gowineda/tang-nano-20k/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Sipeed Tang Nano 20K FPGA development board 2 | 3 | This setup provides a simple script that you can run using the Gowin shell and creates a project with the NEORV32 processor already imported and ready to synthesize in the Gowin FPGA Designer IDE. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor top entity that provides a minimalistic interface (clock, reset, UART and 6 LEDs). 5 | 6 | * FPGA Board: 7 | * :books: [Sipeed Tang Nano 20K](https://wiki.sipeed.com/hardware/en/tang/tang-nano-20k/nano-20k.html) 8 | * FPGA: 9 | * Gowin Morningside GW2AR `GW2AR-LV18QN88C8/I7` 10 | * Toolchain: Gowin EDA (tested with Gowin EDA 1.9.9 on Linux —not a 1.9.9 beta) 11 | 12 | ## NEORV32 Configuration 13 | 14 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 15 | configuration and entity details and [`tang-nano-20k_test_setup_bootloader.cst`](https://github.com/stnolting/neorv32-setups/blob/tang-nano-20k/gowineda/tang-nano-20k/tang-nano-20k_test_setup_bootloader.cst) 16 | for the according FPGA pin mapping. 17 | 18 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors) 19 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 20 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 21 | * Tested with version [`1.9.2.5`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 22 | * Clock: 27MHz from on-board oscillator 23 | * Reset: Via dedicated on-board "RESET" button 24 | * GPIO output port `gpio_o` bits 0..5 are connected to the orange on-board LEDs (LED1 - LED6); LED6 is the bootloader status LED 25 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip 26 | * Under Linux, run `sudo modprobe ftdi_sio` for the on-board UART to appear under `/dev/ttyUSB*` (the higher of the two ports that will appear). Run `sudo modprobe -r ftdi_sio` to be able to program the device on the Gowin Programmer. There is no need to unplug the device from the USB port. 27 | -------------------------------------------------------------------------------- /gowineda/tang-nano-20k/import_neorv32.tcl: -------------------------------------------------------------------------------- 1 | # Usage: 2 | # * Use on an existing project where you want to import neorv32. Importing 3 | # copies all the neorv32 core files into your project. It makes your project 4 | # self-contained. To update your neorv32 library, first get the up to date 5 | # files and run the updated import_neorv32.tcl with the -force flag from 6 | # the Gowin EDA TCL console. 7 | # 8 | # * On the command console (%) type: 9 | # source /path/to/this/import_neorv32.tcl 10 | # Or, with the force flag 11 | # set nrv_force_import true 12 | # source /path/to/this/import_neorv32.tcl 13 | # unset nrv_force_import 14 | 15 | 16 | # Assume we are being called from the project directory 17 | if {![info exists project_dir]} { 18 | set project_dir [pwd] 19 | puts "Assumming project directory is $project_dir" 20 | } 21 | 22 | # Environment variables (flags_import is declared by create_project) 23 | if {![info exists flags_import]} { 24 | set flags_import "" 25 | if {[info exists nrv_force_import] && ($nrv_force_import == true)} { 26 | lappend flags_import -force } 27 | } 28 | 29 | set import_script_dir [file dirname [info script]] 30 | set import_neorv32_dir $import_script_dir/../../neorv32/ 31 | 32 | # Add all neorv32 core files to the project 33 | set corefiles [glob $import_neorv32_dir/rtl/core/*.vhd] 34 | foreach corefile $corefiles { 35 | import_files -file $corefile {*}$flags_import 36 | set_file_prop -lib neorv32 $project_dir/src/[file tail $corefile] 37 | # TODO: verify set_file_prop call is refering to the files correctly 38 | } 39 | 40 | -------------------------------------------------------------------------------- /gowineda/tang-nano-20k/tang-nano-20k_test_setup_bootloader.cst: -------------------------------------------------------------------------------- 1 | //Part Number: GW2AR-LV18QN88C8/I7 2 | //Device: GW2AR-18 3 | //Device Version: C 4 | 5 | IO_LOC "gpio_o[0]" 15; 6 | IO_PORT "gpio_o[0]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 7 | IO_LOC "gpio_o[1]" 16; 8 | IO_PORT "gpio_o[1]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 9 | IO_LOC "gpio_o[2]" 17; 10 | IO_PORT "gpio_o[2]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 11 | IO_LOC "gpio_o[3]" 18; 12 | IO_PORT "gpio_o[3]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 13 | IO_LOC "gpio_o[4]" 19; 14 | IO_PORT "gpio_o[4]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 15 | IO_LOC "gpio_o[5]" 20; 16 | IO_PORT "gpio_o[5]" IO_TYPE=LVCMOS33 DRIVE=8 BANK_VCCIO=3.3; 17 | 18 | IO_LOC "uart0_rxd_i" 70; 19 | IO_PORT "uart0_rxd_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; 20 | IO_LOC "uart0_txd_o" 69; 21 | IO_PORT "uart0_txd_o" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; 22 | 23 | IO_LOC "rst_i" 88; 24 | IO_PORT "rst_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; 25 | IO_LOC "clk_i" 4; 26 | IO_PORT "clk_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; -------------------------------------------------------------------------------- /gowineda/tang-nano-20k/test_setups/neorv32_test_setup_bootloader.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 - Test Setup Using The UART-Bootloader To Upload And Run 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_bootloader 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 | rst_i : in std_ulogic; -- global reset, low-active, async 29 | -- GPIO -- 30 | gpio_o : out std_ulogic_vector(7 downto 0); -- parallel output 31 | -- UART0 -- 32 | uart0_txd_o : out std_ulogic; -- UART0 send data 33 | uart0_rxd_i : in std_ulogic -- UART0 receive data 34 | ); 35 | end entity; 36 | 37 | architecture neorv32_test_setup_bootloader_rtl of neorv32_test_setup_bootloader is 38 | 39 | signal con_gpio_out : std_ulogic_vector(31 downto 0); 40 | signal rst_active_low : std_ulogic; 41 | 42 | begin 43 | 44 | -- Invert active-high external reset to active-low internal reset 45 | rst_active_low <= not rst_i; 46 | 47 | -- The Core Of The Problem ---------------------------------------------------------------- 48 | -- ------------------------------------------------------------------------------------------- 49 | neorv32_top_inst: neorv32_top 50 | generic map ( 51 | -- Clocking -- 52 | CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz 53 | -- Boot Configuration -- 54 | BOOT_MODE_SELECT => 0, -- boot via internal bootloader 55 | -- RISC-V CPU Extensions -- 56 | RISCV_ISA_C => true, -- implement compressed extension? 57 | RISCV_ISA_M => true, -- implement mul/div extension? 58 | RISCV_ISA_Zicntr => true, -- implement base counters? 59 | -- Internal Instruction memory -- 60 | IMEM_EN => true, -- implement processor-internal instruction memory 61 | IMEM_SIZE => IMEM_SIZE, -- size of processor-internal instruction memory in bytes 62 | -- Internal Data memory -- 63 | DMEM_EN => true, -- implement processor-internal data memory 64 | DMEM_SIZE => DMEM_SIZE, -- size of processor-internal data memory in bytes 65 | -- Processor peripherals -- 66 | IO_GPIO_NUM => 8, -- number of GPIO input/output pairs (0..32) 67 | IO_CLINT_EN => true, -- implement core local interruptor (CLINT)? 68 | IO_UART0_EN => true -- implement primary universal asynchronous receiver/transmitter (UART0)? 69 | ) 70 | port map ( 71 | -- Global control -- 72 | clk_i => clk_i, -- global clock, rising edge 73 | rstn_i => rst_active_low, -- global reset, low-active, async 74 | -- GPIO (available if IO_GPIO_NUM > 0) -- 75 | gpio_o => con_gpio_out, -- parallel output 76 | -- primary UART0 (available if IO_UART0_EN = true) -- 77 | uart0_txd_o => uart0_txd_o, -- UART0 send data 78 | uart0_rxd_i => uart0_rxd_i -- UART0 receive data 79 | ); 80 | 81 | -- GPIO output -- 82 | gpio_o <= not con_gpio_out(5 downto 0); 83 | 84 | end architecture; 85 | -------------------------------------------------------------------------------- /gowineda/tang-nano-9k/.gitignore: -------------------------------------------------------------------------------- 1 | work/ 2 | -------------------------------------------------------------------------------- /gowineda/tang-nano-9k/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Sipeed Tang Nano 9K FPGA development board 2 | 3 | This setup provides a simple script that you can run using the Gowin shell and creates a project with the NEORV32 processor already imported and ready to synthesize in the Gowin FPGA Designer IDE. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor top entity that provides a minimalistic interface (clock, reset, UART and 6 LEDs). 5 | 6 | * FPGA Board: 7 | * :books: [Sipeed Tang Nano 9K](https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-9K/Nano-9K.html) 8 | * FPGA: 9 | * Gowin LittleBee GW1NR `GW1NR-LV9QN88PC6/I5` 10 | * Toolchain: Gowin EDA (tested with Gowin EDA 1.9.9 on Linux —not a 1.9.9 beta) 11 | 12 | ## NEORV32 Configuration 13 | 14 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 15 | configuration and entity details and [`tang-nano-9k_test_setup_bootloader.cst`](https://github.com/IvanVeloz/neorv32-setups/blob/master/gowineda/tang-nano-9k/tang-nano-9k_test_setup_bootloader.cst) 16 | for the according FPGA pin mapping. 17 | 18 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors) 19 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 20 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 21 | * Tested with version [`1.9.2.5`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 22 | * Clock: 27MHz from on-board oscillator 23 | * Reset: Via dedicated on-board "RESET" button 24 | * GPIO output port `gpio_o` bits 0..5 are connected to the orange on-board LEDs (LED1 - LED6); LED6 is the bootloader status LED 25 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip 26 | * Under Linux, run `sudo modprobe ftdi_sio` for the on-board UART to appear under `/dev/ttyUSB*` (the higher of the two ports that will appear). Run `sudo modprobe -r ftdi_sio` to be able to program the device on the Gowin Programmer. There is no need to unplug the device from the USB port. 27 | -------------------------------------------------------------------------------- /gowineda/tang-nano-9k/import_neorv32.tcl: -------------------------------------------------------------------------------- 1 | # Usage: 2 | # * Use on an existing project where you want to import neorv32. Importing 3 | # copies all the neorv32 core files into your project. It makes your project 4 | # self-contained. To update your neorv32 library, first get the up to date 5 | # files and run the updated import_neorv32.tcl with the -force flag from 6 | # the Gowin EDA TCL console. 7 | # 8 | # * On the command console (%) type: 9 | # source /path/to/this/import_neorv32.tcl 10 | # Or, with the force flag 11 | # set nrv_force_import true 12 | # source /path/to/this/import_neorv32.tcl 13 | # unset nrv_force_import 14 | 15 | 16 | # Assume we are being called from the project directory 17 | if {![info exists project_dir]} { 18 | set project_dir [pwd] 19 | puts "Assumming project directory is $project_dir" 20 | } 21 | 22 | # Environment variables (flags_import is declared by create_project) 23 | if {![info exists flags_import]} { 24 | set flags_import "" 25 | if {[info exists nrv_force_import] && ($nrv_force_import == true)} { 26 | lappend flags_import -force } 27 | } 28 | 29 | set import_script_dir [file dirname [info script]] 30 | set import_neorv32_dir $import_script_dir/../../neorv32/ 31 | 32 | # Add all neorv32 core files to the project 33 | set corefiles [glob $import_neorv32_dir/rtl/core/*.vhd] 34 | foreach corefile $corefiles { 35 | import_files -file $corefile {*}$flags_import 36 | set_file_prop -lib neorv32 $project_dir/src/[file tail $corefile] 37 | # TODO: verify set_file_prop call is refering to the files correctly 38 | } 39 | 40 | -------------------------------------------------------------------------------- /gowineda/tang-nano-9k/tang-nano-9k_test_setup_bootloader.cst: -------------------------------------------------------------------------------- 1 | //Part Number: GW1NR-LV9QN88PC6/I5 2 | //Device: GW1NR-9 3 | //Device Version: C 4 | 5 | IO_LOC "gpio_o[0]" 10; 6 | IO_PORT "gpio_o[0]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 7 | IO_LOC "gpio_o[1]" 11; 8 | IO_PORT "gpio_o[1]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 9 | IO_LOC "gpio_o[2]" 13; 10 | IO_PORT "gpio_o[2]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 11 | IO_LOC "gpio_o[3]" 14; 12 | IO_PORT "gpio_o[3]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 13 | IO_LOC "gpio_o[4]" 15; 14 | IO_PORT "gpio_o[4]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 15 | IO_LOC "gpio_o[5]" 16; 16 | IO_PORT "gpio_o[5]" IO_TYPE=LVCMOS18 DRIVE=8 BANK_VCCIO=1.8; 17 | 18 | IO_LOC "uart0_rxd_i" 18; 19 | IO_PORT "uart0_rxd_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; 20 | IO_LOC "uart0_txd_o" 17; 21 | IO_PORT "uart0_txd_o" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; 22 | 23 | IO_LOC "rstn_i" 3; 24 | IO_PORT "rstn_i" IO_TYPE=LVCMOS18 PULL_MODE=UP BANK_VCCIO=1.8; 25 | IO_LOC "clk_i" 52; 26 | IO_PORT "clk_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; 27 | -------------------------------------------------------------------------------- /gowineda/tools/uart_upload.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory=$true)] 3 | [string]$Port, 4 | [Parameter(Mandatory=$true)] 5 | [string]$ExeFile 6 | ) 7 | 8 | function Show-Usage { 9 | Write-Host "Upload and execute application image via serial port (UART) to the NEORV32 bootloader." 10 | Write-Host "Reset processor before starting the upload." 11 | Write-Host "" 12 | Write-Host "Usage: .\uart_upload.ps1 " 13 | Write-Host "Example: .\uart_upload.ps1 COM40 C:\path\to\neorv32_exe.bin" 14 | } 15 | 16 | # Show usage if parameters are missing 17 | if (-not $Port -or -not $ExeFile) { 18 | Show-Usage 19 | exit 0 20 | } 21 | 22 | # Check that the executable file exists 23 | if (-not (Test-Path $ExeFile)) { 24 | Write-Host "Error: File '$ExeFile' not found!" 25 | exit 1 26 | } 27 | 28 | # Configure and open the serial port 29 | try { 30 | $serialPort = New-Object System.IO.Ports.SerialPort $Port, 19200, 'None', 8, 'One' 31 | $serialPort.ReadTimeout = 500 # in milliseconds 32 | $serialPort.WriteTimeout = 500 33 | $serialPort.Open() 34 | } catch { 35 | Write-Host "Error opening serial port '$Port'." 36 | exit 1 37 | } 38 | 39 | try { 40 | # Abort autoboot sequence by sending a space 41 | $serialPort.Write(" ") 42 | Start-Sleep -Milliseconds 100 43 | 44 | # Flush any existing input 45 | $serialPort.DiscardInBuffer() 46 | 47 | # Send the upload command "u" 48 | $serialPort.Write("u") 49 | Start-Sleep -Milliseconds 500 50 | 51 | # Read bootloader response 52 | $response = "" 53 | while ($serialPort.BytesToRead -gt 0) { 54 | $response += $serialPort.ReadExisting() 55 | Start-Sleep -Milliseconds 100 56 | } 57 | 58 | if ($response -notmatch "Awaiting neorv32_exe\.bin") { 59 | Write-Host "Bootloader response error!" 60 | Write-Host "Reset processor before starting the upload." 61 | $serialPort.Close() 62 | exit 1 63 | } 64 | 65 | # Upload the executable 66 | Write-Host -NoNewline "Uploading executable... " 67 | $serialPort.DiscardInBuffer() # clear any previous data 68 | 69 | # Read the executable file as a byte array 70 | try { 71 | $fileBytes = [System.IO.File]::ReadAllBytes($ExeFile) 72 | } catch { 73 | Write-Host "Error reading file '$ExeFile'." 74 | $serialPort.Close() 75 | exit 1 76 | } 77 | 78 | # Write the file bytes to the serial port 79 | $serialPort.Write($fileBytes, 0, $fileBytes.Length) 80 | Start-Sleep -Seconds 3 81 | 82 | # Read response after file upload 83 | $response = "" 84 | while ($serialPort.BytesToRead -gt 0) { 85 | $response += $serialPort.ReadExisting() 86 | Start-Sleep -Milliseconds 100 87 | } 88 | 89 | if ($response -notmatch "OK") { 90 | Write-Host "FAILED!" 91 | $serialPort.Close() 92 | exit 1 93 | } else { 94 | Write-Host "OK" 95 | Write-Host "Starting application..." 96 | $serialPort.Write("e") 97 | } 98 | } finally { 99 | # Ensure the port is closed even if errors occur 100 | $serialPort.Close() 101 | } 102 | -------------------------------------------------------------------------------- /osflow/.gitignore: -------------------------------------------------------------------------------- 1 | *.asc 2 | *.bit 3 | *.cf 4 | *.cfg 5 | *.dfu 6 | *.history 7 | *.json 8 | *.o 9 | *.svf 10 | *-report.txt 11 | -------------------------------------------------------------------------------- /osflow/Makefile: -------------------------------------------------------------------------------- 1 | RTL_CORE_SRC := ../neorv32/rtl/core 2 | TEMPLATES := ../neorv32/rtl/processor_templates 3 | MV := mv 4 | 5 | .DEFAULT_GOAL := help 6 | 7 | TASK := clean $(BITSTREAM) 8 | 9 | FOMU_REV ?= pvt 10 | OrangeCrab_REV ?= r02-25F 11 | 12 | #ifndef BOARD 13 | #$(error BOARD needs to be set to 'Fomu', 'iCESugar-v1.5', 'UPDuino-v3.0', 'iCEBreaker' or 'OrangeCrab' !) 14 | #endif 15 | 16 | run: 17 | $(eval TASK ?= clean $(BITSTREAM)) 18 | $(eval TOP ?= neorv32_$(BOARD)_BoardTop_$(DESIGN)) 19 | $(MAKE) -f common.mk \ 20 | BOARD_SRC=./board_tops/neorv32_$(BOARD)_BoardTop_$(DESIGN).vhd \ 21 | TOP="$(TOP)" \ 22 | ID="$(DESIGN)" \ 23 | $(TASK) 24 | IMPL="$${BITSTREAM%%.*}"; for item in ".bit" ".svf"; do \ 25 | if [ -f "./$$IMPL$$item" ]; then \ 26 | $(MV) "./$$IMPL$$item" ./; \ 27 | fi \ 28 | done 29 | 30 | # Boards 31 | 32 | Fomu: 33 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(FOMU_REV)_$(DESIGN).bit) 34 | ifeq ($(DESIGN),Minimal) 35 | $(eval IMEM_SRC := $(RTL_CORE_SRC)/neorv32_imem.vhd) 36 | else 37 | $(eval IMEM_SRC := devices/ice40/neorv32_imem.ice40up_spram.vhd) 38 | endif 39 | $(eval NEORV32_MEM_SRC ?= ${IMEM_SRC} devices/ice40/neorv32_dmem.ice40up_spram.vhd) 40 | $(MAKE) \ 41 | BITSTREAM="$(BITSTREAM)" \ 42 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 43 | run 44 | 45 | iCESugar-v1.5: 46 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 47 | ifeq ($(DESIGN),Minimal) 48 | $(eval IMEM_SRC := $(RTL_CORE_SRC)/neorv32_imem.vhd) 49 | else 50 | $(eval IMEM_SRC := devices/ice40/neorv32_imem.ice40up_spram.vhd) 51 | endif 52 | $(eval NEORV32_MEM_SRC ?= ${IMEM_SRC} devices/ice40/neorv32_dmem.ice40up_spram.vhd) 53 | $(eval TOP ?= neorv32_iCESugarv15_BoardTop_$(DESIGN)) 54 | $(MAKE) \ 55 | BITSTREAM="$(BITSTREAM)" \ 56 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 57 | TOP="$(TOP)" \ 58 | run 59 | 60 | UPDuino-v3.0: 61 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 62 | $(eval NEORV32_MEM_SRC ?= devices/ice40/neorv32_imem.ice40up_spram.vhd devices/ice40/neorv32_dmem.ice40up_spram.vhd) 63 | $(eval TOP ?= neorv32_UPDuinov30_BoardTop_$(DESIGN)) 64 | $(MAKE) \ 65 | BITSTREAM="$(BITSTREAM)" \ 66 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 67 | TOP="$(TOP)" \ 68 | run 69 | 70 | OrangeCrab: 71 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(OrangeCrab_REV)_$(DESIGN).bit) 72 | $(eval NEORV32_MEM_SRC ?= $(RTL_CORE_SRC)/neorv32_imem.vhd $(RTL_CORE_SRC)/neorv32_dmem.vhd) 73 | $(MAKE) \ 74 | BITSTREAM="$(BITSTREAM)" \ 75 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 76 | run 77 | 78 | IceZumAlhambraII: 79 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 80 | $(eval NEORV32_MEM_SRC ?= $(RTL_CORE_SRC)/neorv32_imem.vhd $(RTL_CORE_SRC)/neorv32_dmem.vhd) 81 | $(MAKE) \ 82 | BITSTREAM="$(BITSTREAM)" \ 83 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 84 | run 85 | 86 | ULX3S: 87 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 88 | $(eval NEORV32_MEM_SRC ?= $(RTL_CORE_SRC)/neorv32_imem.vhd $(RTL_CORE_SRC)/neorv32_dmem.vhd) 89 | $(MAKE) \ 90 | BITSTREAM="$(BITSTREAM)" \ 91 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 92 | run 93 | 94 | iCEBreaker: 95 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 96 | $(eval NEORV32_MEM_SRC ?= devices/ice40/neorv32_imem.ice40up_spram.vhd devices/ice40/neorv32_dmem.ice40up_spram.vhd) 97 | $(MAKE) \ 98 | BITSTREAM="$(BITSTREAM)" \ 99 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 100 | run 101 | 102 | iCE40CW312: 103 | $(eval BITSTREAM ?= neorv32_$(BOARD)_$(DESIGN).bit) 104 | $(eval NEORV32_MEM_SRC ?= devices/ice40/neorv32_imem.ice40up_spram.vhd devices/ice40/neorv32_dmem.ice40up_spram.vhd) 105 | $(MAKE) \ 106 | BITSTREAM="$(BITSTREAM)" \ 107 | NEORV32_MEM_SRC="$(NEORV32_MEM_SRC)" \ 108 | run 109 | 110 | 111 | # Designs 112 | 113 | Minimal: 114 | $(eval DESIGN ?= $@) 115 | $(eval DESIGN_SRC ?= $(TEMPLATES)/neorv32_ProcessorTop_Minimal*.vhd) 116 | $(MAKE) \ 117 | DESIGN="$(DESIGN)" \ 118 | DESIGN_SRC="$(DESIGN_SRC)" \ 119 | $(BOARD) 120 | 121 | MinimalBoot: 122 | $(eval DESIGN ?= $@) 123 | $(eval DESIGN_SRC ?= $(TEMPLATES)/neorv32_ProcessorTop_MinimalBoot.vhd) 124 | $(MAKE) \ 125 | DESIGN="$(DESIGN)" \ 126 | DESIGN_SRC="$(DESIGN_SRC)" \ 127 | $(BOARD) 128 | 129 | UP5KDemo: 130 | $(eval DESIGN ?= $@) 131 | $(eval DESIGN_SRC ?= $(TEMPLATES)/neorv32_ProcessorTop_UP5KDemo.vhd) 132 | $(MAKE) \ 133 | DESIGN="$(DESIGN)" \ 134 | DESIGN_SRC="$(DESIGN_SRC)" \ 135 | $(BOARD) 136 | 137 | MixedLanguage: 138 | $(eval DESIGN ?= $@) 139 | $(eval DESIGN_SRC ?= $(TEMPLATES)/neorv32_ProcessorTop_Minimal*.vhd) 140 | $(eval NEORV32_VERILOG_SRC ?= devices/ice40/sb_ice40_components.v board_tops/neorv32_Fomu_MixedLanguage_ClkGen.v) 141 | $(MAKE) \ 142 | DESIGN="$(DESIGN)" \ 143 | DESIGN_SRC="$(DESIGN_SRC)" \ 144 | NEORV32_VERILOG_SRC="$(NEORV32_VERILOG_SRC)" \ 145 | $(BOARD) 146 | 147 | # Help 148 | 149 | help: 150 | @echo "Open-Source Synthesis, P&R, Routing and Bitstream Generation" 151 | @echo "Usage: make BOARD= " 152 | @echo "Example: make BOARD=Fomu Minimal" 153 | 154 | -------------------------------------------------------------------------------- /osflow/PnR_Bit.mk: -------------------------------------------------------------------------------- 1 | ${IMPL}.${PNR2BIT_EXT}: $(IMPL).json $(CONSTRAINTS) 2 | $(NEXTPNR) \ 3 | $(PNRFLAGS) \ 4 | --$(CONSTRAINTS_FORMAT) $(CONSTRAINTS) \ 5 | --json $(IMPL).json \ 6 | --${NEXTPNR_OUT} $@ 2>&1 | tee nextpnr-report.txt 7 | 8 | ${IMPL}.bit: ${IMPL}.${PNR2BIT_EXT} 9 | $(PACKTOOL) $< $@ 10 | 11 | ifeq ($(DEVICE_SERIES),ecp5) 12 | ${IMPL}.svf: ${IMPL}.${PNR2BIT_EXT} 13 | $(PACKTOOL) $(PACKARGS) --svf $@ $< 14 | endif 15 | -------------------------------------------------------------------------------- /osflow/board_tops/neorv32_Fomu_MixedLanguage_ClkGen.v: -------------------------------------------------------------------------------- 1 | module neorv32_Fomu_MixedLanguage_ClkGen ( 2 | output wire clk_o, 3 | output wire rstn_o 4 | ); 5 | 6 | wire hf_osc_clk; 7 | 8 | SB_HFOSC #( 9 | .CLKHF_DIV("0b10") // 12 MHz 10 | ) HSOSC_inst ( 11 | .CLKHFPU(1'b1), 12 | .CLKHFEN(1'b1), 13 | .CLKHF(hf_osc_clk) 14 | ); 15 | 16 | // Settings generated by icepll -i 12 -o 18: 17 | // F_PLLIN: 12.000 MHz (given) 18 | // F_PLLOUT: 18.000 MHz (requested) 19 | // F_PLLOUT: 18.000 MHz (achieved) 20 | // FEEDBACK: SIMPLE 21 | // F_PFD: 12.000 MHz 22 | // F_VCO: 576.000 MHz 23 | // DIVR: 0 (4'b0000) 24 | // DIVF: 47 (7'b0101111) 25 | // DIVQ: 5 (3'b101) 26 | // FILTER_RANGE: 1 (3'b001) 27 | 28 | SB_PLL40_CORE #( 29 | .FEEDBACK_PATH("SIMPLE"), 30 | .DIVR(4'd0), 31 | .DIVF(7'd47), 32 | .DIVQ(3'd5), 33 | .FILTER_RANGE(3'd1) 34 | ) Pll_inst ( 35 | .REFERENCECLK(hf_osc_clk), 36 | .PLLOUTGLOBAL(clk_o), 37 | .EXTFEEDBACK(1'b0), 38 | .LOCK(rstn_o), 39 | .BYPASS(1'b0), 40 | .RESETB(1'b1), 41 | .LATCHINPUTVALUE(1'b0), 42 | .SDI(1'b0), 43 | .SCLK(1'b0) 44 | ); 45 | 46 | endmodule 47 | 48 | -------------------------------------------------------------------------------- /osflow/board_tops/neorv32_ULX3S_BoardTop_MinimalBoot.vhd: -------------------------------------------------------------------------------- 1 | -- ################################################################################################# 2 | -- # << NEORV32 - Example setup including the bootloader, for the ULX3S (c) Board >> # 3 | -- # ********************************************************************************************* # 4 | -- # BSD 3-Clause License # 5 | -- # # 6 | -- # Copyright (c) 2023, Stephan Nolting. All rights reserved. # 7 | -- # # 8 | -- # Redistribution and use in source and binary forms, with or without modification, are # 9 | -- # permitted provided that the following conditions are met: # 10 | -- # # 11 | -- # 1. Redistributions of source code must retain the above copyright notice, this list of # 12 | -- # conditions and the following disclaimer. # 13 | -- # # 14 | -- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # 15 | -- # conditions and the following disclaimer in the documentation and/or other materials # 16 | -- # provided with the distribution. # 17 | -- # # 18 | -- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # 19 | -- # endorse or promote products derived from this software without specific prior written # 20 | -- # permission. # 21 | -- # # 22 | -- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # 23 | -- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # 24 | -- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # 25 | -- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # 26 | -- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # 27 | -- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # 28 | -- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # 29 | -- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # 30 | -- # OF THE POSSIBILITY OF SUCH DAMAGE. # 31 | -- # ********************************************************************************************* # 32 | -- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # 33 | -- ################################################################################################# 34 | 35 | library ieee; 36 | use ieee.std_logic_1164.all; 37 | use ieee.numeric_std.all; 38 | 39 | library ECP5; 40 | use ECP5.components.all; -- for device primitives and macros 41 | 42 | entity neorv32_ULX3S_BoardTop_MinimalBoot is 43 | port ( 44 | -- Clock and Reset inputs 45 | ULX3S_CLK : in std_logic; 46 | ULX3S_RST_N : in std_logic; 47 | -- LED outputs 48 | ULX3S_LED0 : out std_logic; 49 | ULX3S_LED1 : out std_logic; 50 | ULX3S_LED2 : out std_logic; 51 | ULX3S_LED3 : out std_logic; 52 | ULX3S_LED4 : out std_logic; 53 | ULX3S_LED5 : out std_logic; 54 | ULX3S_LED6 : out std_logic; 55 | ULX3S_LED7 : out std_logic; 56 | -- UART0 57 | ULX3S_RX : in std_logic; 58 | ULX3S_TX : out std_logic 59 | ); 60 | end entity; 61 | 62 | architecture neorv32_ULX3S_BoardTop_MinimalBoot_rtl of neorv32_ULX3S_BoardTop_MinimalBoot is 63 | 64 | -- configuration -- 65 | constant f_clock_c : natural := 25000000; -- clock frequency in Hz 66 | 67 | -- internal IO connection -- 68 | signal con_pwm : std_logic_vector(2 downto 0); 69 | signal con_gpio_o : std_ulogic_vector(3 downto 0); 70 | 71 | begin 72 | 73 | -- The core of the problem ---------------------------------------------------------------- 74 | -- ------------------------------------------------------------------------------------------- 75 | neorv32_inst: entity work.neorv32_ProcessorTop_MinimalBoot 76 | generic map ( 77 | CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz 78 | IMEM_SIZE => 16*1024, 79 | DMEM_SIZE => 8*1024 80 | ) 81 | port map ( 82 | -- Global control -- 83 | clk_i => std_ulogic(ULX3S_CLK), 84 | rstn_i => std_ulogic(ULX3S_RST_N), 85 | 86 | -- GPIO -- 87 | gpio_o => con_gpio_o, 88 | 89 | -- primary UART -- 90 | uart_txd_o => ULX3S_TX, -- UART0 send data 91 | uart_rxd_i => ULX3S_RX, -- UART0 receive data 92 | 93 | -- PWM (to on-board RGB LED) -- 94 | pwm_o => con_pwm 95 | ); 96 | 97 | -- IO Connection -------------------------------------------------------------------------- 98 | -- ------------------------------------------------------------------------------------------- 99 | ULX3S_LED0 <= con_gpio_o(0); 100 | ULX3S_LED1 <= con_gpio_o(1); 101 | ULX3S_LED2 <= con_gpio_o(2); 102 | ULX3S_LED3 <= con_gpio_o(3); 103 | ULX3S_LED4 <= '0'; -- unused 104 | ULX3S_LED5 <= con_pwm(0); 105 | ULX3S_LED6 <= con_pwm(1); 106 | ULX3S_LED7 <= con_pwm(2); 107 | 108 | end architecture; 109 | -------------------------------------------------------------------------------- /osflow/board_tops/neorv32_iCE40CW312_BoardTop_MinimalBoot.vhd: -------------------------------------------------------------------------------- 1 | -- ################################################################################################# 2 | -- # << NEORV32 - Example minimal setup for the iCE40CW312 >> # 3 | -- # ********************************************************************************************* # 4 | -- # BSD 3-Clause License # 5 | -- # # 6 | -- # Copyright (c) 2023, Stephan Nolting. All rights reserved. # 7 | -- # # 8 | -- # Redistribution and use in source and binary forms, with or without modification, are # 9 | -- # permitted provided that the following conditions are met: # 10 | -- # # 11 | -- # 1. Redistributions of source code must retain the above copyright notice, this list of # 12 | -- # conditions and the following disclaimer. # 13 | -- # # 14 | -- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # 15 | -- # conditions and the following disclaimer in the documentation and/or other materials # 16 | -- # provided with the distribution. # 17 | -- # # 18 | -- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # 19 | -- # endorse or promote products derived from this software without specific prior written # 20 | -- # permission. # 21 | -- # # 22 | -- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # 23 | -- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # 24 | -- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # 25 | -- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # 26 | -- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # 27 | -- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # 28 | -- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # 29 | -- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # 30 | -- # OF THE POSSIBILITY OF SUCH DAMAGE. # 31 | -- # ********************************************************************************************* # 32 | -- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # 33 | -- ################################################################################################# 34 | 35 | library ieee; 36 | use ieee.std_logic_1164.all; 37 | use ieee.numeric_std.all; 38 | 39 | library iCE40; 40 | use iCE40.components.all; -- for device primitives and macros 41 | 42 | entity neorv32_iCE40CW312_BoardTop_MinimalBoot is 43 | port ( 44 | iCE40CW312_CLK : in std_logic; 45 | -- UART (uart0) -- 46 | iCE40CW312_TX : out std_ulogic; 47 | iCE40CW312_RX : in std_ulogic; 48 | -- GPIO -- 49 | iCE40CW312_GPIO_O : out std_ulogic_vector(1 downto 0) 50 | ); 51 | end entity; 52 | 53 | architecture neorv32_iCE40CW312_BoardTop_MinimalBoot_rtl of neorv32_iCE40CW312_BoardTop_MinimalBoot is 54 | 55 | -- configuration -- 56 | constant f_clock_c : natural := 7372800; -- Input clock frequency in Hz 57 | 58 | -- Clock connection -- 59 | signal sys_clk : std_logic; 60 | 61 | -- internal IO connection -- 62 | signal GPIO_Intermediate : std_ulogic_vector(3 downto 0); 63 | 64 | -- reset generator -- 65 | signal rst_cnt : std_logic_vector(8 downto 0) := (others => '0'); -- initialized by bitstream 66 | signal sys_rstn : std_logic; 67 | 68 | begin 69 | 70 | -- Reset Generator ------------------------------------------------------------------------ 71 | -- ------------------------------------------------------------------------------------------- 72 | reset_generator: process(sys_clk) 73 | begin 74 | if rising_edge(sys_clk) then 75 | if (rst_cnt(rst_cnt'left) = '0') then 76 | rst_cnt <= std_logic_vector(unsigned(rst_cnt) + 1); 77 | end if; 78 | end if; 79 | end process reset_generator; 80 | 81 | sys_rstn <= rst_cnt(rst_cnt'left); 82 | 83 | -- The core of the problem ---------------------------------------------------------------- 84 | -- ------------------------------------------------------------------------------------------- 85 | neorv32_inst: entity work.neorv32_ProcessorTop_MinimalBoot 86 | generic map ( 87 | CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz 88 | IO_PWM_NUM_CH => 0 89 | ) 90 | port map ( 91 | -- Global control -- 92 | clk_i => sys_clk, 93 | rstn_i => sys_rstn, 94 | 95 | -- GPIO -- 96 | gpio_o => GPIO_Intermediate, 97 | 98 | -- primary UART -- 99 | uart_txd_o => iCE40CW312_TX, -- UART0 send data 100 | uart_rxd_i => iCE40CW312_RX -- UART0 receive data 101 | ); 102 | 103 | -- External to System Connections --------------------------------------------------------- 104 | -- ------------------------------------------------------------------------------------------- 105 | iCE40CW312_GPIO_O <= GPIO_Intermediate(1 downto 0); 106 | sys_clk <= iCE40CW312_CLK; 107 | 108 | end architecture; 109 | -------------------------------------------------------------------------------- /osflow/boards/Fomu.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | # Default target: run all required targets to build the DFU image. 4 | all: $(IMPL).dfu 5 | echo "! Built $(IMPL) for $(BOARD) $(FOMU_REV)" 6 | 7 | # Use dfu-suffix to generate the DFU image from the FPGA bitstream. 8 | ${IMPL}.dfu: $(IMPL).bit 9 | $(COPY) $< $@ 10 | dfu-suffix -v 1209 -p 70b1 -a $@ 11 | 12 | # Use df-util to load the DFU image onto the Fomu. 13 | load: $(IMPL).dfu 14 | dfu-util -D $< 15 | 16 | .PHONY: load 17 | -------------------------------------------------------------------------------- /osflow/boards/IceZumAlhambraII.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/OrangeCrab.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/ULX3S.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/UPDuino-v3.0.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/iCE40CW312.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/iCEBreaker.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/iCESugar-v1.5.mk: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: bit 4 | echo "! Built $(IMPL) for $(BOARD)" 5 | -------------------------------------------------------------------------------- /osflow/boards/index.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Constraints from submodule 3 | # 4 | 5 | CONSTRAINTS_BOARD_PATH ?= ../constraints/board 6 | 7 | 8 | ifeq ($(BOARD),iCESugar-v1.5) 9 | $(info Setting constraints and implementation args for BOARD iCESugar-v1.5) 10 | 11 | CONSTRAINTS ?= $(CONSTRAINTS_BOARD_PATH)/$(BOARD)/constraints.pcf 12 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 13 | IMPL ?= neorv32_$(BOARD)_$(ID) 14 | 15 | endif 16 | 17 | 18 | ifeq ($(BOARD),iCEBreaker) 19 | $(info Setting constraints and implementation args for BOARD iCEBreaker) 20 | 21 | CONSTRAINTS ?= $(CONSTRAINTS_BOARD_PATH)/$(BOARD)/constraints.pcf 22 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 23 | IMPL ?= neorv32_$(BOARD)_$(ID) 24 | 25 | endif 26 | 27 | 28 | ifeq ($(BOARD),IceZumAlhambraII) 29 | $(info Setting constraints and implementation args for BOARD IceZumAlhambraII) 30 | 31 | CONSTRAINTS ?= $(CONSTRAINTS_BOARD_PATH)/$(BOARD)/constraints.pcf 32 | PNRFLAGS ?= --hx8k --package tq144:4k --ignore-loops --timing-allow-fail 33 | IMPL ?= neorv32_$(BOARD)_$(ID) 34 | 35 | endif 36 | 37 | 38 | ifeq ($(BOARD),UPDuino-v3.0) 39 | $(info Setting constraints and implementation args for BOARD UPDuino-v3.0) 40 | 41 | CONSTRAINTS ?= $(CONSTRAINTS_BOARD_PATH)/$(BOARD)/constraints.pcf 42 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 43 | IMPL ?= neorv32_$(BOARD)_$(ID) 44 | 45 | endif 46 | 47 | 48 | # 49 | # Local constraints files 50 | # 51 | 52 | PCF_PATH ?= constraints 53 | 54 | 55 | ifeq ($(BOARD),Fomu) 56 | 57 | $(info Setting constraints and implementation args for BOARD Fomu) 58 | 59 | # Different Fomu hardware revisions are wired differently and thus 60 | # require different configurations for yosys and nextpnr. 61 | # Configuration is performed by setting the environment variable FOMU_REV accordingly. 62 | 63 | FOMU_REV ?= pvt 64 | 65 | ifeq ($(FOMU_REV),evt1) 66 | YOSYSFLAGS ?= -D EVT=1 -D EVT1=1 -D HAVE_PMOD=1 67 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 68 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-evt2.pcf 69 | else ifeq ($(FOMU_REV),evt2) 70 | YOSYSFLAGS ?= -D EVT=1 -D EVT2=1 -D HAVE_PMOD=1 71 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 72 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf 73 | else ifeq ($(FOMU_REV),evt3) 74 | YOSYSFLAGS ?= -D EVT=1 -D EVT3=1 -D HAVE_PMOD=1 75 | PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail 76 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf 77 | else ifeq ($(FOMU_REV),hacker) 78 | YOSYSFLAGS ?= -D HACKER=1 79 | PNRFLAGS ?= --up5k --package uwg30 --ignore-loops --timing-allow-fail 80 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf 81 | else ifeq ($(FOMU_REV),pvt) 82 | YOSYSFLAGS ?= -D PVT=1 83 | PNRFLAGS ?= --up5k --package uwg30 --ignore-loops --timing-allow-fail 84 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf 85 | else 86 | $(error Unrecognized FOMU_REV value. must be "evt1", "evt2", "evt3", "pvt", or "hacker") 87 | endif 88 | 89 | IMPL := neorv32_Fomu_$(FOMU_REV)_$(ID) 90 | 91 | endif 92 | 93 | 94 | ifeq ($(BOARD),OrangeCrab) 95 | $(info Setting constraints and implementation args for BOARD OrangeCrab) 96 | 97 | DEVICE_SERIES = ecp5 98 | 99 | OrangeCrab_REV ?= r02-25F 100 | 101 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD).lpf 102 | PNRFLAGS ?= --25k --package CSFBGA285 --ignore-loops --timing-allow-fail 103 | IMPL ?= neorv32_$(BOARD)_$(OrangeCrab_REV)_$(ID) 104 | 105 | endif 106 | 107 | 108 | ifeq ($(BOARD),ULX3S) 109 | $(info Setting constraints and implementation args for BOARD ULX3S) 110 | 111 | DEVICE_SERIES = ecp5 112 | 113 | CONSTRAINTS ?= $(PCF_PATH)/$(BOARD).lpf 114 | PNRFLAGS ?= --85k --freq 25 --package CABGA381 --ignore-loops --timing-allow-fail 115 | IMPL ?= neorv32_$(BOARD)_$(ID) 116 | 117 | endif 118 | 119 | 120 | ifeq ($(BOARD),iCE40CW312) 121 | $(info Setting constraints and implementation args for BOARD iCE40CW312) 122 | 123 | CONSTRAINTS ?= $(CONSTRAINTS_BOARD_PATH)/$(BOARD)/constraints.pcf 124 | PNRFLAGS ?= --up5k --package uwg30 --ignore-loops --timing-allow-fail 125 | IMPL ?= neorv32_$(BOARD)_$(ID) 126 | 127 | endif 128 | -------------------------------------------------------------------------------- /osflow/common.mk: -------------------------------------------------------------------------------- 1 | ID ?= impl_1 2 | 3 | include boards/index.mk 4 | 5 | ifndef TOP 6 | $(error TOP needs to be specified!) 7 | endif 8 | 9 | include filesets.mk 10 | 11 | ifndef DESIGN_SRC 12 | ifndef BOARD_SRC 13 | $(error Neither DESIGN_SRC nor BOARD_SRC were set!) 14 | endif 15 | endif 16 | 17 | include tools.mk 18 | 19 | ifdef GHDL_PLUGIN_MODULE 20 | YOSYSFLAGS += -m $(GHDL_PLUGIN_MODULE) 21 | endif 22 | 23 | include synthesis.mk 24 | include PnR_Bit.mk 25 | 26 | .PHONY: syn impl bit svf clean 27 | 28 | syn: ${IMPL}.json 29 | impl: ${IMPL}.${PNR2BIT_EXT} 30 | bit: ${IMPL}.bit 31 | 32 | ifeq ($(DEVICE_SERIES),ecp5) 33 | svf: ${IMPL}.svf 34 | endif 35 | 36 | clean: 37 | rm -rf build *.{${PNR2BIT_EXT},bit,cf,dfu,history,json,o,svf} *-report.txt 38 | 39 | include boards/$(BOARD).mk 40 | -------------------------------------------------------------------------------- /osflow/constraints/Fomu-evt2.pcf: -------------------------------------------------------------------------------- 1 | # Configuration for the Fomu 'evt2' board 2 | set_io clki 44 3 | set_io clki_alt 20 4 | set_io rgb[0] 39 5 | set_io rgb[1] 40 6 | set_io rgb[2] 41 7 | set_io pmod[0] 25 8 | set_io pmod[1] 26 9 | set_io pmod[2] 27 10 | set_io pmod[3] 28 11 | set_io user[0] 48 12 | set_io user[1] 47 13 | set_io user[2] 46 14 | set_io user[3] 45 15 | set_io user[4] 42 16 | set_io user[5] 38 17 | set_io spi_mosi 14 18 | set_io spi_miso 17 19 | set_io spi_clk 15 20 | set_io spi_cs 16 21 | set_io spi_io2 18 22 | set_io spi_io3 19 23 | set_io uart_tx 21 24 | set_io uart_rx 13 25 | set_io usb_dn 37 26 | set_io usb_dp 34 27 | set_io usb_dp_pu 35 28 | set_io usb_dn_pu 36 29 | set_io dbg[0] 20 30 | set_io dbg[1] 12 31 | set_io dbg[2] 11 32 | set_io dbg[3] 23 33 | set_io dbg[4] 10 34 | set_io dbg[5] 9 35 | -------------------------------------------------------------------------------- /osflow/constraints/Fomu-evt3.pcf: -------------------------------------------------------------------------------- 1 | # Configuration for the Fomu 'evt3' board 2 | set_io rgb[0] 39 3 | set_io rgb[1] 40 4 | set_io rgb[2] 41 5 | set_io pmod[0] 28 6 | set_io pmod[1] 27 7 | set_io pmod[2] 26 8 | set_io pmod[3] 23 9 | set_io clki_alt 20 10 | set_io clki 44 11 | set_io user[0] 48 12 | set_io user[1] 47 13 | set_io user[2] 46 14 | set_io user[3] 45 15 | set_io user[4] 42 16 | set_io user[5] 38 17 | set_io spi_mosi 14 18 | set_io spi_miso 17 19 | set_io spi_clk 15 20 | set_io spi_io2 18 21 | set_io spi_io3 19 22 | set_io spi_cs 16 23 | set_io uart_tx 21 24 | set_io uart_rx 13 25 | set_io usb_dn 37 26 | set_io usb_dp 34 27 | set_io usb_dp_pu 35 28 | set_io usb_dn_pu 36 29 | set_io dbg[0] 20 30 | set_io dbg[1] 12 31 | set_io dbg[2] 11 32 | set_io dbg[3] 25 33 | set_io dbg[4] 10 34 | set_io dbg[5] 9 35 | -------------------------------------------------------------------------------- /osflow/constraints/Fomu-hacker.pcf: -------------------------------------------------------------------------------- 1 | # Configuration for the Fomu 'hacker' board 2 | set_io clki F5 # Clock input from 48MHz Oscillator 3 | set_io rgb[0] A5 # Blue LED 4 | set_io rgb[1] B5 # Green LED 5 | set_io rgb[2] C5 # Red LED 6 | set_io user[0] F4 # User touch pad 1 7 | set_io user[1] E5 # User touch pad 2 8 | set_io user[2] E4 # User touch pad 3 9 | set_io user[3] F2 # User touch pad 4 10 | set_io spi_mosi F1 # SPI Master Out, Slave In Pin 11 | set_io spi_miso E1 # SPI Master In, Slave Out Pin 12 | set_io spi_clk D1 # SPI Master Clock Output Pin 13 | set_io spi_cs C1 # SPI Chip Select 14 | set_io usb_dn A2 # USB D- pad 15 | set_io usb_dp A4 # USB D+ pad 16 | set_io usb_dp_pu D5 # USB D+ pull up (indicates device connected) 17 | -------------------------------------------------------------------------------- /osflow/constraints/Fomu-pvt.pcf: -------------------------------------------------------------------------------- 1 | # Configuration for the Fomu 'pvt' board 2 | set_io clki F4 # Clock input from 48MHz Oscillator 3 | set_io rgb[0] A5 # Blue LED 4 | set_io rgb[1] B5 # Green LED 5 | set_io rgb[2] C5 # Red LED 6 | set_io user[0] E4 # User touch pad 1 7 | set_io user[1] D5 # User touch pad 2 8 | set_io user[2] E5 # User touch pad 3 9 | set_io user[3] F5 # User touch pad 4 10 | set_io spi_mosi F1 # SPI Master Out, Slave In Pin 11 | set_io spi_miso E1 # SPI Master In, Slave Out Pin 12 | set_io spi_clk D1 # SPI Master Clock Output Pin 13 | set_io spi_cs C1 # SPI Chip Select 14 | set_io spi_io2 F2 15 | set_io spi_io3 B1 16 | set_io usb_dn A2 # USB D- pad 17 | set_io usb_dp A1 # USB D+ pad 18 | set_io usb_dp_pu A4 # USB D+ pull up (indicates device connected) 19 | -------------------------------------------------------------------------------- /osflow/devices/ecp5/ecp5_components.vhd: -------------------------------------------------------------------------------- 1 | library ieee ; 2 | use ieee.std_logic_1164.all; 3 | 4 | package components is 5 | 6 | -- Yosys wrapper components 7 | 8 | component EHXPLLL 9 | generic 10 | ( 11 | CLKI_DIV : integer := 1; 12 | CLKFB_DIV : integer := 1; 13 | CLKOP_DIV : integer := 8; 14 | CLKOS_DIV : integer := 8; 15 | CLKOS2_DIV : integer := 8; 16 | CLKOS3_DIV : integer := 8; 17 | CLKOP_ENABLE : string := "ENABLED"; 18 | CLKOS_ENABLE : string := "DISABLED"; 19 | CLKOS2_ENABLE : string := "DISABLED"; 20 | CLKOS3_ENABLE : string := "DISABLED"; 21 | CLKOP_CPHASE : integer := 0; 22 | CLKOS_CPHASE : integer := 0; 23 | CLKOS2_CPHASE : integer := 0; 24 | CLKOS3_CPHASE : integer := 0; 25 | CLKOP_FPHASE : integer := 0; 26 | CLKOS_FPHASE : integer := 0; 27 | CLKOS2_FPHASE : integer := 0; 28 | CLKOS3_FPHASE : integer := 0; 29 | FEEDBK_PATH : string := "CLKOP"; 30 | CLKOP_TRIM_POL : string := "RISING"; 31 | CLKOP_TRIM_DELAY : integer := 0; 32 | CLKOS_TRIM_POL : string := "RISING"; 33 | CLKOS_TRIM_DELAY : integer := 0; 34 | OUTDIVIDER_MUXA : string := "DIVA"; 35 | OUTDIVIDER_MUXB : string := "DIVB"; 36 | OUTDIVIDER_MUXC : string := "DIVC"; 37 | OUTDIVIDER_MUXD : string := "DIVD"; 38 | PLL_LOCK_MODE : integer := 0; 39 | PLL_LOCK_DELAY : integer := 200; 40 | STDBY_ENABLE : string := "DISABLED"; 41 | REFIN_RESET : string := "DISABLED"; 42 | SYNC_ENABLE : string := "DISABLED"; 43 | INT_LOCK_STICKY : string := "ENABLED"; 44 | DPHASE_SOURCE : string := "DISABLED"; 45 | PLLRST_ENA : string := "DISABLED"; 46 | INTFB_WAKE : string := "DISABLED" 47 | ); 48 | port 49 | ( 50 | CLKI : IN std_logic := 'X'; 51 | CLKFB : IN std_logic := 'X'; 52 | RST : IN std_logic := 'X'; 53 | STDBY : IN std_logic := 'X'; 54 | PLLWAKESYNC : IN std_logic := 'X'; 55 | PHASESEL1 : IN std_logic := 'X'; 56 | PHASESEL0 : IN std_logic := 'X'; 57 | PHASEDIR : IN std_logic := 'X'; 58 | PHASESTEP : IN std_logic := 'X'; 59 | PHASELOADREG : IN std_logic := 'X'; 60 | ENCLKOP : IN std_logic := 'X'; 61 | ENCLKOS : IN std_logic := 'X'; 62 | ENCLKOS2 : IN std_logic := 'X'; 63 | ENCLKOS3 : IN std_logic := 'X'; 64 | CLKOP : OUT std_logic := 'X'; 65 | CLKOS : OUT std_logic := 'X'; 66 | CLKOS2 : OUT std_logic := 'X'; 67 | CLKOS3 : OUT std_logic := 'X'; 68 | LOCK : OUT std_logic := 'X'; 69 | INTLOCK : OUT std_logic := 'X'; 70 | REFCLK : OUT std_logic := 'X'; 71 | CLKINTFB : OUT std_logic := 'X' 72 | ); 73 | end component; 74 | 75 | end package; 76 | -------------------------------------------------------------------------------- /osflow/devices/ice40/neorv32_dmem.ice40up_spram.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Data Memory (DMEM) -- 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 | 14 | library neorv32; 15 | use neorv32.neorv32_package.all; 16 | 17 | library iCE40; 18 | use iCE40.components.all; 19 | 20 | entity neorv32_dmem is 21 | generic ( 22 | DMEM_SIZE : natural; -- memory size in bytes, has to be a power of 2, min 4 23 | OUTREG_EN : boolean -- implement output register stage 24 | ); 25 | port ( 26 | clk_i : in std_ulogic; -- global clock line 27 | rstn_i : in std_ulogic; -- async reset, low-active 28 | bus_req_i : in bus_req_t; -- bus request 29 | bus_rsp_o : out bus_rsp_t -- bus response 30 | ); 31 | end neorv32_dmem; 32 | 33 | architecture neorv32_dmem_rtl of neorv32_dmem is 34 | 35 | -- advanced configuration -------------------------------------------------------------------------------- 36 | constant spram_sleep_mode_en_c : boolean := false; -- put DMEM into sleep mode when idle (for low power) 37 | -- ------------------------------------------------------------------------------------------------------- 38 | 39 | -- IO space: module base address -- 40 | constant hi_abb_c : natural := 31; -- high address boundary bit 41 | constant lo_abb_c : natural := index_size_f(DMEM_SIZE); -- low address boundary bit 42 | 43 | -- local signals -- 44 | signal mem_cs : std_ulogic; 45 | signal rdata : std_ulogic_vector(31 downto 0); 46 | signal rden : std_ulogic; 47 | 48 | -- SPRAM signals -- 49 | signal spram_clk : std_logic; 50 | signal spram_addr : std_logic_vector(13 downto 0); 51 | signal spram_di_lo : std_logic_vector(15 downto 0); 52 | signal spram_di_hi : std_logic_vector(15 downto 0); 53 | signal spram_do_lo : std_logic_vector(15 downto 0); 54 | signal spram_do_hi : std_logic_vector(15 downto 0); 55 | signal spram_be_lo : std_logic_vector(03 downto 0); 56 | signal spram_be_hi : std_logic_vector(03 downto 0); 57 | signal spram_we : std_logic; 58 | signal spram_pwr_n : std_logic; 59 | signal spram_cs : std_logic; 60 | 61 | begin 62 | 63 | -- Sanity Checks -------------------------------------------------------------------------- 64 | -- ------------------------------------------------------------------------------------------- 65 | assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using iCE40up SPRAM-based DMEM." severity note; 66 | assert not (DMEM_SIZE /= 64*1024) report "NEORV32 PROCESSOR CONFIG NOTE: DMEM SPRAM has a fixed physical size of 64kB." severity note; 67 | 68 | 69 | -- Access Control ------------------------------------------------------------------------- 70 | -- ------------------------------------------------------------------------------------------- 71 | mem_cs <= bus_req_i.stb; 72 | 73 | 74 | -- Memory Access -------------------------------------------------------------------------- 75 | -- ------------------------------------------------------------------------------------------- 76 | imem_spram_lo_inst : SB_SPRAM256KA 77 | port map ( 78 | ADDRESS => spram_addr, -- I 79 | DATAIN => spram_di_lo, -- I 80 | MASKWREN => spram_be_lo, -- I 81 | WREN => spram_we, -- I 82 | CHIPSELECT => spram_cs, -- I 83 | CLOCK => spram_clk, -- I 84 | STANDBY => '0', -- I 85 | SLEEP => spram_pwr_n, -- I 86 | POWEROFF => '1', -- I 87 | DATAOUT => spram_do_lo -- O 88 | ); 89 | 90 | imem_spram_hi_inst : SB_SPRAM256KA 91 | port map ( 92 | ADDRESS => spram_addr, -- I 93 | DATAIN => spram_di_hi, -- I 94 | MASKWREN => spram_be_hi, -- I 95 | WREN => spram_we, -- I 96 | CHIPSELECT => spram_cs, -- I 97 | CLOCK => spram_clk, -- I 98 | STANDBY => '0', -- I 99 | SLEEP => spram_pwr_n, -- I 100 | POWEROFF => '1', -- I 101 | DATAOUT => spram_do_hi -- O 102 | ); 103 | 104 | -- access logic and signal type conversion -- 105 | spram_clk <= std_logic(clk_i); 106 | spram_addr <= std_logic_vector(bus_req_i.addr(13+2 downto 0+2)); 107 | spram_di_lo <= std_logic_vector(bus_req_i.data(15 downto 00)); 108 | spram_di_hi <= std_logic_vector(bus_req_i.data(31 downto 16)); 109 | spram_we <= '1' when (bus_req_i.rw = '1') else '0'; -- global write enable 110 | spram_cs <= std_logic(mem_cs); 111 | spram_be_lo <= std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(0)) & std_logic(bus_req_i.ben(0)); -- low byte write enable 112 | spram_be_hi <= std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(2)) & std_logic(bus_req_i.ben(2)); -- high byte write enable 113 | spram_pwr_n <= '0' when ((spram_sleep_mode_en_c = false) or (mem_cs = '1')) else '1'; -- LP mode disabled or IMEM selected 114 | rdata <= std_ulogic_vector(spram_do_hi) & std_ulogic_vector(spram_do_lo); 115 | 116 | buffer_ff: process(clk_i) 117 | begin 118 | if rising_edge(clk_i) then 119 | bus_rsp_o.ack <= mem_cs; 120 | rden <= bus_req_i.stb and (not bus_req_i.rw); 121 | end if; 122 | end process buffer_ff; 123 | 124 | -- no access error possible -- 125 | bus_rsp_o.err <= '0'; 126 | 127 | -- output gate -- 128 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); 129 | 130 | 131 | end neorv32_dmem_rtl; 132 | -------------------------------------------------------------------------------- /osflow/devices/ice40/neorv32_imem.ice40up_spram.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Instruction Memory (IMEM) -- 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 | 14 | library neorv32; 15 | use neorv32.neorv32_package.all; 16 | 17 | library iCE40; 18 | use iCE40.components.all; 19 | 20 | entity neorv32_imem is 21 | generic ( 22 | IMEM_SIZE : natural; -- memory size in bytes, has to be a power of 2, min 4 23 | IMEM_INIT : boolean; -- implement IMEM as pre-initialized read-only memory? 24 | OUTREG_EN : boolean -- implement output register stage 25 | ); 26 | port ( 27 | clk_i : in std_ulogic; -- global clock line 28 | rstn_i : in std_ulogic; -- async reset, low-active 29 | bus_req_i : in bus_req_t; -- bus request 30 | bus_rsp_o : out bus_rsp_t -- bus response 31 | ); 32 | end neorv32_imem; 33 | 34 | architecture neorv32_imem_rtl of neorv32_imem is 35 | 36 | -- advanced configuration -------------------------------------------------------------------------------- 37 | constant spram_sleep_mode_en_c : boolean := false; -- put IMEM into sleep mode when idle (for low power) 38 | -- ------------------------------------------------------------------------------------------------------- 39 | 40 | -- IO space: module base address -- 41 | constant hi_abb_c : natural := 31; -- high address boundary bit 42 | constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit 43 | 44 | -- local signals -- 45 | signal mem_cs : std_ulogic; 46 | signal rdata : std_ulogic_vector(31 downto 0); 47 | signal rden : std_ulogic; 48 | 49 | -- SPRAM signals -- 50 | signal spram_clk : std_logic; 51 | signal spram_addr : std_logic_vector(13 downto 0); 52 | signal spram_di_lo : std_logic_vector(15 downto 0); 53 | signal spram_di_hi : std_logic_vector(15 downto 0); 54 | signal spram_do_lo : std_logic_vector(15 downto 0); 55 | signal spram_do_hi : std_logic_vector(15 downto 0); 56 | signal spram_be_lo : std_logic_vector(03 downto 0); 57 | signal spram_be_hi : std_logic_vector(03 downto 0); 58 | signal spram_we : std_logic; 59 | signal spram_pwr_n : std_logic; 60 | signal spram_cs : std_logic; 61 | 62 | begin 63 | 64 | -- Sanity Checks -------------------------------------------------------------------------- 65 | -- ------------------------------------------------------------------------------------------- 66 | assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using iCE40up SPRAM-based IMEM." severity note; 67 | assert not (IMEM_INIT = true) report "NEORV32 PROCESSOR CONFIG ERROR: ICE40 Ultra Plus SPRAM cannot be initialized by bitstream!" severity failure; 68 | assert not (IMEM_SIZE /= 64*1024) report "NEORV32 PROCESSOR CONFIG NOTE: IMEM SPRAM has a fixed physical size of 64kB." severity note; 69 | 70 | 71 | -- Access Control ------------------------------------------------------------------------- 72 | -- ------------------------------------------------------------------------------------------- 73 | mem_cs <= bus_req_i.stb; 74 | 75 | 76 | -- Memory Access -------------------------------------------------------------------------- 77 | -- ------------------------------------------------------------------------------------------- 78 | imem_spram_lo_inst : SB_SPRAM256KA 79 | port map ( 80 | ADDRESS => spram_addr, -- I 81 | DATAIN => spram_di_lo, -- I 82 | MASKWREN => spram_be_lo, -- I 83 | WREN => spram_we, -- I 84 | CHIPSELECT => spram_cs, -- I 85 | CLOCK => spram_clk, -- I 86 | STANDBY => '0', -- I 87 | SLEEP => spram_pwr_n, -- I 88 | POWEROFF => '1', -- I 89 | DATAOUT => spram_do_lo -- O 90 | ); 91 | 92 | imem_spram_hi_inst : SB_SPRAM256KA 93 | port map ( 94 | ADDRESS => spram_addr, -- I 95 | DATAIN => spram_di_hi, -- I 96 | MASKWREN => spram_be_hi, -- I 97 | WREN => spram_we, -- I 98 | CHIPSELECT => spram_cs, -- I 99 | CLOCK => spram_clk, -- I 100 | STANDBY => '0', -- I 101 | SLEEP => spram_pwr_n, -- I 102 | POWEROFF => '1', -- I 103 | DATAOUT => spram_do_hi -- O 104 | ); 105 | 106 | -- access logic and signal type conversion -- 107 | spram_clk <= std_logic(clk_i); 108 | spram_addr <= std_logic_vector(bus_req_i.addr(13+2 downto 0+2)); 109 | spram_di_lo <= std_logic_vector(bus_req_i.data(15 downto 00)); 110 | spram_di_hi <= std_logic_vector(bus_req_i.data(31 downto 16)); 111 | spram_we <= '1' when (bus_req_i.rw = '1') else '0'; -- global write enable 112 | spram_cs <= std_logic(mem_cs); 113 | spram_be_lo <= std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(0)) & std_logic(bus_req_i.ben(0)); -- low byte write enable 114 | spram_be_hi <= std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(2)) & std_logic(bus_req_i.ben(2)); -- high byte write enable 115 | spram_pwr_n <= '0' when ((spram_sleep_mode_en_c = false) or (mem_cs = '1')) else '1'; -- LP mode disabled or IMEM selected 116 | rdata <= std_ulogic_vector(spram_do_hi) & std_ulogic_vector(spram_do_lo); 117 | 118 | buffer_ff: process(clk_i) 119 | begin 120 | if rising_edge(clk_i) then 121 | bus_rsp_o.ack <= mem_cs; 122 | rden <= bus_req_i.stb and (not bus_req_i.rw); 123 | end if; 124 | end process buffer_ff; 125 | 126 | -- no access error possible -- 127 | bus_rsp_o.err <= '0'; 128 | 129 | -- output gate -- 130 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); 131 | 132 | 133 | end neorv32_imem_rtl; 134 | -------------------------------------------------------------------------------- /osflow/devices/ice40/sb_ice40_components.v: -------------------------------------------------------------------------------- 1 | (* blackbox *) 2 | module SB_HFOSC ( 3 | input CLKHFEN, 4 | input CLKHFPU, 5 | output CLKHF 6 | ); 7 | parameter CLKHF_DIV = 2'b00; 8 | endmodule 9 | 10 | (* blackbox *) 11 | module SB_PLL40_CORE ( 12 | input REFERENCECLK, 13 | output PLLOUTCORE, 14 | output PLLOUTGLOBAL, 15 | input EXTFEEDBACK, 16 | input [7:0] DYNAMICDELAY, 17 | output LOCK, 18 | input BYPASS, 19 | input RESETB, 20 | input LATCHINPUTVALUE, 21 | output SDO, 22 | input SDI, 23 | input SCLK 24 | ); 25 | parameter FEEDBACK_PATH = "SIMPLE"; 26 | parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED"; 27 | parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED"; 28 | parameter SHIFTREG_DIV_MODE = 1'b0; 29 | parameter FDA_FEEDBACK = 4'b0000; 30 | parameter FDA_RELATIVE = 4'b0000; 31 | parameter PLLOUT_SELECT = "GENCLK"; 32 | parameter DIVR = 4'b0000; 33 | parameter DIVF = 7'b0000000; 34 | parameter DIVQ = 3'b000; 35 | parameter FILTER_RANGE = 3'b000; 36 | parameter ENABLE_ICEGATE = 1'b0; 37 | parameter TEST_MODE = 1'b0; 38 | parameter EXTERNAL_DIVIDE_FACTOR = 1; 39 | endmodule 40 | -------------------------------------------------------------------------------- /osflow/devices/ice40/sb_ice40_components.vhd: -------------------------------------------------------------------------------- 1 | library ieee ; 2 | use ieee.std_logic_1164.all; 3 | 4 | package components is 5 | 6 | -- Yosys / IceCube wrapper components 7 | 8 | component SB_GB 9 | port( 10 | GLOBAL_BUFFER_OUTPUT : out std_logic; 11 | USER_SIGNAL_TO_GLOBAL_BUFFER : in std_logic 12 | ); 13 | end component; 14 | 15 | component SB_HFOSC 16 | generic ( 17 | CLKHF_DIV : string 18 | ); 19 | port ( 20 | CLKHFPU : in std_logic; 21 | CLKHFEN : in std_logic; 22 | CLKHF : out std_logic 23 | ); 24 | end component; 25 | 26 | component SB_PLL40_CORE is 27 | generic ( 28 | FEEDBACK_PATH : string := "SIMPLE"; 29 | DELAY_ADJUSTMENT_MODE_FEEDBACK : string := "FIXED"; 30 | DELAY_ADJUSTMENT_MODE_RELATIVE : string := "FIXED"; 31 | SHIFTREG_DIV_MODE : std_logic := '0'; 32 | FDA_FEEDBACK : std_logic_vector(3 downto 0) := x"0"; 33 | FDA_RELATIVE : std_logic_vector(3 downto 0) := x"0"; 34 | PLLOUT_SELECT : string := "GENCLK"; 35 | DIVR : std_logic_vector(3 downto 0) := x"0"; 36 | DIVF : std_logic_vector(6 downto 0) := "0000000"; 37 | DIVQ : std_logic_vector(2 downto 0) := "000"; 38 | FILTER_RANGE : std_logic_vector(2 downto 0) := "000"; 39 | ENABLE_ICEGATE : bit := '0'; 40 | TEST_MODE : bit := '0'; 41 | EXTERNAL_DIVIDE_FACTOR : integer := 1 42 | ); 43 | port ( 44 | REFERENCECLK : in std_logic; 45 | PLLOUTCORE : out std_logic; 46 | PLLOUTGLOBAL : out std_logic; 47 | EXTFEEDBACK : in std_logic; 48 | DYNAMICDELAY : in std_logic_vector(7 downto 0); 49 | LOCK : out std_logic; 50 | BYPASS : in std_logic; 51 | RESETB : in std_logic; 52 | LATCHINPUTVALUE : in std_logic; 53 | SDO : out std_logic; 54 | SDI : in std_logic; 55 | SCLK : in std_logic 56 | ); 57 | end component; 58 | 59 | component SB_PLL40_PAD 60 | generic ( 61 | FEEDBACK_PATH : string := "SIMPLE"; 62 | DELAY_ADJUSTMENT_MODE_FEEDBACK : string := "FIXED"; 63 | DELAY_ADJUSTMENT_MODE_RELATIVE : string := "FIXED"; 64 | SHIFTREG_DIV_MODE : bit_vector(1 downto 0) := "00"; 65 | FDA_FEEDBACK : bit_vector(3 downto 0) := "0000"; 66 | FDA_RELATIVE : bit_vector(3 downto 0) := "0000"; 67 | PLLOUT_SELECT : string := "GENCLK"; 68 | DIVR : bit_vector(3 downto 0) := x"0"; 69 | DIVF : bit_vector(6 downto 0) := "0000000"; 70 | DIVQ : bit_vector(2 downto 0) := "000"; 71 | FILTER_RANGE : bit_vector(2 downto 0) := "000"; 72 | ENABLE_ICEGATE : bit := '0'; 73 | TEST_MODE : bit := '0'; 74 | EXTERNAL_DIVIDE_FACTOR : integer := 1 75 | ); 76 | port ( 77 | PACKAGEPIN : in std_logic; 78 | PLLOUTCORE : out std_logic; 79 | PLLOUTGLOBAL : out std_logic; 80 | EXTFEEDBACK : in std_logic; 81 | DYNAMICDELAY : in std_logic_vector(7 downto 0); 82 | LOCK : out std_logic; 83 | BYPASS : in std_logic; 84 | RESETB : in std_logic; 85 | LATCHINPUTVALUE : in std_logic; 86 | SDO : out std_logic; 87 | SDI : in std_logic; 88 | SCLK : in std_logic 89 | ); 90 | end component; 91 | 92 | component SB_RGBA_DRV 93 | generic ( 94 | CURRENT_MODE : string := "0b0"; 95 | RGB0_CURRENT : string := "0b000000"; 96 | RGB1_CURRENT : string := "0b000000"; 97 | RGB2_CURRENT : string := "0b000000" 98 | ); 99 | port ( 100 | RGB0PWM : in std_logic; 101 | RGB1PWM : in std_logic; 102 | RGB2PWM : in std_logic; 103 | CURREN : in std_logic; 104 | RGBLEDEN : in std_logic; 105 | RGB0 : out std_logic; 106 | RGB1 : out std_logic; 107 | RGB2 : out std_logic 108 | ); 109 | end component; 110 | 111 | component SB_SPRAM256KA 112 | port ( 113 | ADDRESS : in std_logic_vector(13 downto 0); 114 | DATAIN : in std_logic_vector(15 downto 0); 115 | MASKWREN : in std_logic_vector(3 downto 0); 116 | WREN : in std_logic; 117 | CHIPSELECT : in std_logic; 118 | CLOCK : in std_logic; 119 | STANDBY : in std_logic; 120 | SLEEP : in std_logic; 121 | POWEROFF : in std_logic; 122 | DATAOUT : out std_logic_vector(15 downto 0) 123 | ); 124 | end component; 125 | 126 | end package; 127 | -------------------------------------------------------------------------------- /osflow/filesets.mk: -------------------------------------------------------------------------------- 1 | # read default SoC file-list file 2 | NEORV32_HOME = ../neorv32 3 | NEORV32_SOC_FILE = $(shell cat $(NEORV32_HOME)/rtl/file_list_soc.f) 4 | NEORV32_CORE_SRC = $(subst NEORV32_RTL_PATH_PLACEHOLDER, $(NEORV32_HOME)/rtl, $(NEORV32_SOC_FILE)) 5 | 6 | # Before including this partial makefile, NEORV32_MEM_SRC needs to be set 7 | # (containing two VHDL sources: one for IMEM and one for DMEM) 8 | 9 | NEORV32_SRC := $(NEORV32_CORE_SRC) ${NEORV32_MEM_SRC} ${NEORV32_MEM_SRC_EXTRA} ${NEORV32_CORE_SRC_EXTRA} 10 | NEORV32_VERILOG_ALL := ${NEORV32_VERILOG_SRC} ${NEORV32_VERILOG_SRC_EXTRA} 11 | 12 | ICE40_SRC := \ 13 | devices/ice40/sb_ice40_components.vhd 14 | 15 | ECP5_SRC := \ 16 | devices/ecp5/ecp5_components.vhd 17 | 18 | ifeq ($(DEVICE_SERIES),ecp5) 19 | DEVICE_SRC := ${ECP5_SRC} 20 | else 21 | DEVICE_SRC := ${ICE40_SRC} 22 | endif 23 | 24 | # Optionally NEORV32_VERILOG_SRC can be set to a list of Verilog sources 25 | -------------------------------------------------------------------------------- /osflow/synthesis.mk: -------------------------------------------------------------------------------- 1 | ${DEVICE_LIB}-obj08.cf: ${DEVICE_SRC} 2 | mkdir -p build 3 | ghdl -a $(GHDL_FLAGS) --workdir=build --work=${DEVICE_LIB} ${DEVICE_SRC} 4 | 5 | neorv32-obj08.cf: ${DEVICE_LIB}-obj08.cf ${NEORV32_SRC} 6 | ghdl -i $(GHDL_FLAGS) --work=neorv32 ${NEORV32_SRC} 7 | ghdl -m $(GHDL_FLAGS) --work=neorv32 neorv32_top 8 | 9 | work-obj08.cf: neorv32-obj08.cf ${DESIGN_SRC} ${BOARD_SRC} 10 | ghdl -a $(GHDL_FLAGS) --work=work ${DESIGN_SRC} ${BOARD_SRC} 11 | 12 | ifeq ($(strip $(NEORV32_VERILOG_ALL)),) 13 | READ_VERILOG = 14 | else 15 | READ_VERILOG = read_verilog ${NEORV32_VERILOG_ALL}; 16 | endif 17 | 18 | ${IMPL}.json: work-obj08.cf $(NEORV32_VERILOG_ALL) 19 | $(YOSYS) $(YOSYSFLAGS) \ 20 | -p \ 21 | "$(GHDLSYNTH) $(GHDL_FLAGS) --no-formal $(TOP); \ 22 | $(READ_VERILOG) synth_${YOSYSSYNTH} \ 23 | -top $(TOP) $(YOSYSPIPE) \ 24 | -json $@" 2>&1 | tee yosys-report.txt 25 | -------------------------------------------------------------------------------- /osflow/tools.mk: -------------------------------------------------------------------------------- 1 | GHDL_FLAGS += --std=08 --workdir=build -Pbuild 2 | GHDL ?= ghdl 3 | GHDLSYNTH ?= ghdl 4 | YOSYS ?= yosys 5 | ICEPACK ?= icepack 6 | ECPPACK ?= ecppack 7 | OPENOCD ?= openocd 8 | COPY ?= cp -a 9 | 10 | DEVICE_SERIES ?= ice40 11 | DEVICE_LIB ?= $(DEVICE_SERIES) 12 | YOSYSSYNTH ?= $(DEVICE_SERIES) 13 | NEXTPNR ?= nextpnr-$(DEVICE_SERIES) 14 | 15 | ifeq ($(DEVICE_SERIES),ice40) 16 | YOSYSPIPE ?= -dsp 17 | CONSTRAINTS_FORMAT ?= pcf 18 | NEXTPNR_OUT ?= asc 19 | PNR2BIT_EXT ?= asc 20 | PACKTOOL ?= $(ICEPACK) 21 | PACKARGS ?= 22 | else 23 | CONSTRAINTS_FORMAT ?= lpf 24 | NEXTPNR_OUT ?= textcfg 25 | PNR2BIT_EXT ?= cfg 26 | PACKTOOL ?= $(ECPPACK) 27 | PACKARGS ?= --compress 28 | endif 29 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-avalonmm-wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | incremental_db 3 | output_files 4 | greybox_tmp 5 | *.qws 6 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-avalonmm-wrapper/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup using the NEORV32 with AvalonMM Master Interface wrapper 2 | 3 | This setup provides a very simple "demo setup" that uses the NEORV32 with a AvalonMM 4 | Interface wrapper. This makes if possible to connect you own modules using a simple 5 | version of the AvalonMM Master interface. 6 | 7 | Note that the AvalonMM Master is a very simple version providing only basic features: 8 | 9 | * Single read and write access 10 | * Flow control (variable wait-states) 11 | * 8/16/32 bit data access 12 | * Aligned and unaligned access supported 13 | 14 | The AvalonMM Master does **not** support: 15 | * Burst access 16 | * Pipeline transfer 17 | * Pending reads 18 | 19 | The design is based on the de0-nano-test-setup, but added a AvalonMM Master wrapper. 20 | The wrapper file can be found here [`AvalonMM wrapper`](../../../rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd). 21 | 22 | As a test an "external" DMEM is conneced to the NEORV32 over the AvalonMM Master Interface. 23 | 24 | It uses the simplified and simple example top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs). 25 | 26 | * FPGA Board: :books: [Terasic DE0-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) 27 | * FPGA: Intel Cyclone-IV `EP4CE22F17C6N` 28 | * Toolchain: Intel Quartus Prime (tested with Quartus Prime 18.1.1 - Lite Edition) 29 | 30 | 31 | ### NEORV32 Configuration 32 | 33 | For NEORV32 configuration the default values of the neorv32_top in version 1.6.0 are used 34 | with a few exceptions: 35 | 36 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (external DMEM), No bootloader 37 | * Tested with version [`1.6.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 38 | * Clock: 50MHz from on-board oscillator 39 | * Reset: via on-board button "KEY0" 40 | * GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0") 41 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header 42 | * `uart0_txd_o:` output, connected to FPGA pin `C3` - header pin `GPIO_01` (pin number "4") 43 | * `uart0_rxd_i:` input, connected to FPGA pin `A3` - header pin `GPIO_03` (pin number "6") 44 | 45 | ### FPGA Utilization 46 | 47 | ``` 48 | Total logic elements 3,439 / 22,320 ( 15 % ) 49 | Total registers 1674 50 | Total pins 12 / 154 ( 8 % ) 51 | Total virtual pins 0 52 | Total memory bits 197,632 / 608,256 ( 32 % ) 53 | Embedded Multiplier 9-bit elements 0 / 132 ( 0 % ) 54 | Total PLLs 0 / 4 ( 0 % ) 55 | ``` 56 | 57 | 58 | ## How To Run 59 | 60 | Open the Quartus project file, compile and upload to FPGA. -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-avalonmm-wrapper/de0-nano-test-setup.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2019 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and any partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details, at 16 | # https://fpgasoftware.intel.com/eula. 17 | # 18 | # -------------------------------------------------------------------------- # 19 | # 20 | # Quartus Prime 21 | # Version 18.1.1 Build 646 04/11/2019 SJ Lite Edition 22 | # Date created = 20:23:30 September 13, 2021 23 | # 24 | # -------------------------------------------------------------------------- # 25 | 26 | QUARTUS_VERSION = "18.1" 27 | DATE = "20:23:30 September 13, 2021" 28 | 29 | # Revisions 30 | 31 | PROJECT_REVISION = "de0-nano-test-setup" 32 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-avalonmm-wrapper/dmem_ram.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "18.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "dmem_ram.vhd"] 5 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/.gitignore: -------------------------------------------------------------------------------- 1 | /.qsys_edit 2 | /db 3 | /neorv32_test_qsys 4 | /*.sopcinfo 5 | /*.rpt 6 | /output_files 7 | /incremental_db 8 | /*.qws 9 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup using the NEORV32 as a Nios II drop-in replacement 2 | 3 | This setup provides a very simple "demo setup" that uses the NEORV32 Qsys/Platform Designer component 4 | so that the NEORV32 can be used as a drop-in replacement of the Nios II soft CPU from Intel. 5 | The demo is running on the Terasic DE0-Nano FPGA Board. 6 | 7 | The design is based on the de0-nano-test-setup, but the NEORV32 cpu is added as a QSys/Platform Designer 8 | component. As an example the DMEM is "external" and uses an Platform Designer SRAM block. 9 | 10 | ![NEORV32 in Platform Designer](figures/neorv32_platform_designer.png) 11 | 12 | For details about the design and use of the NEORV32 as a Qsys/Platform Designer component please 13 | look at the Qsys component files and documentation here [`NEORV32 Qsys Component`](../neorv32_qsys_component) 14 | 15 | It uses the simplified simple example top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs). 16 | 17 | * FPGA Board: :books: [Terasic DE0-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) 18 | * FPGA: Intel Cyclone-IV `EP4CE22F17C6N` 19 | * Toolchain: Intel Quartus Prime (tested with Quartus Prime 18.1.1 - Lite Edition) 20 | 21 | 22 | ### NEORV32 Configuration 23 | 24 | For NEORV32 configuration the default values of the neorv32_top in version 1.6.0 are used 25 | with a few exceptions: 26 | 27 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (external DMEM), No bootloader 28 | * Tested with version [`1.6.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 29 | * Clock: 50MHz from on-board oscillator 30 | * Reset: via on-board button "KEY0" 31 | * GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0") 32 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header 33 | * `uart0_txd_o:` output, connected to FPGA pin `C3` - header pin `GPIO_01` (pin number "4") 34 | * `uart0_rxd_i:` input, connected to FPGA pin `A3` - header pin `GPIO_03` (pin number "6") 35 | 36 | ### FPGA Utilization 37 | 38 | ``` 39 | Total logic elements 4,064 / 22,320 ( 18 % ) 40 | Total registers 1932 41 | Total pins 12 / 154 ( 8 % ) 42 | Total virtual pins 0 43 | Total memory bits 230,400 / 608,256 ( 38 % ) 44 | Embedded Multiplier 9-bit elements 0 / 132 ( 0 % ) 45 | Total PLLs 0 / 4 ( 0 % ) 46 | ``` 47 | 48 | 49 | ## How To Run 50 | 51 | Open the Quartus project file, compile and upload to FPGA. -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/User_Components.ipx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/de0-nano-test-setup.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2019 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and any partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details, at 16 | # https://fpgasoftware.intel.com/eula. 17 | # 18 | # -------------------------------------------------------------------------- # 19 | # 20 | # Quartus Prime 21 | # Version 18.1.1 Build 646 04/11/2019 SJ Lite Edition 22 | # Date created = 21:29:54 June 08, 2021 23 | # 24 | # -------------------------------------------------------------------------- # 25 | 26 | QUARTUS_VERSION = "18.1" 27 | DATE = "21:29:54 June 08, 2021" 28 | 29 | # Revisions 30 | 31 | PROJECT_REVISION = "de0-nano-test-setup" 32 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/de0-nano-test-setup.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2019 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and any partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details, at 16 | # https://fpgasoftware.intel.com/eula. 17 | # 18 | # -------------------------------------------------------------------------- # 19 | # 20 | # Quartus Prime 21 | # Version 18.1.1 Build 646 04/11/2019 SJ Lite Edition 22 | # Date created = 21:29:54 June 08, 2021 23 | # 24 | # -------------------------------------------------------------------------- # 25 | # 26 | # Notes: 27 | # 28 | # 1) The default values for assignments are stored in the file: 29 | # de0-nano-test-setup_assignment_defaults.qdf 30 | # If this file doesn't exist, see file: 31 | # assignment_defaults.qdf 32 | # 33 | # 2) Altera recommends that you do not modify this file. This 34 | # file is updated automatically by the Quartus Prime software 35 | # and any changes you make may be lost or overwritten. 36 | # 37 | # -------------------------------------------------------------------------- # 38 | 39 | 40 | set_global_assignment -name FAMILY "Cyclone IV E" 41 | set_global_assignment -name DEVICE EP4CE22F17C6 42 | set_global_assignment -name TOP_LEVEL_ENTITY neorv32_ProcessorTop_Test 43 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0 44 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:40:53 APRIL 10, 2021" 45 | set_global_assignment -name LAST_QUARTUS_VERSION "18.1.1 Lite Edition" 46 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 47 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 48 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 49 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 50 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 51 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id neorv32_ProcessorTop_Test 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id neorv32_ProcessorTop_Test 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id neorv32_ProcessorTop_Test 55 | set_location_assignment PIN_R8 -to clk_i 56 | set_location_assignment PIN_J15 -to rstn_i 57 | set_location_assignment PIN_C3 -to uart0_txd_o 58 | set_location_assignment PIN_A3 -to uart0_rxd_i 59 | set_location_assignment PIN_L3 -to gpio_o[7] 60 | set_location_assignment PIN_B1 -to gpio_o[6] 61 | set_location_assignment PIN_F3 -to gpio_o[5] 62 | set_location_assignment PIN_D1 -to gpio_o[4] 63 | set_location_assignment PIN_A11 -to gpio_o[3] 64 | set_location_assignment PIN_B13 -to gpio_o[2] 65 | set_location_assignment PIN_A13 -to gpio_o[1] 66 | set_location_assignment PIN_A15 -to gpio_o[0] 67 | set_global_assignment -name QSYS_FILE neorv32_test_qsys.qsys 68 | set_global_assignment -name QIP_FILE ../neorv32_qsys_component/neorv32_qsys.qip 69 | set_global_assignment -name VHDL_FILE ../../NEORV32/rtl/core/neorv32_application_image.vhd 70 | set_global_assignment -name VHDL_FILE ../../NEORV32/rtl/core/neorv32_bootloader_image.vhd 71 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/neorv32_dmem.entity.vhd -library neorv32 72 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/neorv32_imem.entity.vhd -library neorv32 73 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_dmem.default.vhd -library neorv32 74 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_imem.default.vhd -library neorv32 75 | set_global_assignment -name VHDL_FILE neorv32_ProcessorTop_Test.vhd 76 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id neorv32_ProcessorTop_Test -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/de0-nano-test-setup.sdc: -------------------------------------------------------------------------------- 1 | #************************************************************** 2 | # Time Information 3 | #************************************************************** 4 | 5 | set_time_format -unit ns -decimal_places 3 6 | 7 | #************************************************************** 8 | # Create Clock 9 | #************************************************************** 10 | 11 | create_clock -name {altera_reserved_tck} -period 100.000 -waveform { 0.000 50.000 } [get_ports {altera_reserved_tck}] 12 | create_clock -name {clk_i} -period 20.0 -waveform { 0.0 10.0 } [get_ports {clk_i}] 13 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/figures/neorv32_platform_designer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32-setups/dcba8bb6089eacb39273255627121e25e7beea8b/quartus/de0-nano-test-setup-qsys/figures/neorv32_platform_designer.png -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup-qsys/neorv32_ProcessorTop_Test.vhd: -------------------------------------------------------------------------------- 1 | library ieee; 2 | use ieee.std_logic_1164.all; 3 | use ieee.std_logic_arith.all; 4 | use ieee.std_logic_unsigned.all; 5 | library work; 6 | 7 | entity neorv32_ProcessorTop_Test is port ( 8 | clk_i : in std_logic; 9 | rstn_i : in std_logic; 10 | gpio_o : out std_logic_vector(7 downto 0); 11 | uart0_txd_o : out std_logic; 12 | uart0_rxd_i : in std_logic); 13 | end neorv32_ProcessorTop_Test; 14 | 15 | ---------------------------------------------------------------------------------------------------- 16 | architecture rtl of neorv32_ProcessorTop_Test is 17 | ---------------------------------------------------------------------------------------------------- 18 | 19 | component neorv32_test_qsys is 20 | port ( 21 | clk_clk : in std_logic; 22 | perf_uart0_uart0_txd_o : out std_logic; 23 | perf_uart0_uart0_rxd_i : in std_logic; 24 | perf_gpio_gpio_o : out std_logic_vector(31 downto 0); 25 | perf_gpio_gpio_i : in std_logic_vector(31 downto 0); 26 | reset_reset_n : in std_logic); 27 | end component; 28 | 29 | signal perf_gpio_gpio_o : std_logic_vector(31 downto 0); 30 | 31 | begin 32 | 33 | gpio_o <= perf_gpio_gpio_o(7 downto 0); 34 | 35 | my_riscv_core : neorv32_test_qsys 36 | port map ( 37 | clk_clk => clk_i, 38 | perf_gpio_gpio_o => perf_gpio_gpio_o, 39 | perf_gpio_gpio_i => (others => '0'), 40 | perf_uart0_uart0_txd_o => uart0_txd_o, 41 | perf_uart0_uart0_rxd_i => uart0_rxd_i, 42 | reset_reset_n => rstn_i); 43 | 44 | end rtl; 45 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup/.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | incremental_db 3 | output_files 4 | *.qpf 5 | *.qsf 6 | *.qws 7 | *.vhd 8 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Terasic DE0-Nano FPGA Board 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Terasic DE0-Nano board. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor 5 | top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs). 6 | 7 | * FPGA Board: :books: [Terasic DE0-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) 8 | * FPGA: Intel Cyclone-IV `EP4CE22F17C6N` 9 | * Toolchain: Intel Quartus Prime (tested with Quartus Prime 20.1.0 - Lite Edition) 10 | 11 | 12 | ### NEORV32 Configuration 13 | 14 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 15 | configuration and entity details and `create_project.tcl` for the according FPGA pin mapping. 16 | 17 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors, 40-bit wide) 18 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 19 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 20 | * Tested with version [`1.5.7.6`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 21 | * Clock: 50MHz from on-board oscillator 22 | * Reset: via on-board button "KEY0" 23 | * GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0") 24 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header 25 | * `uart0_txd_o:` output, connected to FPGA pin `C3` - header pin `GPIO_01` (pin number "4") 26 | * `uart0_rxd_i:` input, connected to FPGA pin `A3` - header pin `GPIO_03` (pin number "6") 27 | 28 | :warning: The default [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity 29 | is configured for a 100MHz input clock. Since the on-board oscillator of the DE0-nano board generates a 50MHz clock, the test setup has to be modified. 30 | This is automatically done by the `create_project.tcl` TCL script, which makes a local copy of the original test setup VHDL file 31 | (in *this* folder) and uses `sed` to configure the `CLOCK_FREQUENCY` generic (in the local copy) for 50MHz. The local copy is then used as actual 32 | top entity. 33 | 34 | ### FPGA Utilization 35 | 36 | ``` 37 | Total logic elements 4,009 / 22,320 ( 18 % ) 38 | Total registers 1860 39 | Total pins 12 / 154 ( 8 % ) 40 | Total virtual pins 0 41 | Total memory bits 230,400 / 608,256 ( 38 % ) 42 | Embedded Multiplier 9-bit elements 0 / 132 ( 0 % ) 43 | Total PLLs 0 / 4 ( 0 % ) 44 | ``` 45 | 46 | 47 | ## How To Run 48 | 49 | The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project. 50 | If not already available, this script will create a `work` folder in this directory. 51 | 52 | 1. start Quartus (in GUI mode) 53 | 2. in the menu line click "View/Utility Windows/Tcl console" to open the Tcl console 54 | 3. use the console to naviagte to **this** folder: `cd .../neorv32-setups/quartus/de0-nano-test-setup` 55 | 4. execute `source create_project.tcl` - this will create and open the actual Quartus project in this folder 56 | 5. if a "select family" prompt appears select the "Cyclone IV E" family and click OK 57 | 6. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream 58 | 7. when the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA 59 | 8. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration: 60 | 19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline) 61 | 9. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) 62 | and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources. 63 | -------------------------------------------------------------------------------- /quartus/de0-nano-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | # make a local copy of original "./../../rtl/test_setups/neorv32_test_setup_bootloader.vhd " file 2 | # and modify the default clock frequency: set to 50MHz 3 | set shell_script "cp -f ./../../neorv32/rtl/test_setups/neorv32_test_setup_bootloader.vhd . && sed -i 's/100000000/50000000/g' neorv32_test_setup_bootloader.vhd " 4 | exec sh -c $shell_script 5 | 6 | # Copyright (C) 2020 Intel Corporation. All rights reserved. 7 | # Your use of Intel Corporation's design tools, logic functions 8 | # and other software and tools, and any partner logic 9 | # functions, and any output files from any of the foregoing 10 | # (including device programming or simulation files), and any 11 | # associated documentation or information are expressly subject 12 | # to the terms and conditions of the Intel Program License 13 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 14 | # the Intel FPGA IP License Agreement, or other applicable license 15 | # agreement, including, without limitation, that your use is for 16 | # the sole purpose of programming logic devices manufactured by 17 | # Intel and sold by Intel or its authorized distributors. Please 18 | # refer to the applicable agreement for further details, at 19 | # https://fpgasoftware.intel.com/eula. 20 | 21 | # Quartus Prime: Generate Tcl File for Project 22 | # File: de0_nano_test.tcl 23 | # Generated on: Sat Apr 10 16:57:48 2021 24 | 25 | # Load Quartus Prime Tcl Project package 26 | package require ::quartus::project 27 | 28 | set need_to_close_project 0 29 | set make_assignments 1 30 | 31 | # Check that the right project is open 32 | if {[is_project_open]} { 33 | if {[string compare $quartus(project) "de0-nano-test-setup"]} { 34 | puts "Project de0-nano-test-setup is not open" 35 | set make_assignments 0 36 | } 37 | } else { 38 | # Only open if not already open 39 | if {[project_exists de0-nano-test-setup]} { 40 | project_open -revision de0-nano-test-setup de0-nano-test-setup 41 | } else { 42 | project_new -revision de0-nano-test-setup de0-nano-test-setup 43 | } 44 | set need_to_close_project 1 45 | } 46 | 47 | # Make assignments 48 | if {$make_assignments} { 49 | set_global_assignment -name FAMILY "Cyclone IV E" 50 | set_global_assignment -name DEVICE EP4CE22F17C6 51 | set_global_assignment -name TOP_LEVEL_ENTITY neorv32_test_setup_bootloader 52 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0 53 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:40:53 APRIL 10, 2021" 54 | set_global_assignment -name LAST_QUARTUS_VERSION "20.1.0 Lite Edition" 55 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 56 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 57 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 58 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 59 | 60 | # core VHDL files 61 | set core_src_dir [glob ./../../neorv32/rtl/core/*.vhd] 62 | foreach core_src_file $core_src_dir { 63 | set_global_assignment -name VHDL_FILE $core_src_file -library neorv32 64 | } 65 | 66 | # top entity: use local modified copy of the original test setup 67 | set_global_assignment -name VHDL_FILE "neorv32_test_setup_bootloader.vhd" 68 | 69 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 70 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 71 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 72 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 73 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 74 | 75 | set_location_assignment PIN_R8 -to clk_i 76 | set_location_assignment PIN_L3 -to gpio_o[7] 77 | set_location_assignment PIN_B1 -to gpio_o[6] 78 | set_location_assignment PIN_F3 -to gpio_o[5] 79 | set_location_assignment PIN_D1 -to gpio_o[4] 80 | set_location_assignment PIN_A11 -to gpio_o[3] 81 | set_location_assignment PIN_B13 -to gpio_o[2] 82 | set_location_assignment PIN_A13 -to gpio_o[1] 83 | set_location_assignment PIN_A15 -to gpio_o[0] 84 | set_location_assignment PIN_J15 -to rstn_i 85 | set_location_assignment PIN_C3 -to uart0_txd_o 86 | set_location_assignment PIN_A3 -to uart0_rxd_i 87 | 88 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top 89 | 90 | # Commit assignments 91 | export_assignments 92 | } 93 | -------------------------------------------------------------------------------- /quartus/de10-nano-test-setup/.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | incremental_db 3 | output_files 4 | *.qpf 5 | *.qsf 6 | *.qws -------------------------------------------------------------------------------- /quartus/de10-nano-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Terasic DE10-Nano FPGA Board 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the 4 | NEORV32 processor on the Terasic DE10-Nano board. 5 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) 6 | top entity, which is a wrapper for the actual processor 7 | top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs). 8 | 9 | * FPGA Board: :books: [Terasic DE10-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=1046) 10 | * FPGA: Intel Cyclone-V `5CSEBA6U23I7` 11 | * Toolchain: Intel Quartus Lite (tested with Quartus Prime Lite 22.1.2) 12 | 13 | 14 | ### NEORV32 Configuration 15 | 16 | :information_source: See the top entity 17 | [`\neorv32-setups\quartus\de10-nano-test-setup\neorv32_test_setup_bootloader.vhd`](/neorv32-setups/quartus/de10-nano-test-setup/neorv32_test_setup_bootloader.vhd) 18 | for configuration and entity details and `create_project.tcl` for the according FPGA pin mapping. 19 | 20 | * CPU: `rv32imc_Zicsr` 21 | * Memory: 22 | * 16kB instruction memory (internal IMEM) 23 | * 8kB data memory (internal DMEM) 24 | * bootloader ROM 25 | * Peripherals: 26 | * `GPIO` 27 | * `CLINT` 28 | * `UART0` 29 | * Tested with version `1.10.8.8` 30 | * Clock: 50MHz from on-board oscillator 31 | * Reset: via on-board button "KEY0" 32 | * GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0") 33 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header 34 | * `uart0_txd_o:` output, connected to FPGA pin `Y15` - header pin `GPIO 0` (pin number "40") 35 | * `uart0_rxd_i:` input, connected to FPGA pin `AA11` - header pin `GPIO 1` (pin number "1") 36 | 37 | 38 | ### FPGA Utilization 39 | 40 | ``` 41 | Logic utilization (in ALMs) 1,335 / 41,910 ( 3 % ) 42 | Total registers 1694 43 | Total pins 12 / 314 ( 4 % ) 44 | Total virtual pins 0 45 | Total block memory bits 231,424 / 5,662,720 ( 4 % ) 46 | Total DSP Blocks 0 / 112 ( 0 % ) 47 | ``` 48 | 49 | ## How To Run 50 | 51 | The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project. 52 | If not already available, this script will create a `work` folder in this directory. 53 | 54 | 1. start Quartus (in GUI mode) 55 | 2. in the menu line click "View/Utility Windows/Tcl console" to open the Tcl console 56 | 3. use the console to naviagte to **this** folder: `cd ..\neorv32-setups\quartus\de10-nano-test-setup` 57 | 4. execute `source create_project.tcl` - this will create and open the actual Quartus project in this folder 58 | 5. copy paste the neorv32_test_setup_bootloader.vhd in this folder and change the frequency to 50 MHz 59 | 6. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream 60 | 7. When the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA 61 | 8. Use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration: 62 | 19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline) 63 | 9. now you can communicate with the bootloader console and upload a new program. 64 | Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) 65 | and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources. 66 | 67 | -------------------------------------------------------------------------------- /quartus/de10-nano-test-setup/constraints/neorv32_test_setup_bootloader.sdc: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | #-- Quartus timing constraint file for uart_spw <> Terrasic DE10 nano Cyclone 5 design 3 | #-- rev. 1.0 : 2021 Provoost Kris 4 | #------------------------------------------------------------------------------ 5 | 6 | # clock definitions 7 | create_clock -name clk_i -period 20 [get_ports clk_i] 8 | 9 | # set false paths from user I/O 10 | set_false_path -from [get_ports { rstn_i } ] -to [get_registers *] 11 | set_false_path -to [get_ports { gpio_o[*] } ] 12 | 13 | # general directives for PLL usage 14 | derive_pll_clocks 15 | derive_clock_uncertainty 16 | -------------------------------------------------------------------------------- /quartus/de10-nano-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | # make a local copy of original "./../../rtl/test_setups/neorv32_test_setup_bootloader.vhd " file 2 | # and modify the default clock frequency: set to 50MHz 3 | #set shell_script "cp -f ./../../../rtl/test_setups/neorv32_test_setup_bootloader.vhd . && sed -i 's/100000000/50000000/g' neorv32_test_setup_bootloader.vhd " 4 | #exec sh -c $shell_script 5 | 6 | 7 | # Load Quartus Prime Tcl Project package 8 | package require ::quartus::project 9 | 10 | set need_to_close_project 0 11 | set make_assignments 1 12 | 13 | # Check that the right project is open 14 | if {[is_project_open]} { 15 | if {[string compare $quartus(project) "de10-nano-test-setup"]} { 16 | puts "Project de10-nano-test-setup is not open" 17 | set make_assignments 0 18 | } 19 | } else { 20 | # Only open if not already open 21 | if {[project_exists de10-nano-test-setup]} { 22 | project_open -revision de10-nano-test-setup de10-nano-test-setup 23 | } else { 24 | project_new -revision de10-nano-test-setup de10-nano-test-setup 25 | } 26 | set need_to_close_project 1 27 | } 28 | 29 | # Make assignments 30 | if {$make_assignments} { 31 | 32 | set_global_assignment -name FAMILY "Cyclone V" 33 | set_global_assignment -name DEVICE 5CSEBA6U23I7 34 | set_global_assignment -name TOP_LEVEL_ENTITY neorv32_test_setup_bootloader 35 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.10 36 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:18:14 OCTOBER 31, 2021" 37 | set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition" 38 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 39 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 40 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 41 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 42 | 43 | # core VHDL files 44 | set core_src_dir [glob ./../../NEORV32/rtl/core/*.vhd] 45 | foreach core_src_file $core_src_dir { 46 | set_global_assignment -name VHDL_FILE $core_src_file -library neorv32 47 | } 48 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_dmem.default.vhd -library neorv32 49 | set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_imem.default.vhd -library neorv32 50 | 51 | # top entity: use local modified copy of the original test setup 52 | set_global_assignment -name VHDL_FILE "neorv32_test_setup_bootloader.vhd" 53 | 54 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 55 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 56 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 57 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 58 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 59 | 60 | set_location_assignment PIN_V11 -to clk_i 61 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk_i 62 | 63 | set_location_assignment PIN_AH17 -to rstn_i 64 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to rstn_i 65 | 66 | set_location_assignment PIN_W15 -to gpio_o[7] 67 | set_location_assignment PIN_AA24 -to gpio_o[6] 68 | set_location_assignment PIN_V16 -to gpio_o[5] 69 | set_location_assignment PIN_V15 -to gpio_o[4] 70 | set_location_assignment PIN_AF26 -to gpio_o[3] 71 | set_location_assignment PIN_AE26 -to gpio_o[2] 72 | set_location_assignment PIN_Y16 -to gpio_o[1] 73 | set_location_assignment PIN_AA23 -to gpio_o[0] 74 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[7] 75 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[6] 76 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[5] 77 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[4] 78 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[3] 79 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[2] 80 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[1] 81 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[0] 82 | 83 | set_location_assignment PIN_AA11 -to uart0_rxd_i 84 | set_location_assignment PIN_Y15 -to uart0_txd_o 85 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart0_rxd_i 86 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart0_txd_o 87 | 88 | 89 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top 90 | 91 | # Commit assignments 92 | export_assignments 93 | } 94 | -------------------------------------------------------------------------------- /quartus/de10-nano-test-setup/neorv32_test_setup_bootloader.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 - Test Setup Using The UART-Bootloader To Upload And Run Executables -- 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 | 15 | library neorv32; 16 | use neorv32.neorv32_package.all; 17 | 18 | entity neorv32_test_setup_bootloader is 19 | generic ( 20 | -- adapt these for your setup -- 21 | CLOCK_FREQUENCY : natural := 50_000_000; -- 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 | -- UART0 -- 32 | uart0_txd_o : out std_ulogic; -- UART0 send data 33 | uart0_rxd_i : in std_ulogic -- UART0 receive data 34 | ); 35 | end entity; 36 | 37 | architecture neorv32_test_setup_bootloader_rtl of neorv32_test_setup_bootloader is 38 | 39 | signal con_gpio_out : std_ulogic_vector(63 downto 0); 40 | 41 | begin 42 | 43 | -- The Core Of The Problem ---------------------------------------------------------------- 44 | -- ------------------------------------------------------------------------------------------- 45 | neorv32_top_inst: neorv32_top 46 | generic map ( 47 | -- Clocking -- 48 | CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz 49 | -- Boot Configuration -- 50 | BOOT_MODE_SELECT => 0, -- boot via internal bootloader 51 | -- RISC-V CPU Extensions -- 52 | RISCV_ISA_C => true, -- implement compressed extension? 53 | RISCV_ISA_M => true, -- implement mul/div extension? 54 | RISCV_ISA_Zicntr => true, -- implement base counters? 55 | -- Internal Instruction memory -- 56 | IMEM_EN => true, -- implement processor-internal instruction memory 57 | IMEM_SIZE => IMEM_SIZE, -- size of processor-internal instruction memory in bytes 58 | -- Internal Data memory -- 59 | DMEM_EN => true, -- implement processor-internal data memory 60 | DMEM_SIZE => DMEM_SIZE, -- size of processor-internal data memory in bytes 61 | -- Processor peripherals -- 62 | IO_GPIO_NUM => 8, -- number of GPIO input/output pairs (0..64) 63 | IO_CLINT_EN => true, -- implement core local interruptor (CLINT)? 64 | IO_UART0_EN => true -- implement primary universal asynchronous receiver/transmitter (UART0)? 65 | ) 66 | port map ( 67 | -- Global control -- 68 | clk_i => clk_i, -- global clock, rising edge 69 | rstn_i => rstn_i, -- global reset, low-active, async 70 | -- GPIO (available if IO_GPIO_NUM > 0) -- 71 | gpio_o => con_gpio_out, -- parallel output 72 | -- primary UART0 (available if IO_UART0_EN = true) -- 73 | uart0_txd_o => uart0_txd_o, -- UART0 send data 74 | uart0_rxd_i => uart0_rxd_i -- UART0 receive data 75 | ); 76 | 77 | -- GPIO output -- 78 | gpio_o <= con_gpio_out(7 downto 0); 79 | 80 | 81 | end architecture; 82 | -------------------------------------------------------------------------------- /quartus/neorv32_qsys_component/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Platform Designer Component 2 | 3 | This folder contains a Qsys/Platform Designer wrapper for the NEORV32 together with 4 | an Wishbone to AvalonMM bridge. This makes the NEORV32 a drop-in replacement for the 5 | Altera/Intel Nios II soft CPU. 6 | 7 | This is just a quick template showing a possible solution, and not a feature complete 8 | solution. All parameters in the Generic section could be added to the GUI. 9 | 10 | Only some peripherals (UART0, UART1 and GPIO) are connected, but other peripheral 11 | could easily be connected. 12 | 13 | ## Solution overview 14 | 15 | The solution is made up of 3 files. One VHDL file for the component implementation 16 | (neorv32_qsys.vhd), one file for the Qsys component (neorv32_qsys_hw.tcl) and one file 17 | listing files to include (neorv32_qsys.qip) to simplify the Quartus setup (.qsf) file. 18 | The figure below shows how the component is implemented. 19 | 20 | ![NEORV32 Qsys Component Solution](figures/overview.png) 21 | 22 | ## GUI Settings 23 | 24 | The Qsys component is created so that some parameters can be set in the Platform Design 25 | GUI. More settings could be added as needed. 26 | 27 | ![NEORV32 GUI Settings](figures/gui_settings.png) 28 | 29 | ## Implementation notes 30 | 31 | The Platform Designer has a bug (feature?) that makes boolean parameters from the Platform 32 | Designer GUI being port mapped to the VHDL component generic as 0/1 instead of true/false. 33 | This is a known bug/feature. 34 | 35 | A workaround for this is made by making the generic (boolean) parameters in the VHDL 36 | as "integer", and then use a "integer2bool" function to make the parameter boolean 37 | again to fit the NEORV32 top. 38 | 39 | ## How to use 40 | 41 | To use the Qsys component in your Platform Designer design, you will just need to 42 | make a "User_Components.ipx" file in your Qsys folder, and reference this (rtl/system_integration/neorv32_qsys_component) folder. 43 | 44 | Example "User_Components.ipx" content: 45 | ``` 46 | 47 | 48 | 49 | ``` 50 | 51 | You will also need to add 3 lines in your Quartus project file (QSF-file) in order to 52 | get the correct source files. 53 | 54 | Example QSF-file info: 55 | ``` 56 | ...... 57 | set_global_assignment -name QIP_FILE ../neorv32_qsys_component/neorv32_qsys.qip 58 | set_global_assignment -name VHDL_FILE ../../../rtl/core/neorv32_application_image.vhd 59 | set_global_assignment -name VHDL_FILE ../../../rtl/core/neorv32_bootloader_image.vhd 60 | ...... 61 | ``` 62 | 63 | Having seperate links for the bootloader and application images makes it easy to include images 64 | from your own project folders. 65 | 66 | # NEORV32 Platform Designer Component - Example Design 67 | 68 | The branch contains an example design using the Qsys/Platform designer component 69 | and running on the DE0 Nano board. 70 | 71 | The example design can be found here [setups/quartus/de0-nano-test-setup-qsys`](../de0-nano-test-setup-qsys) 72 | 73 | The example design will run the software examples. 74 | -------------------------------------------------------------------------------- /quartus/neorv32_qsys_component/figures/gui_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32-setups/dcba8bb6089eacb39273255627121e25e7beea8b/quartus/neorv32_qsys_component/figures/gui_settings.png -------------------------------------------------------------------------------- /quartus/neorv32_qsys_component/figures/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stnolting/neorv32-setups/dcba8bb6089eacb39273255627121e25e7beea8b/quartus/neorv32_qsys_component/figures/overview.png -------------------------------------------------------------------------------- /quartus/neorv32_qsys_component/neorv32_qsys.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_package.vhd"] -library neorv32 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_boot_rom.vhd"] -library neorv32 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_busswitch.vhd"] -library neorv32 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_bus_keeper.vhd"] -library neorv32 5 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cfs.vhd"] -library neorv32 6 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu.vhd"] -library neorv32 7 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_alu.vhd"] -library neorv32 8 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_bus.vhd"] -library neorv32 9 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_control.vhd"] -library neorv32 10 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_cp_fpu.vhd"] -library neorv32 11 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_cp_muldiv.vhd"] -library neorv32 12 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_decompressor.vhd"] -library neorv32 13 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_regfile.vhd"] -library neorv32 14 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_debug_dm.vhd"] -library neorv32 15 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_debug_dtm.vhd"] -library neorv32 16 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_gpio.vhd"] -library neorv32 17 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_icache.vhd"] -library neorv32 18 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_mtime.vhd"] -library neorv32 19 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_nco.vhd"] -library neorv32 20 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_neoled.vhd"] -library neorv32 21 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_package.vhd"] -library neorv32 22 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_pwm.vhd"] -library neorv32 23 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_spi.vhd"] -library neorv32 24 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_sysinfo.vhd"] -library neorv32 25 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_top.vhd"] -library neorv32 26 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_trng.vhd"] -library neorv32 27 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_twi.vhd"] -library neorv32 28 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_uart.vhd"] -library neorv32 29 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_wdt.vhd"] -library neorv32 30 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_wishbone.vhd"] -library neorv32 31 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_fifo.vhd"] -library neorv32 32 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "../../NEORV32/rtl/core/neorv32_cpu_cp_shifter.vhd"] -library neorv32 33 | 34 | -------------------------------------------------------------------------------- /quartus/on-chip-debugger-intel/.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | incremental_db 3 | output_files 4 | *.qpf 5 | *.qsf 6 | *.qws 7 | -------------------------------------------------------------------------------- /quartus/on-chip-debugger-intel/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for using Intel FPGA integrated JTAG as On-Chip Debugger 2 | 3 | This setup provides a way to use the FPGAs own JTAG connection as on chip debugger with OpenOCD & GDB. 4 | Instead of requiring additional four I/O pins to implement a custom JTAG TAP, the JTAG connection used 5 | to program the FPGA itself can be used within the user design. The basic principle of operation is based 6 | on the excellent blog of [tomverbeure](https://tomverbeure.github.io/2021/10/30/Intel-JTAG-Primitive.html). 7 | 8 | Please refer to the blog post for an in-depth explanation of the topic. But basically Intel FPGAs allows the user to use two special ir addresses (10 bit) for their own purpose. USR0 at `0x00c` 9 | and USR1 at `0x00e`. For those (and only those) addresses a user can supply the `tdo` signals that then are 10 | outputted from the FPGA. OpenOCD as debugger can be configured to use those addresses instead of the default RISC-V ones with following commands: 11 | 12 | ```tcl 13 | riscv set_ir dtmcs 0x00c 14 | riscv set_ir dmi 0x00e 15 | ``` 16 | 17 | The top entity is a modified version of [`neorv32_test_setup_on_chip_debugger.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_on_chip_debugger.vhd) 18 | that uses Intel specific entities to get access to the FPGAs own JTAG TAP. An additional modified `dtm` implementation replaces the default `neorv32_debug_dtm` entity, listens for the Intel specific ir addresses and acts as usual translator for DMI access to the core. 19 | 20 | * FPGA Board: :books: [Gecko4Education Cyclone-IV E FPGA Board](https://gecko-wiki.ti.bfh.ch/gecko4education:start) 21 | * FPGA: Intel Cyclone-IV E `EP4CE15F23C8` 22 | * Toolchain: Intel Quartus Prime (tested with Quartus Prime 21.1 - Lite Edition) 23 | 24 | 25 | ### NEORV32 Configuration 26 | 27 | :information_source: See the original top entity [`neorv32_test_setup_on_chip_debugger.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_on_chip_debugger.vhd) for 28 | configuration and entity details. 29 | 30 | :warning: The Gecko board is used in university at Bern and you propably won't have access to one. As such the pin mapping is different and needs to be changed in `create_project.tcl` to your according FPGA pin mapping. 31 | 32 | * CPU: `rv32imcu_Zicsr` + On-Chip Debugger 33 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 34 | * Peripherals: `GPIO`, `MTIME` 35 | * Tested with version [`1.8.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 36 | * Clock: 50MHz from on-board oscillator 37 | * Reset: via on-board button next to seven segment displays 38 | * GPIO output port `gpio_o` (8-bit) connected to the upper-most LED-matrix row 39 | 40 | 41 | ### FPGA Utilization 42 | 43 | ``` 44 | Total logic elements 3,791 / 15,408 ( 25 % ) 45 | Total registers 1,750 / 17,056 ( 11 % ) 46 | Total LABs 278 / 963 ( 29 % ) 47 | Virtual pins 0 48 | I/O pins 10 / 344 ( 3 % ) 49 | M9Ks 30 / 56 ( 54 % ) 50 | Total block memory bits 231,424 / 516,096 ( 45 % ) 51 | Total block memory implementation bits 276,480 / 516,096 ( 54 % ) 52 | Embedded Multiplier 9-bit elements 0 / 112 ( 0 % ) 53 | PLLs 0 / 4 ( 0 % ) 54 | JTAGs 1 / 1 ( 100 % ) 55 | CRC blocks 0 / 1 ( 0 % ) 56 | ASMI blocks 0 / 1 ( 0 % ) 57 | Oscillator blocks 0 / 1 ( 0 % ) 58 | Impedance control blocks 0 / 4 ( 0 % ) 59 | Average interconnect usage (total/H/V) 10.0% / 9.4% / 10.7% 60 | Peak interconnect usage (total/H/V) 39.7% / 37.3% / 43.1% 61 | ``` 62 | 63 | 64 | ## How To Run 65 | 66 | The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project. 67 | 68 | 1. run `quartus_sh -t create_project.tcl` once to generate the Quartus project 69 | 2. start Quartus (in GUI mode) and open the `neorv32_on_chip_debugger_intel.qpf` file 70 | 3. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream 71 | 4. when the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA 72 | 5. open a debug connection with OpenOCD with the command `openocd -f openocd_neorv32_intel.cfg` 73 | 6. upload a program or debug existing one as described in section "Debugging with GDB" of the :page_facing_up: [NEORV32 User Guide](https://stnolting.github.io/neorv32/ug/#_debugging_with_gdb) 74 | -------------------------------------------------------------------------------- /quartus/on-chip-debugger-intel/compile_project.tcl: -------------------------------------------------------------------------------- 1 | # Load Quartus II Tcl project package 2 | package require ::quartus::project 3 | 4 | project_open "neorv32_on_chip_debugger_intel" 5 | 6 | # Run compile design flow 7 | load_package flow 8 | execute_flow -compile 9 | 10 | project_close 11 | -------------------------------------------------------------------------------- /quartus/on-chip-debugger-intel/create_project.tcl: -------------------------------------------------------------------------------- 1 | # Load Quartus II Tcl project package 2 | package require ::quartus::project 3 | 4 | # Create project 5 | project_new "neorv32_on_chip_debugger_intel" -overwrite 6 | 7 | # Assign family, device, and top-level entity 8 | set_global_assignment -name FAMILY "Cyclone IV E" 9 | set_global_assignment -name DEVICE EP4CE15F23C8 10 | set_global_assignment -name TOP_LEVEL_ENTITY neorv32_on_chip_debugger_intel 11 | 12 | # Default settings 13 | set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" 14 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 15 | set_global_assignment -name NUM_PARALLEL_PROCESSORS [expr {[get_environment_info -num_logical_processors] / 2}] 16 | 17 | # search for all core VHDL files 18 | set core_src_files [glob ./../../neorv32/rtl/core/*.vhd] 19 | 20 | # filter out the default platform agnostic DTM so that we can replace it later 21 | set core_src_files [lsearch -inline -all -not $core_src_files *neorv32_debug_dtm.vhd] 22 | 23 | # add all VHDL source file to the neorv32 library 24 | foreach core_src_file $core_src_files { 25 | set_global_assignment -name VHDL_FILE $core_src_file -library neorv32 26 | } 27 | 28 | # add Intel specific DTM implementation, replaces default one 29 | set_global_assignment -name VHDL_FILE ./neorv32_debug_dtm.intel.vhd -library neorv32 30 | 31 | # Toplevel 32 | set_global_assignment -name VHDL_FILE ./neorv32_on_chip_debugger_intel_top.vhd 33 | 34 | # Pin assignments. (Source: https://gecko-wiki.ti.bfh.ch/gecko4education:start) 35 | set_location_assignment PIN_T1 -to clk_i 36 | set_location_assignment PIN_AB11 -to rstn_i 37 | set_location_assignment PIN_K17 -to gpio_o[7] 38 | set_location_assignment PIN_J18 -to gpio_o[6] 39 | set_location_assignment PIN_K18 -to gpio_o[5] 40 | set_location_assignment PIN_F19 -to gpio_o[4] 41 | set_location_assignment PIN_J15 -to gpio_o[3] 42 | set_location_assignment PIN_K15 -to gpio_o[2] 43 | set_location_assignment PIN_L16 -to gpio_o[1] 44 | set_location_assignment PIN_L15 -to gpio_o[0] 45 | 46 | # Close project 47 | export_assignments 48 | project_close 49 | -------------------------------------------------------------------------------- /quartus/on-chip-debugger-intel/openocd_neorv32_intel.cfg: -------------------------------------------------------------------------------- 1 | # use Altera Blaster cable as (slow) JTAG connection 2 | source [find interface/altera-usb-blaster.cfg] 3 | 4 | 5 | # Intel (Altera) Cyclone IV E FPGA 6 | if { [info exists CHIPNAME] } { 7 | set _CHIPNAME $CHIPNAME 8 | } else { 9 | set _CHIPNAME cycloneive 10 | } 11 | 12 | 13 | # Subsidiary TAP: fpga (tap) 14 | # EP4CE15F23C8 has id 0x020f20dd 15 | jtag newtap $_CHIPNAME tap -irlen 10 -expected-id 0x020f20dd 16 | 17 | 18 | # NEOrv32 https://github.com/stnolting/neorv32 19 | if { [info exists CPUNAME] } { 20 | set _CPUNAME $CPUNAME 21 | } else { 22 | set _CPUNAME neorv32 23 | } 24 | 25 | set _TARGETNAME $_CHIPNAME.$_CPUNAME 26 | 27 | 28 | # NEOrv32 target 29 | target create $_TARGETNAME riscv -chain-position $_CHIPNAME.tap 30 | 31 | # We use the Intel JTAG atom that only exposes USR0 & USR1, remap registers. 32 | # riscv set_ir idcode 0x09 inacessible, handled by fpga tap 33 | riscv set_ir dtmcs 0x00c 34 | riscv set_ir dmi 0x00e 35 | 36 | # Access memory via program buffer 37 | # riscv set_mem_access progbuf <-- openocd does not know this command? 38 | 39 | # Scratch pad RAM 40 | # work area ("scratch pad RAM"): beginning of (internal) DMEM, 256 bytes, requires(!) backup 41 | $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 256 -work-area-backup 1 42 | 43 | # Expose NEORV32-specific CSRs 44 | riscv expose_csrs 4032 45 | 46 | 47 | # Start session 48 | init 49 | halt 50 | 51 | echo "Target HALTED." 52 | echo "Ready for remote connections." 53 | -------------------------------------------------------------------------------- /quartus/terasic-cyclone-V-gx-starter-kit-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Terasic Cyclone-V GX Starter Kit FPGA Board 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Terasic Cyclone-V GX Starter Kit board. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor 5 | top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs). 6 | 7 | * FPGA Board: :books: [Terasic Cyclone-V GX Starter Kit FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=830) 8 | * FPGA: Intel Cyclone-V GX `5CGXFC5C6F27C7N` 9 | * Toolchain: Intel Quartus Prime (tested with Quartus Prime 20.1.0 - Lite Edition) 10 | 11 | 12 | ### NEORV32 Configuration 13 | 14 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 15 | configuration and entity details and `create_project.tcl` for the according FPGA pin mapping. 16 | 17 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors, 40-bit wide) 18 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 19 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 20 | * Tested with version [`1.5.9.4`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 21 | * Clock: 50MHz from on-board oscillator 22 | * Reset: via on-board button "KEY0" 23 | * GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0") 24 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board provided USB to UART converter 25 | 26 | :warning: The default [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity 27 | is configured for a 100MHz input clock. Since the on-board clock generator of the Cyclone-V GX Starter Kit board needs I2C to be programmed, the fixed 50MHz clock on bank 5B, pin R20 is used for this test setup, and the test setup has to be modified accordingly. 28 | This is automatically done by the `create_project.tcl` TCL script, which makes a local copy of the original test setup VHDL file 29 | (in *this* folder) and uses `sed` to configure the `CLOCK_FREQUENCY` generic (in the local copy) for 50MHz. The local copy is then used as actual 30 | top entity. 31 | 32 | ### FPGA Utilization 33 | 34 | ``` 35 | Logic utilization (in ALMs) 1,442 / 29,080 ( 5 % ) 36 | Total registers 1771 37 | Total pins 12 / 364 ( 3 % ) 38 | Total virtual pins 0 39 | Total block memory bits 231,424 / 4,567,040 ( 5 % ) 40 | Total DSP Blocks 0 / 150 ( 0 % ) 41 | Total HSSI RX PCSs 0 / 6 ( 0 % ) 42 | Total HSSI PMA RX Deserializers 0 / 6 ( 0 % ) 43 | Total HSSI TX PCSs 0 / 6 ( 0 % ) 44 | Total HSSI PMA TX Serializers 0 / 6 ( 0 % ) 45 | Total PLLs 0 / 12 ( 0 % ) 46 | Total DLLs 0 / 4 ( 0 % ) 47 | ``` 48 | 49 | 50 | ## How To Run 51 | 52 | The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project. 53 | If not already available, this script will create a `work` folder in this directory. 54 | 55 | 1. start Quartus (in GUI mode) 56 | 2. in the menu line click "View/Utility Windows/Tcl console" to open the Tcl console 57 | 3. use the console to navigate to **this** folder: `cd .../setups/quartus/terasic-cyclone-V-gx-starter-kit-test-setup` 58 | 4. execute `source create_project.tcl` - this will create and open the actual Quartus project in this folder. Do NOT run the Quartus-supplied tcl setup script, as that will change all assignment names. 59 | 5. if a "select family" prompt appears, go to the "Board" tab, select the "Cyclone V GX Starter Kit" board and click OK 60 | 6. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream 61 | 7. when the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA 62 | 8. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration: 63 | 19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline) 64 | 9. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) 65 | and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources. 66 | -------------------------------------------------------------------------------- /quartus/terasic-cyclone-V-gx-starter-kit-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | # make a local copy of original "./../../rtl/test_setups/neorv32_test_setup_bootloader.vhd " file 2 | # and modify the default clock frequency: set to 50MHz 3 | set shell_script "cp -f ./../../NEORV32/rtl/test_setups/neorv32_test_setup_bootloader.vhd . && sed -i 's/100000000/50000000/g' neorv32_test_setup_bootloader.vhd " 4 | exec sh -c $shell_script 5 | 6 | # Copyright (C) 2020 Intel Corporation. All rights reserved. 7 | # Your use of Intel Corporation's design tools, logic functions 8 | # and other software and tools, and any partner logic 9 | # functions, and any output files from any of the foregoing 10 | # (including device programming or simulation files), and any 11 | # associated documentation or information are expressly subject 12 | # to the terms and conditions of the Intel Program License 13 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 14 | # the Intel FPGA IP License Agreement, or other applicable license 15 | # agreement, including, without limitation, that your use is for 16 | # the sole purpose of programming logic devices manufactured by 17 | # Intel and sold by Intel or its authorized distributors. Please 18 | # refer to the applicable agreement for further details, at 19 | # https://fpgasoftware.intel.com/eula. 20 | 21 | # Quartus Prime: Generate Tcl File for Project 22 | # File: terasic-cyclone-V-gx=starter-kit_test.tcl 23 | # Generated on: Sat Apr 10 16:57:48 2021 24 | 25 | # Load Quartus Prime Tcl Project package 26 | package require ::quartus::project 27 | 28 | set need_to_close_project 0 29 | set make_assignments 1 30 | 31 | # Check that the right project is open 32 | if {[is_project_open]} { 33 | if {[string compare $quartus(project) "terasic-cyclone-V-gx-starter-kit-test-setup"]} { 34 | puts "Project terasic-cyclone-V-gx-starter-kit-test-setup is not open" 35 | set make_assignments 0 36 | } 37 | } else { 38 | # Only open if not already open 39 | if {[project_exists de0-nano-test-setup]} { 40 | project_open -revision terasic-cyclone-V-gx-starter-kit-setup terasic-cyclone-V-gx-starter-kit-test-setup 41 | } else { 42 | project_new -revision terasic-cyclone-V-gx-starter-kit-test-setup terasic-cyclone-V-gx-starter-kit-test-setup 43 | } 44 | set need_to_close_project 1 45 | } 46 | 47 | # Make assignments 48 | if {$make_assignments} { 49 | set_global_assignment -name FAMILY "Cyclone V" 50 | set_global_assignment -name DEVICE 5CGXFC5C6F27C7 51 | set_global_assignment -name TOP_LEVEL_ENTITY neorv32_test_setup_bootloader 52 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0 53 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "TUE JUN 4 20:41:15 2013" 54 | set_global_assignment -name LAST_QUARTUS_VERSION "20.1.1 Lite Edition" 55 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 56 | set_global_assignment -name BOARD "Cyclone V GX Starter Kit" 57 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 58 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 59 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 60 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 61 | 62 | # core VHDL files 63 | set core_src_dir [glob ./../../NEORV32/rtl/core/*.vhd] 64 | foreach core_src_file $core_src_dir { 65 | set_global_assignment -name VHDL_FILE $core_src_file -library neorv32 66 | } 67 | 68 | # top entity: use local modified copy of the original test setup 69 | set_global_assignment -name VHDL_FILE "neorv32_test_setup_bootloader.vhd" 70 | 71 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 72 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 73 | 74 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 75 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 76 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 77 | 78 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk_i 79 | set_instance_assignment -name IO_STANDARD "1.2 V" -to rstn_i 80 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[0] 81 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[1] 82 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[2] 83 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[3] 84 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[4] 85 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[5] 86 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[6] 87 | set_instance_assignment -name IO_STANDARD "2.5 V" -to gpio_o[7] 88 | set_instance_assignment -name IO_STANDARD "2.5 V" -to uart0_rxd_i 89 | set_instance_assignment -name IO_STANDARD "2.5 V" -to uart0_txd_o 90 | 91 | set_location_assignment PIN_R20 -to clk_i 92 | set_location_assignment PIN_P11 -to rstn_i 93 | set_location_assignment PIN_L7 -to gpio_o[0] 94 | set_location_assignment PIN_K6 -to gpio_o[1] 95 | set_location_assignment PIN_D8 -to gpio_o[2] 96 | set_location_assignment PIN_E9 -to gpio_o[3] 97 | set_location_assignment PIN_A5 -to gpio_o[4] 98 | set_location_assignment PIN_B6 -to gpio_o[5] 99 | set_location_assignment PIN_H8 -to gpio_o[6] 100 | set_location_assignment PIN_H9 -to gpio_o[7] 101 | set_location_assignment PIN_M9 -to uart0_rxd_i 102 | set_location_assignment PIN_L9 -to uart0_txd_o 103 | 104 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top 105 | 106 | # Commit assignments 107 | export_assignments 108 | } 109 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | !.gitignore 4 | !README.md 5 | 6 | !source/ 7 | source/* 8 | !source/impl_1.xcf 9 | 10 | !*.vhd 11 | !*.rdf 12 | !*.pdc 13 | !*.bin 14 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Example Setup for the tinyVision.ai Inc. "UPduino v3.0" FPGA Board 2 | 3 | > [!WARNING] 4 | > This setup **requires** Lattice Radiant version **2022.1**! 5 | 6 | This example setup turns the UPduino v3.0 board, which features a Lattice iCE40 UltraPlus FPGA, into a tiny-scale NEORV32 microcontroller. 7 | The processor setup provides 64kB of data and instruction memory, an RTOS-capable CPU (privileged architecture) 8 | and a set of standard peripherals like UART, TWI and SPI. 9 | 10 | * FPGA Board: :books: [tinyVision.ai Inc. UPduino v3 FPGA Board (GitHub)](https://github.com/tinyvision-ai-inc/UPduino-v3.0/), 11 | :credit_card: buy on [Tindie](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/) 12 | * FPGA: Lattice iCE40 UltraPlus 5k `iCE40UP5K-SG48I` 13 | * Toolchain: Lattice Radiant (tested with version 2022.1), using **Synplify Pro** synthesis engine 14 | * Top entity: `neorv32_upduino_v3_top.vhd` 15 | 16 | 17 | ### Processor Configuration 18 | 19 | * CPU: `rv32imcu_Zicsr_Zicntr` 20 | * Memory: 64kB instruction memory (internal IMEM), 64kB data memory (internal DMEM), 4kB bootloader ROM 21 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `SPI`, `TWI`, `PWM`, `WDT` 22 | * Clock: 24 MHz from on-chip HF oscillator 23 | * Reset: indirect reset via FPGA re-reconfiguration pin (`creset_n`) 24 | * Tested with processor version [`1.9.4.10`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 25 | * On-board FPGA bitstream flash storage can also be used to store/load NEORV32 application software (via the bootloader) 26 | 27 | 28 | ### Interface Signals 29 | 30 | :information_source: See [`neorv32_upduino_v3.pdc`](https://github.com/stnolting/neorv32/blob/master/boards/UPduino_v3/neorv32_upduino_v3.pdc) 31 | for the FPGA pin mapping. 32 | 33 | | Top Entity Signal | FPGA Pin | Package Pin | Board Header Pin | 34 | |:------------------------------|:----------:|:------------:|:-----------------| 35 | | `flash_csn_o` (spi_cs[0]) | IOB_35B | 16 | J3-1 | 36 | | `flash_sck_o` | IOB_34A | 15 | J3-2 | 37 | | `flash_sdo_o` | IOB_32A | 14 | J3-3 | 38 | | `flash_sdi_i` | IOB_33B | 17 | J3-4 | 39 | | `gpio_i(0)` | IOB_3B_G6 | 44 | J3-9 | 40 | | `gpio_i(1)` | IOB_8A | 4 | J3-10 | 41 | | `gpio_i(2)` | IOB_9B | 3 | J3-11 | 42 | | `gpio_i(3)` | IOB_4A | 48 | J3-12 | 43 | | `gpio_o(0)` (status LED) | IOB_5B | 45 | J3-13 | 44 | | `gpio_o(1)` | IOB_2A | 47 | J3-14 | 45 | | `gpio_o(2)` | IOB_0A | 46 | J3-15 | 46 | | `gpio_o(3)` | IOB_6A | 2 | J3-16 | 47 | | - | - | - | - | 48 | | **reconfigure FPGA** ("_reset_") | CRESET | 8 | J2-3 | 49 | | `pwm_o(0)` | `gpio_i(0)` (red)| RGB2 | 41 | J2-5 | 50 | | `pwm_o(1)` (green) | RGB0 | 39 | J2-6 | 51 | | `pwm_o(2)` (blue) | RGB1 | 40 | J2-7 | 52 | | `twi_sda_io` | IOT_42B | 31 | J2-9 | 53 | | `twi_scl_io` | IOT_45A_G1 | 37 | J2-10 | 54 | | `spi_sdo_o` | IOT_44B | 34 | J2-11 | 55 | | `spi_sck_o` | IOT_49A | 43 | J2-12 | 56 | | `spi_csn_o` (spi_cs[1]) | IOT_48B | 36 | J2-13 | 57 | | `spi_sdi_i` | IOT_51A | 42 | J2-14 | 58 | | `uart_txd_o` (UART0) | IOT_50B | 38 | J2-15 | 59 | | `uart_rxd_i` (UART0) | IOT_41A | 28 | J2-16 | 60 | 61 | :information_source: The TWI signals (`twi_sda_io` and `twi_scl_io`) and the reset input (`rstn_i`) require an external pull-up resistor. 62 | GPIO output 0 (`gpio_o(0)`, also connected to the RGB drive) is used as output for a high-active **status LED** driven by the bootloader. 63 | 64 | 65 | ### FPGA Setup 66 | 67 | 1. start Lattice Radiant (in GUI mode) 68 | 2. click on "open project" and select `neorv32_upduino_v3.rdf` from this folder 69 | 3. click the :arrow_forward: button to synthesize, map, place and route the design and to generate a programming file 70 | 4. when done open the programmer (for example via "Tools" -> "Programmer"); you will need a programmer configuration, which will be created in the next steps; alternatively, 71 | you can use the pre-build configuration `source/impl_1.xcf` 72 | 5. in the programmer double click on the field under "Operation" (_fast configuration_ should be the default) and select "External SPI Memory" as "Target Memory" 73 | 6. select "SPI Serial Flash" under "SPI Flash Options / Family" 74 | 7. select "WinBond" under "SPI Flash Options / Vendor" 75 | 8. select "W25Q32" under "SPI Flash Options / Device" 76 | 9. close the dialog by clicking "ok" 77 | 10. click on "Program Device" 78 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/neorv32_dmem.ice40up_spram.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Data Memory (DMEM) -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- Memory has a physical size of 64kb (2 x SPRAMs). -- 5 | -- Logical size DMEM_SIZE must be less or equal. -- 6 | -- -------------------------------------------------------------------------------- -- 7 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 8 | -- Copyright (c) NEORV32 contributors. -- 9 | -- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. -- 10 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 11 | -- SPDX-License-Identifier: BSD-3-Clause -- 12 | -- ================================================================================ -- 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.numeric_std.all; 17 | 18 | library neorv32; 19 | use neorv32.neorv32_package.all; 20 | 21 | library iCE40UP; 22 | use iCE40UP.components.all; -- for device primitives 23 | 24 | entity neorv32_dmem is 25 | generic ( 26 | DMEM_SIZE : natural -- processor-internal instruction memory size in bytes, has to be a power of 2 27 | ); 28 | port ( 29 | clk_i : in std_ulogic; -- global clock line 30 | rstn_i : in std_ulogic; -- async reset, low-active 31 | bus_req_i : in bus_req_t; -- bus request 32 | bus_rsp_o : out bus_rsp_t -- bus response 33 | ); 34 | end neorv32_dmem; 35 | 36 | architecture neorv32_dmem_rtl of neorv32_dmem is 37 | 38 | -- advanced configuration -------------------------------------------------------------------------------- 39 | constant spram_sleep_mode_en_c : boolean := false; -- put DMEM into sleep mode when idle (for low power) 40 | -- ------------------------------------------------------------------------------------------------------- 41 | 42 | -- IO space: module base address -- 43 | constant hi_abb_c : natural := 31; -- high address boundary bit 44 | constant lo_abb_c : natural := index_size_f(64*1024); -- low address boundary bit 45 | 46 | -- local signals -- 47 | signal mem_cs : std_ulogic; 48 | signal rdata : std_ulogic_vector(31 downto 0); 49 | signal rden : std_ulogic; 50 | 51 | -- SPRAM signals -- 52 | signal spram_clk : std_logic; 53 | signal spram_addr : std_logic_vector(13 downto 0); 54 | signal spram_di_lo : std_logic_vector(15 downto 0); 55 | signal spram_di_hi : std_logic_vector(15 downto 0); 56 | signal spram_do_lo : std_logic_vector(15 downto 0); 57 | signal spram_do_hi : std_logic_vector(15 downto 0); 58 | signal spram_be_lo : std_logic_vector(03 downto 0); 59 | signal spram_be_hi : std_logic_vector(03 downto 0); 60 | signal spram_we : std_logic; 61 | signal spram_pwr_n : std_logic; 62 | signal spram_cs : std_logic; 63 | 64 | begin 65 | 66 | -- Sanity Checks -------------------------------------------------------------------------- 67 | -- ------------------------------------------------------------------------------------------- 68 | assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using iCE40up SPRAM-based DMEM." severity note; 69 | assert not (DMEM_SIZE > 64*1024) report "NEORV32 PROCESSOR CONFIG ERROR: DMEM has a fixed physical size of 64kB. Logical size must be less or equal." severity error; 70 | 71 | 72 | -- Access Control ------------------------------------------------------------------------- 73 | -- ------------------------------------------------------------------------------------------- 74 | mem_cs <= bus_req_i.stb; 75 | 76 | 77 | -- Memory Access -------------------------------------------------------------------------- 78 | -- ------------------------------------------------------------------------------------------- 79 | dmem_spram_lo_inst : SP256K 80 | port map ( 81 | AD => spram_addr, -- I 82 | DI => spram_di_lo, -- I 83 | MASKWE => spram_be_lo, -- I 84 | WE => spram_we, -- I 85 | CS => spram_cs, -- I 86 | CK => spram_clk, -- I 87 | STDBY => '0', -- I 88 | SLEEP => spram_pwr_n, -- I 89 | PWROFF_N => '1', -- I 90 | DO => spram_do_lo -- O 91 | ); 92 | 93 | dmem_spram_hi_inst : SP256K 94 | port map ( 95 | AD => spram_addr, -- I 96 | DI => spram_di_hi, -- I 97 | MASKWE => spram_be_hi, -- I 98 | WE => spram_we, -- I 99 | CS => spram_cs, -- I 100 | CK => spram_clk, -- I 101 | STDBY => '0', -- I 102 | SLEEP => spram_pwr_n, -- I 103 | PWROFF_N => '1', -- I 104 | DO => spram_do_hi -- O 105 | ); 106 | 107 | -- access logic and signal type conversion -- 108 | spram_clk <= std_logic(clk_i); 109 | spram_addr <= std_logic_vector(bus_req_i.addr(13+2 downto 0+2)); 110 | spram_di_lo <= std_logic_vector(bus_req_i.data(15 downto 00)); 111 | spram_di_hi <= std_logic_vector(bus_req_i.data(31 downto 16)); 112 | spram_we <= '1' when (bus_req_i.rw = '1') else '0'; -- global write enable 113 | spram_cs <= std_logic(mem_cs); 114 | spram_be_lo <= std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(0)) & std_logic(bus_req_i.ben(0)); -- low byte write enable 115 | spram_be_hi <= std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(2)) & std_logic(bus_req_i.ben(2)); -- high byte write enable 116 | spram_pwr_n <= '0' when ((spram_sleep_mode_en_c = false) or (mem_cs = '1')) else '1'; -- LP mode disabled or IMEM selected 117 | rdata <= std_ulogic_vector(spram_do_hi) & std_ulogic_vector(spram_do_lo); 118 | 119 | buffer_ff: process(clk_i) 120 | begin 121 | if rising_edge(clk_i) then 122 | bus_rsp_o.ack <= mem_cs; 123 | rden <= bus_req_i.stb and (not bus_req_i.rw); 124 | end if; 125 | end process buffer_ff; 126 | 127 | -- no access error possible -- 128 | bus_rsp_o.err <= '0'; 129 | 130 | -- output gate -- 131 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); 132 | 133 | 134 | end neorv32_dmem_rtl; 135 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/neorv32_imem.ice40up_spram.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Instruction Memory (IMEM) -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- Memory has a physical size of 64kb (2 x SPRAMs). -- 5 | -- Logical size IMEM_SIZE must be less or equal. -- 6 | -- -------------------------------------------------------------------------------- -- 7 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 8 | -- Copyright (c) NEORV32 contributors. -- 9 | -- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. -- 10 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 11 | -- SPDX-License-Identifier: BSD-3-Clause -- 12 | -- ================================================================================ -- 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.numeric_std.all; 17 | 18 | library neorv32; 19 | use neorv32.neorv32_package.all; 20 | 21 | library iCE40UP; 22 | use iCE40UP.components.all; -- for device primitives 23 | 24 | entity neorv32_imem is 25 | generic ( 26 | IMEM_SIZE : natural; -- processor-internal instruction memory size in bytes, has to be a power of 2 27 | IMEM_AS_IROM : boolean -- implement IMEM as pre-initialized read-only memory? 28 | ); 29 | port ( 30 | clk_i : in std_ulogic; -- global clock line 31 | rstn_i : in std_ulogic; -- async reset, low-active 32 | bus_req_i : in bus_req_t; -- bus request 33 | bus_rsp_o : out bus_rsp_t -- bus response 34 | ); 35 | end neorv32_imem; 36 | 37 | architecture neorv32_imem_rtl of neorv32_imem is 38 | 39 | -- advanced configuration -------------------------------------------------------------------------------- 40 | constant spram_sleep_mode_en_c : boolean := false; -- put IMEM into sleep mode when idle (for low power) 41 | -- ------------------------------------------------------------------------------------------------------- 42 | 43 | -- IO space: module base address -- 44 | constant hi_abb_c : natural := 31; -- high address boundary bit 45 | constant lo_abb_c : natural := index_size_f(64*1024); -- low address boundary bit 46 | 47 | -- local signals -- 48 | signal mem_cs : std_ulogic; 49 | signal rdata : std_ulogic_vector(31 downto 0); 50 | signal rden : std_ulogic; 51 | 52 | -- SPRAM signals -- 53 | signal spram_clk : std_logic; 54 | signal spram_addr : std_logic_vector(13 downto 0); 55 | signal spram_di_lo : std_logic_vector(15 downto 0); 56 | signal spram_di_hi : std_logic_vector(15 downto 0); 57 | signal spram_do_lo : std_logic_vector(15 downto 0); 58 | signal spram_do_hi : std_logic_vector(15 downto 0); 59 | signal spram_be_lo : std_logic_vector(03 downto 0); 60 | signal spram_be_hi : std_logic_vector(03 downto 0); 61 | signal spram_we : std_logic; 62 | signal spram_pwr_n : std_logic; 63 | signal spram_cs : std_logic; 64 | 65 | begin 66 | 67 | -- Sanity Checks -------------------------------------------------------------------------- 68 | -- ------------------------------------------------------------------------------------------- 69 | assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using iCE40up SPRAM-based IMEM." severity note; 70 | assert not (IMEM_AS_IROM = true) report "NEORV32 PROCESSOR CONFIG ERROR: ICE40 Ultra Plus SPRAM cannot be initialized by bitstream!" severity failure; 71 | assert not (IMEM_SIZE > 64*1024) report "NEORV32 PROCESSOR CONFIG ERROR: IMEM has a fixed physical size of 64kB. Logical size must be less or equal." severity error; 72 | 73 | 74 | -- Access Control ------------------------------------------------------------------------- 75 | -- ------------------------------------------------------------------------------------------- 76 | mem_cs <= bus_req_i.stb; 77 | 78 | 79 | -- Memory Access -------------------------------------------------------------------------- 80 | -- ------------------------------------------------------------------------------------------- 81 | imem_spram_lo_inst : SP256K 82 | port map ( 83 | AD => spram_addr, -- I 84 | DI => spram_di_lo, -- I 85 | MASKWE => spram_be_lo, -- I 86 | WE => spram_we, -- I 87 | CS => spram_cs, -- I 88 | CK => spram_clk, -- I 89 | STDBY => '0', -- I 90 | SLEEP => spram_pwr_n, -- I 91 | PWROFF_N => '1', -- I 92 | DO => spram_do_lo -- O 93 | ); 94 | 95 | imem_spram_hi_inst : SP256K 96 | port map ( 97 | AD => spram_addr, -- I 98 | DI => spram_di_hi, -- I 99 | MASKWE => spram_be_hi, -- I 100 | WE => spram_we, -- I 101 | CS => spram_cs, -- I 102 | CK => spram_clk, -- I 103 | STDBY => '0', -- I 104 | SLEEP => spram_pwr_n, -- I 105 | PWROFF_N => '1', -- I 106 | DO => spram_do_hi -- O 107 | ); 108 | 109 | -- access logic and signal type conversion -- 110 | spram_clk <= std_logic(clk_i); 111 | spram_addr <= std_logic_vector(bus_req_i.addr(13+2 downto 0+2)); 112 | spram_di_lo <= std_logic_vector(bus_req_i.data(15 downto 00)); 113 | spram_di_hi <= std_logic_vector(bus_req_i.data(31 downto 16)); 114 | spram_we <= '1' when (bus_req_i.rw = '1') else '0'; -- global write enable 115 | spram_cs <= std_logic(mem_cs); 116 | spram_be_lo <= std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(0)) & std_logic(bus_req_i.ben(0)); -- low byte write enable 117 | spram_be_hi <= std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(2)) & std_logic(bus_req_i.ben(2)); -- high byte write enable 118 | spram_pwr_n <= '0' when ((spram_sleep_mode_en_c = false) or (mem_cs = '1')) else '1'; -- LP mode disabled or IMEM selected 119 | rdata <= std_ulogic_vector(spram_do_hi) & std_ulogic_vector(spram_do_lo); 120 | 121 | buffer_ff: process(clk_i) 122 | begin 123 | if rising_edge(clk_i) then 124 | bus_rsp_o.ack <= mem_cs; 125 | rden <= bus_req_i.stb and (not bus_req_i.rw); 126 | end if; 127 | end process buffer_ff; 128 | 129 | -- no access error possible -- 130 | bus_rsp_o.err <= '0'; 131 | 132 | -- output gate -- 133 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); 134 | 135 | 136 | end neorv32_imem_rtl; 137 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/neorv32_upduino_v3.pdc: -------------------------------------------------------------------------------- 1 | # Radiant pin mapping for the "tinyvision.ai Inc. UPduino v3" FPGA board 2 | 3 | ## Clock (on-chip hf oscillator) 4 | #create_clock -period 41.666666 -name hf_osc_clk [get_nets hf_osc_clk] 5 | 6 | ## UART (uart0) 7 | ldc_set_location -site {38} [get_ports uart_txd_o] 8 | ldc_set_location -site {28} [get_ports uart_rxd_i] 9 | 10 | ## SPI - on-board flash 11 | ldc_set_location -site {14} [get_ports flash_sdo_o] 12 | ldc_set_location -site {15} [get_ports flash_sck_o] 13 | ldc_set_location -site {16} [get_ports flash_csn_o] 14 | ldc_set_location -site {17} [get_ports flash_sdi_i] 15 | 16 | ## SPI - user port 17 | ldc_set_location -site {34} [get_ports spi_sdo_o] 18 | ldc_set_location -site {43} [get_ports spi_sck_o] 19 | ldc_set_location -site {36} [get_ports spi_csn_o] 20 | ldc_set_location -site {42} [get_ports spi_sdi_i] 21 | 22 | ## TWI 23 | ldc_set_location -site {31} [get_ports twi_sda_io] 24 | ldc_set_location -site {37} [get_ports twi_scl_io] 25 | 26 | ## GPIO - input 27 | ldc_set_location -site {44} [get_ports {gpio_i[0]}] 28 | ldc_set_location -site {4} [get_ports {gpio_i[1]}] 29 | ldc_set_location -site {3} [get_ports {gpio_i[2]}] 30 | ldc_set_location -site {48} [get_ports {gpio_i[3]}] 31 | 32 | ## GPIO - output 33 | ldc_set_location -site {45} [get_ports {gpio_o[0]}] 34 | ldc_set_location -site {47} [get_ports {gpio_o[1]}] 35 | ldc_set_location -site {46} [get_ports {gpio_o[2]}] 36 | ldc_set_location -site {2} [get_ports {gpio_o[3]}] 37 | 38 | ## RGB power LED 39 | ldc_set_location -site {39} [get_ports {pwm_o[0]}] 40 | ldc_set_location -site {40} [get_ports {pwm_o[1]}] 41 | ldc_set_location -site {41} [get_ports {pwm_o[2]}] 42 | -------------------------------------------------------------------------------- /radiant/UPduino_v3/source/impl_1.xcf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SPI 7 | 8 | 9 | 1 10 | Lattice 11 | iCE40 UltraPlus 12 | iCE40UP5K 13 | All 14 | 15 | 8 16 | 11111111 17 | 1 18 | 0 19 | 20 | ../../impl_1/neorv32_upduino_v3_impl_1.bin 21 | 02/11/24 09:39:36 22 | External SPI Flash Memory (SPI FLASH) 23 | Erase,Program,Verify 24 | 29 | 30 | 31 | 32 | 1 33 | Lattice 34 | iCE40 UltraPlus 35 | iCE40UP5K 36 | 0x11200639 37 | All 38 | iCE40UP5K 39 | 40 | 8 41 | 11111111 42 | 1 43 | 0 44 | 45 | Compressed Random Access Memory (CRAM) 46 | Bypass 47 | 54 | 55 | 56 | 57 | 58 | 1 59 | WinBond 60 | SPI Serial Flash 61 | W25Q32 62 | 0x15 63 | 8-pin SOIC 64 | Erase,Program,Verify 65 | ../../impl_1/neorv32_upduino_v3_impl_1.bin 66 | 0x00000000 67 | 0x003F0000 68 | 32 69 | 104156 70 | 1 71 | 72 | 73 | 74 | 75 | 76 | 1 77 | 78 | N:/Projects/neorv32/boards/UPduino_v3/impl_1/neorv32_upduino_v3_impl_1.bin 79 | 80 | 83 | 84 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | SEQUENTIAL 95 | ENTIRED CHAIN 96 | No Override 97 | TLR 98 | TLR 99 | 100 | 101 | 1 102 | 103 | 104 | USB2 105 | FTUSB-0 106 | Single RS232-HS Location 0000 Serial 107 | 108 | 109 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/.gitignore: -------------------------------------------------------------------------------- 1 | # ignore ALL 2 | /* 3 | 4 | # keep project sources/configuration 5 | !*.vhd 6 | !*.rdf 7 | !*.pdc 8 | !*.bin 9 | !*.sty 10 | 11 | # keep pr0ject description 12 | !.gitignore 13 | !README.md 14 | 15 | # keep PLL IP 16 | !system_pll/ 17 | system_pll/* 18 | !system_pll/system_pll.ipx 19 | !system_pll/rtl/ 20 | system_pll/rtl/* 21 | !system_pll/rtl/system_pll.v 22 | 23 | # keep programmer file 24 | !source/ 25 | source/* 26 | !source/impl_1.xcf 27 | 28 | # keep precompiled bitstream 29 | !impl_1/ 30 | impl_1/* 31 | !impl_1/iCEBreaker_impl_1.bin 32 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Example Setup for the iCEBreaker FPGA Board 2 | 3 | > [!WARNING] 4 | > This setup **requires** Lattice Radiant version **2022.1**! 5 | 6 | ### General 7 | 8 | * FPGA board: https://github.com/icebreaker-fpga/icebreaker 9 | * FPGA: Lattice iCE40 UltraPlus 5k `iCE40UP5K-SG48I` 10 | * Toolchain: Lattice Radiant (version 2022.1) using **Synplify Pro** as synthesis engine 11 | * Top entity: `icebreaker_top.vhd` 12 | * Radiant project file: `iCEBreaker.rdf` 13 | * Radiant programmer configuration: `source/impl_1.xcf` 14 | * Implementation strategy file: `iCEBreaker1.sty` (just to enable VHDL08 support) 15 | * Pre-compiled bitstream: `impl_1/iCEBreaker_impl_1.bin` 16 | 17 | ### NEORV32 18 | 19 | * CPU: `rv32imau_Zicsr_Zicntr_Zifencei` 20 | * Memory: 64kB instruction memory (internal IMEM, instantiating 2x SRAM primitives), 64kB data memory (internal DMEM, instantiating 2x SRAM primitives), 4kB bootloader ROM (inferring blockRAM) 21 | * make sure to update/override the linker script configurations accordingly to utilizes the full memory capacity 22 | * Peripherals: `GPIO`, `MTIME`, `UART0` + FIFOs, `SPI` 23 | * Clock: 24 MHz from PLL, driven by 12 MHz on-chip HF oscillator 24 | * Reset: from PLL's "lock" signal, PLL is reset by the on-board user-button 25 | * Tested with processor version [`1.9.4.10`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 26 | 27 | ### IO 28 | 29 | * On-board LEDs (2x, low-active) 30 | * On-board reset button 31 | * On board UART-USB serial bridge 32 | * On-board SPIFPGA bitstream flash storage can also be used to store/load NEORV32 application software (using the processor's default bootloader) 33 | 34 | See pin-mapping constraints file `icebreaker.pdc`. 35 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/icebreaker.pdc: -------------------------------------------------------------------------------- 1 | # Radiant pin mapping for iCEBreaker FPGA Board 2 | 3 | ## UART (uart0) - on-board USB-serial bridge 4 | ldc_set_location -site {9} [get_ports uart_txd_o] 5 | ldc_set_location -site {6} [get_ports uart_rxd_i] 6 | 7 | ## SPI - on-board flash 8 | ldc_set_location -site {14} [get_ports flash_sdo_o] 9 | ldc_set_location -site {15} [get_ports flash_sck_o] 10 | ldc_set_location -site {16} [get_ports flash_csn_o] 11 | ldc_set_location -site {17} [get_ports flash_sdi_i] 12 | 13 | ## GPIO - on-board low-active LEDs 14 | ldc_set_location -site {37} [get_ports led_gr_o] 15 | ldc_set_location -site {11} [get_ports led_rd_o] 16 | 17 | ## RESET - on-board low-active button 18 | ldc_set_location -site {10} [get_ports button_i] 19 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/neorv32_dmem.ice40up_spram.vhd: -------------------------------------------------------------------------------- 1 | -- ================================================================================ -- 2 | -- NEORV32 SoC - Processor-Internal Data Memory (DMEM) -- 3 | -- -------------------------------------------------------------------------------- -- 4 | -- Memory has a physical size of 64kb (2 x SPRAMs). -- 5 | -- Logical size DMEM_SIZE must be less or equal. -- 6 | -- -------------------------------------------------------------------------------- -- 7 | -- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 -- 8 | -- Copyright (c) NEORV32 contributors. -- 9 | -- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. -- 10 | -- Licensed under the BSD-3-Clause license, see LICENSE for details. -- 11 | -- SPDX-License-Identifier: BSD-3-Clause -- 12 | -- ================================================================================ -- 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.numeric_std.all; 17 | 18 | library neorv32; 19 | use neorv32.neorv32_package.all; 20 | 21 | library iCE40UP; 22 | use iCE40UP.components.all; -- for device primitives 23 | 24 | entity neorv32_dmem is 25 | generic ( 26 | DMEM_SIZE : natural -- processor-internal instruction memory size in bytes, has to be a power of 2 27 | ); 28 | port ( 29 | clk_i : in std_ulogic; -- global clock line 30 | rstn_i : in std_ulogic; -- async reset, low-active 31 | bus_req_i : in bus_req_t; -- bus request 32 | bus_rsp_o : out bus_rsp_t -- bus response 33 | ); 34 | end neorv32_dmem; 35 | 36 | architecture neorv32_dmem_rtl of neorv32_dmem is 37 | 38 | -- advanced configuration -------------------------------------------------------------------------------- 39 | constant spram_sleep_mode_en_c : boolean := false; -- put DMEM into sleep mode when idle (for low power) 40 | -- ------------------------------------------------------------------------------------------------------- 41 | 42 | -- IO space: module base address -- 43 | constant hi_abb_c : natural := 31; -- high address boundary bit 44 | constant lo_abb_c : natural := index_size_f(64*1024); -- low address boundary bit 45 | 46 | -- local signals -- 47 | signal mem_cs : std_ulogic; 48 | signal rdata : std_ulogic_vector(31 downto 0); 49 | signal rden : std_ulogic; 50 | 51 | -- SPRAM signals -- 52 | signal spram_clk : std_logic; 53 | signal spram_addr : std_logic_vector(13 downto 0); 54 | signal spram_di_lo : std_logic_vector(15 downto 0); 55 | signal spram_di_hi : std_logic_vector(15 downto 0); 56 | signal spram_do_lo : std_logic_vector(15 downto 0); 57 | signal spram_do_hi : std_logic_vector(15 downto 0); 58 | signal spram_be_lo : std_logic_vector(03 downto 0); 59 | signal spram_be_hi : std_logic_vector(03 downto 0); 60 | signal spram_we : std_logic; 61 | signal spram_pwr_n : std_logic; 62 | signal spram_cs : std_logic; 63 | 64 | begin 65 | 66 | -- Sanity Checks -------------------------------------------------------------------------- 67 | -- ------------------------------------------------------------------------------------------- 68 | assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using iCE40up SPRAM-based DMEM." severity note; 69 | assert not (DMEM_SIZE > 64*1024) report "NEORV32 PROCESSOR CONFIG ERROR: DMEM has a fixed physical size of 64kB. Logical size must be less or equal." severity error; 70 | 71 | 72 | -- Access Control ------------------------------------------------------------------------- 73 | -- ------------------------------------------------------------------------------------------- 74 | mem_cs <= bus_req_i.stb; 75 | 76 | 77 | -- Memory Access -------------------------------------------------------------------------- 78 | -- ------------------------------------------------------------------------------------------- 79 | dmem_spram_lo_inst : SP256K 80 | port map ( 81 | AD => spram_addr, -- I 82 | DI => spram_di_lo, -- I 83 | MASKWE => spram_be_lo, -- I 84 | WE => spram_we, -- I 85 | CS => spram_cs, -- I 86 | CK => spram_clk, -- I 87 | STDBY => '0', -- I 88 | SLEEP => spram_pwr_n, -- I 89 | PWROFF_N => '1', -- I 90 | DO => spram_do_lo -- O 91 | ); 92 | 93 | dmem_spram_hi_inst : SP256K 94 | port map ( 95 | AD => spram_addr, -- I 96 | DI => spram_di_hi, -- I 97 | MASKWE => spram_be_hi, -- I 98 | WE => spram_we, -- I 99 | CS => spram_cs, -- I 100 | CK => spram_clk, -- I 101 | STDBY => '0', -- I 102 | SLEEP => spram_pwr_n, -- I 103 | PWROFF_N => '1', -- I 104 | DO => spram_do_hi -- O 105 | ); 106 | 107 | -- access logic and signal type conversion -- 108 | spram_clk <= std_logic(clk_i); 109 | spram_addr <= std_logic_vector(bus_req_i.addr(13+2 downto 0+2)); 110 | spram_di_lo <= std_logic_vector(bus_req_i.data(15 downto 00)); 111 | spram_di_hi <= std_logic_vector(bus_req_i.data(31 downto 16)); 112 | spram_we <= '1' when (bus_req_i.rw = '1') else '0'; -- global write enable 113 | spram_cs <= std_logic(mem_cs); 114 | spram_be_lo <= std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(1)) & std_logic(bus_req_i.ben(0)) & std_logic(bus_req_i.ben(0)); -- low byte write enable 115 | spram_be_hi <= std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(3)) & std_logic(bus_req_i.ben(2)) & std_logic(bus_req_i.ben(2)); -- high byte write enable 116 | spram_pwr_n <= '0' when ((spram_sleep_mode_en_c = false) or (mem_cs = '1')) else '1'; -- LP mode disabled or IMEM selected 117 | rdata <= std_ulogic_vector(spram_do_hi) & std_ulogic_vector(spram_do_lo); 118 | 119 | buffer_ff: process(clk_i) 120 | begin 121 | if rising_edge(clk_i) then 122 | bus_rsp_o.ack <= mem_cs; 123 | rden <= bus_req_i.stb and (not bus_req_i.rw); 124 | end if; 125 | end process buffer_ff; 126 | 127 | -- no access error possible -- 128 | bus_rsp_o.err <= '0'; 129 | 130 | -- output gate -- 131 | bus_rsp_o.data <= rdata when (rden = '1') else (others => '0'); 132 | 133 | 134 | end neorv32_dmem_rtl; 135 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/source/impl_1.xcf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SPI 7 | 8 | 9 | 1 10 | Lattice 11 | iCE40 UltraPlus 12 | iCE40UP5K 13 | All 14 | 15 | 8 16 | 11111111 17 | 1 18 | 0 19 | 20 | ../../impl_1/iCEBreaker_impl_1.bin 21 | 02/10/24 19:41:19 22 | 0xB101 23 | External SPI Flash Memory (SPI FLASH) 24 | Erase,Program,Verify 25 | 30 | 31 | 32 | 33 | 1 34 | Lattice 35 | iCE40 UltraPlus 36 | iCE40UP5K 37 | 0x11200639 38 | All 39 | iCE40UP5K 40 | 41 | 8 42 | 11111111 43 | 1 44 | 0 45 | 46 | Compressed Random Access Memory (CRAM) 47 | Bypass 48 | 54 | 55 | 56 | 57 | 58 | 1 59 | WinBond 60 | SPI Serial Flash 61 | W25Q128JV 62 | 0x17 63 | 8-pin SOIC 64 | Erase,Program,Verify 65 | ../../impl_1/iCEBreaker_impl_1.bin 66 | 0x00000000 67 | 0x00FF0000 68 | 128 69 | 104156 70 | 1 71 | 72 | 73 | 74 | 75 | 76 | 1 77 | 78 | N:/Projects/neorv32-setups/radiant/iCEBreaker/impl_1/iCEBreaker_impl_1.bin 79 | 80 | 83 | 84 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | SEQUENTIAL 95 | ENTIRED CHAIN 96 | No Override 97 | TLR 98 | TLR 99 | 100 | 101 | 1 102 | 103 | 104 | USB2 105 | FTUSB-0 106 | iCEBreaker V1.0d A Location 0000 Serial ibT0gbT8A 107 | 108 | 109 | -------------------------------------------------------------------------------- /radiant/iCEBreaker/system_pll/system_pll.ipx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /vivado/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Xilinx Vivado Example Setups 2 | 3 | ## How To Run 4 | 5 | The `create_project.tcl` TCL script in the board subdirectories can be used for creating a complete Vivado project and for running the implementation. 6 | If not already available, this script will create a `work` folder in those subdirectories. 7 | 8 | Note that you may need to install support for your particular development board through "XHub Stores" menu item within Vivado prior to sourcing the `create_project.tcl` script. 9 | 10 | ### Batch mode 11 | 12 | Execute `vivado -mode batch -nojournal -nolog -source create_project.tcl` from the board subdir. 13 | The project will be created and implementation will be run until generation of `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`. 14 | 15 | ### GUI 16 | 17 | 1. start Vivado (in GUI mode) 18 | 2. click on "TCL Console" at the bottom 19 | 3. use the console to navigation to the boards folder. For example: `cd somewhere/neorv32-setups/vivado/arty-a7-test-setup` 20 | 4. execute `source create_project.tcl` - this will create the actual Vivado project in `work` 21 | 5. when the Vivado project has opened, Implementation will run and a bitstream will be generated - if the process is not started automatically, click "run" 22 | to "run synthesis", "run implementation" and "generate bitstream" steps 23 | 24 | ### Programming the Bitstream 25 | 26 | 1. open the "Hardware Manager" (maybe a prompt will ask for that) 27 | 2. click on "Open target/Auto Connect" 28 | 3. click on "Program device" and select `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`; click "Program" 29 | 4. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration: 30 | 19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline) 31 | 5. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) 32 | and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources. 33 | -------------------------------------------------------------------------------- /vivado/arty-a7-test-setup/.gitignore: -------------------------------------------------------------------------------- 1 | /vivado* 2 | /.Xil 3 | /work/* 4 | -------------------------------------------------------------------------------- /vivado/arty-a7-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Digilent Arty A7-35 FPGA Board 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Digilent Arty A7-35 board. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor 5 | top entity that provides a minimalistic interface (clock, reset, UART and 4 LEDs). 6 | 7 | * FPGA Board: :books: [Digilent Arty A7-35 FPGA Board](https://reference.digilentinc.com/reference/programmable-logic/arty-a7/reference-manual) 8 | * FPGA: Xilinx Artix-7 `XC7A35TICSG324-1L` 9 | * Toolchain: Xilinx Vivado (tested with Vivado 2019.2) 10 | 11 | 12 | ## NEORV32 Configuration 13 | 14 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 15 | configuration and entity details and [`arty_a7_35_test_setup.xdc`](https://github.com/stnolting/neorv32/blob/master/boards/arty-a7-35-test-setup/arty_a7_35_test_setup.xdc) 16 | for the according FPGA pin mapping. 17 | 18 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors) 19 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 20 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 21 | * Tested with version [`1.5.3.3`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 22 | * Clock: 100MHz from on-board oscillator 23 | * Reset: Via dedicated on-board "RESET" button 24 | * GPIO output port `gpio_o` 25 | * bits 0..3 are connected to the green on-board LEDs (LD4 - LD7); LD4 is the bootloader status LED 26 | * bits 4..7 are (not actually used) connected to PMOD `JA` connector pins 1-4 27 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip 28 | 29 | 30 | -------------------------------------------------------------------------------- /vivado/arty-a7-test-setup/arty_a7_test_setup.xdc: -------------------------------------------------------------------------------- 1 | ## This file is a general .xdc for the Arty A7-35 Rev. D 2 | 3 | ## For default neorv32_test_setup.vhd top entity 4 | 5 | ## Clock signal 6 | set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_i }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] 7 | create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { clk_i }]; 8 | 9 | ## LEDs 10 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[0] }]; #IO_L24N_T3_35 Sch=led[4] 11 | set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[1] }]; #IO_25_35 Sch=led[5] 12 | set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[2] }]; #IO_L24P_T3_A01_D17_14 Sch=led[6] 13 | set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7] 14 | 15 | ## Pmod Header JA (unused GPIO outputs) 16 | set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[4] }]; #IO_0_15 Sch=ja[1] 17 | set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[5] }]; #IO_L4P_T0_15 Sch=ja[2] 18 | set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[6] }]; #IO_L4N_T0_15 Sch=ja[3] 19 | set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[7] }]; #IO_L6P_T0_15 Sch=ja[4] 20 | 21 | ## USB-UART Interface 22 | set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart0_txd_o }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out 23 | set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart0_rxd_i }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in 24 | 25 | ## Misc. 26 | set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { rstn_i }]; #IO_L16P_T2_35 Sch=ck_rst 27 | -------------------------------------------------------------------------------- /vivado/arty-a7-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | set board "arty-a7-35" 2 | 3 | # Create and clear output directory 4 | set outputdir work 5 | file mkdir $outputdir 6 | 7 | set files [glob -nocomplain "$outputdir/*"] 8 | if {[llength $files] != 0} { 9 | puts "deleting contents of $outputdir" 10 | file delete -force {*}[glob -directory $outputdir *]; # clear folder contents 11 | } else { 12 | puts "$outputdir is empty" 13 | } 14 | 15 | switch $board { 16 | "arty-a7-35" { 17 | set a7part "xc7a35ticsg324-1L" 18 | set a7prj ${board}-test-setup 19 | } 20 | } 21 | 22 | # Create project 23 | create_project -part $a7part $a7prj $outputdir 24 | 25 | set_property board_part digilentinc.com:${board}:part0:1.0 [current_project] 26 | set_property target_language VHDL [current_project] 27 | 28 | # Define filesets 29 | 30 | ## Core: NEORV32 31 | add_files [glob ./../../neorv32/rtl/core/*.vhd] 32 | set_property library neorv32 [get_files [glob ./../../neorv32/rtl/core/*.vhd]] 33 | 34 | ## Design: processor subsystem template, and (optionally) BoardTop and/or other additional sources 35 | set fileset_design ./../../neorv32/rtl/test_setups/neorv32_test_setup_bootloader.vhd 36 | 37 | ## Constraints 38 | set fileset_constraints [glob ./*.xdc] 39 | 40 | ## Simulation-only sources 41 | set fileset_sim [list ./../../neorv32/sim/neorv32_tb.vhd ./../../neorv32/sim/sim_uart_rx.vhd] 42 | 43 | # Add source files 44 | 45 | ## Design 46 | add_files $fileset_design 47 | 48 | ## Constraints 49 | add_files -fileset constrs_1 $fileset_constraints 50 | 51 | ## Simulation-only 52 | add_files -fileset sim_1 $fileset_sim 53 | 54 | # Run synthesis, implementation and bitstream generation 55 | launch_runs impl_1 -to_step write_bitstream -jobs 4 56 | wait_on_run impl_1 57 | -------------------------------------------------------------------------------- /vivado/nexys-a7-test-setup/.gitignore: -------------------------------------------------------------------------------- 1 | /vivado* 2 | /.Xil 3 | /work/* 4 | -------------------------------------------------------------------------------- /vivado/nexys-a7-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Digilent Nexys A7 and Nexys 4 DDR FPGA Boards 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Digilent Nexys A7 and Nexys 4 DDR boards. 4 | It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor 5 | top entity that provides a minimalistic interface (clock, reset, UART and 4 LEDs). 6 | 7 | * FPGA Boards: 8 | * :books: [Digilent Nexys A7 FPGA Boards](https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/reference-manual) 9 | * :books: [Digilent Nexys 4 DDR FPGA Board](https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/reference-manual) 10 | * FPGAs: 11 | * Xilinx Artix-7 `XC7A50TCSG324-1` 12 | * Xilinx Artix-7 `XC7A100TCSG324-1` 13 | * Toolchain: Xilinx Vivado (tested with Vivado 2020.2) 14 | 15 | 16 | ## NEORV32 Configuration 17 | 18 | :information_source: See the top entity [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 19 | configuration and entity details and [`nexys_a7_test_setup.xdc`](https://github.com/AWenzel83/neorv32/blob/nexys_a7_example/boards/nexys-a7-test-setup/nexys_a7_test_setup.xdc) 20 | for the according FPGA pin mapping. 21 | 22 | * CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors) 23 | * Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM 24 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 25 | * Tested with version [`1.5.3.3`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 26 | * Clock: 100MHz from on-board oscillator 27 | * Reset: Via dedicated on-board "RESET" button 28 | * GPIO output port `gpio_o` bits 0..7 are connected to the green on-board LEDs (LD0 - LD7); LD0 is the bootloader status LED 29 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip 30 | -------------------------------------------------------------------------------- /vivado/nexys-a7-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | set board "A7-50" 2 | 3 | # create and clear output directory 4 | set outputdir work 5 | file mkdir $outputdir 6 | 7 | set files [glob -nocomplain "$outputdir/*"] 8 | if {[llength $files] != 0} { 9 | puts "deleting contents of $outputdir" 10 | file delete -force {*}[glob -directory $outputdir *]; # clear folder contents 11 | } else { 12 | puts "$outputdir is empty" 13 | } 14 | 15 | switch $board { 16 | "A7-50" { 17 | set a7part "xc7a50tcsg324-1" 18 | set a7prj "nexys-a7-50-test-setup" 19 | } 20 | "A7-100" { 21 | set a7part "xc7a100tcsg324-1" 22 | set a7prj "nexys-a7-100-test-setup" 23 | } 24 | } 25 | 26 | # create project 27 | create_project -part $a7part $a7prj $outputdir 28 | 29 | # add source files: core sources 30 | add_files [glob ./../../neorv32/rtl/core/*.vhd] 31 | set_property library neorv32 [get_files [glob ./../../neorv32/rtl/core/*.vhd]] 32 | 33 | # add source file: top entity 34 | add_files [glob ./../../neorv32/rtl/test_setups/neorv32_test_setup_bootloader.vhd] 35 | 36 | # add source files: simulation-only 37 | add_files -fileset sim_1 [list ./../../neorv32/sim/neorv32_tb.vhd ./../../neorv32/sim/sim_uart_rx.vhd] 38 | 39 | # add source files: constraints 40 | add_files -fileset constrs_1 [glob ./*.xdc] 41 | 42 | # run synthesis, implementation and bitstream generation 43 | launch_runs impl_1 -to_step write_bitstream -jobs 4 44 | wait_on_run impl_1 45 | -------------------------------------------------------------------------------- /vivado/nexys-a7-test-setup/nexys_a7_test_setup.xdc: -------------------------------------------------------------------------------- 1 | ## This file is a general .xdc for the Nexys A7 and Nexys 4 DDR 2 | ## For default neorv32_test_setup.vhd top entity 3 | 4 | ## Clock signal 5 | set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_i }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] 6 | create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { clk_i }]; 7 | 8 | ## LEDs 9 | set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[0] }]; #IO_L18P_T2_A24_15 Sch=led[0] 10 | set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1] 11 | set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[2] }]; #IO_L17N_T2_A25_15 Sch=led[2] 12 | set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[3] }]; #IO_L8P_T1_D11_14 Sch=led[3] 13 | set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[4] }]; #IO_L7P_T1_D09_14 Sch=led[4] 14 | set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5] 15 | set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6] 16 | set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7] 17 | 18 | ## USB-UART Interface 19 | set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart0_txd_o }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out 20 | set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart0_rxd_i }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in 21 | 22 | ## Misc. 23 | set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { rstn_i }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ck_rst 24 | -------------------------------------------------------------------------------- /vivado/z7-nano-test-setup/.gitignore: -------------------------------------------------------------------------------- 1 | /vivado* 2 | /.Xil 3 | /work/* 4 | -------------------------------------------------------------------------------- /vivado/z7-nano-test-setup/README.md: -------------------------------------------------------------------------------- 1 | # NEORV32 Test Setup for the Microphase Z7 Nano FPGA Board 2 | 3 | This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Microphase Z7 Nano board. 4 | It uses the simplified 5 | [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) top entity, which is a wrapper for the actual processor 6 | top entity that provides a minimalistic interface (clock, reset, UART and 8 IO's). 7 | 8 | * FPGA Board: :books: [Microphase Z7 Nano FPGA Board](https://github.com/MicroPhase/fpga-docs/blob/master/schematic/Z7-NANO_R21.pdf) 9 | * FPGA: Xilinx ZynQ 7000 `c7z020clg400-2` 10 | * Toolchain: Xilinx Vivado (tested with Vivado 2023.1) 11 | 12 | ### FPGA Utilization 13 | 14 | ``` 15 | Total LUT's 2034 / 53,200 ( 3.82 % ) 16 | Total registers 1400 / 106400 ( 1.32 % ) 17 | Total Block RAM s 8 / 140 ( 5.71 % ) 18 | ``` 19 | 20 | ## NEORV32 Configuration 21 | 22 | :information_source: 23 | See the top entity 24 | [`rtl/test_setups/neorv32_test_setup_bootloader.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd) for 25 | configuration and entity details and oin_constraints.xdc for the according FPGA pin mapping. 26 | 27 | * CPU: `rv32imc_Zicsr` 28 | * Memory: 29 | * 16kB instruction memory (internal IMEM) 30 | * 8kB data memory (internal DMEM) 31 | * bootloader ROM 32 | * Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT` 33 | * Tested with version [`1.10.8.8`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) 34 | * Clock: 50 MHz from on-board oscillator 35 | * Reset: Via dedicated on-board "RESET" button 36 | * GPIO output port `gpio_o` 37 | * bits 0..7 are connected to the expansion header 38 | * UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the expansion header -------------------------------------------------------------------------------- /vivado/z7-nano-test-setup/create_project.tcl: -------------------------------------------------------------------------------- 1 | set board "z7-nano" 2 | 3 | # Create and clear output directory 4 | 5 | set loc_script [file normalize [info script]] 6 | set loc_folder [file dirname $loc_script] 7 | puts $loc_folder 8 | cd $loc_folder 9 | 10 | set outputdir work 11 | file mkdir $outputdir 12 | 13 | set files [glob -nocomplain "$outputdir/*"] 14 | if {[llength $files] != 0} { 15 | puts "deleting contents of $outputdir" 16 | file delete -force {*}[glob -directory $outputdir *]; # clear folder contents 17 | } else { 18 | puts "$outputdir is empty" 19 | } 20 | 21 | switch $board { 22 | "z7-nano" { 23 | set z7part "xc7z020clg400-2" 24 | set z7prj ${board}-test-setup 25 | } 26 | } 27 | 28 | # Create project 29 | create_project -part $z7part $z7prj $outputdir 30 | 31 | set_property target_language VHDL [current_project] 32 | set_property simulator_language VHDL [current_project] 33 | 34 | # Define filesets 35 | 36 | ## Core: NEORV32 37 | add_files [glob ./../../neorv32/rtl/core/*.vhd] 38 | set_property library neorv32 [get_files [glob ./../../neorv32/rtl/core/*.vhd]] 39 | 40 | ## Design: processor subsystem template, and (optionally) BoardTop and/or other additional sources 41 | set fileset_design ./../../neorv32/rtl/test_setups/neorv32_test_setup_bootloader.vhd 42 | 43 | ## Constraints 44 | set fileset_constraints [glob ./*.xdc] 45 | 46 | ## Simulation-only sources 47 | set fileset_sim [list ./../../neorv32/sim/neorv32_tb.vhd ./../../neorv32/sim/sim_uart_rx.vhd] 48 | 49 | # Add source files 50 | 51 | ## Design 52 | add_files $fileset_design 53 | 54 | ## Constraints 55 | add_files -fileset constrs_1 $fileset_constraints 56 | 57 | ## Simulation-only 58 | add_files -fileset sim_1 $fileset_sim 59 | 60 | # Run synthesis, implementation and bitstream generation 61 | launch_runs impl_1 -to_step write_bitstream 62 | wait_on_run impl_1 63 | -------------------------------------------------------------------------------- /vivado/z7-nano-test-setup/pin_constraints.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN N18 [get_ports clk_i] 2 | set_property PACKAGE_PIN P14 [get_ports rstn_i] 3 | 4 | set_property IOSTANDARD LVCMOS33 [get_ports clk_i] 5 | set_property IOSTANDARD LVCMOS33 [get_ports rstn_i] 6 | 7 | 8 | set_property PACKAGE_PIN N17 [get_ports {gpio_o[7]}] 9 | set_property PACKAGE_PIN R16 [get_ports {gpio_o[6]}] 10 | set_property PACKAGE_PIN T17 [get_ports {gpio_o[5]}] 11 | set_property PACKAGE_PIN T16 [get_ports {gpio_o[4]}] 12 | set_property PACKAGE_PIN W18 [get_ports {gpio_o[3]}] 13 | set_property PACKAGE_PIN Y18 [get_ports {gpio_o[2]}] 14 | set_property PACKAGE_PIN Y16 [get_ports {gpio_o[1]}] 15 | set_property PACKAGE_PIN V17 [get_ports {gpio_o[0]}] 16 | 17 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[7]}] 18 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[6]}] 19 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[5]}] 20 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[4]}] 21 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[3]}] 22 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[2]}] 23 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[1]}] 24 | set_property IOSTANDARD LVCMOS33 [get_ports {gpio_o[0]}] 25 | 26 | 27 | set_property PACKAGE_PIN T10 [get_ports uart0_txd_o] 28 | set_property PACKAGE_PIN T11 [get_ports uart0_rxd_i] 29 | 30 | set_property IOSTANDARD LVCMOS33 [get_ports uart0_txd_o] 31 | set_property IOSTANDARD LVCMOS33 [get_ports uart0_rxd_i] 32 | -------------------------------------------------------------------------------- /vivado/z7-nano-test-setup/timings.xdc: -------------------------------------------------------------------------------- 1 | # CLOCKS external 2 | 3 | create_clock -period 20.000 [get_ports clk_i] 4 | 5 | # False paths 6 | 7 | set_false_path -from [get_ports rstn_i] --------------------------------------------------------------------------------