{"id":18352669,"url":"https://github.com/chipsalliance/veerwolf","last_synced_at":"2026-02-19T11:31:17.625Z","repository":{"id":35123253,"uuid":"201076719","full_name":"chipsalliance/VeeRwolf","owner":"chipsalliance","description":"FuseSoC-based SoC for VeeR EH1 and EL2","archived":false,"fork":false,"pushed_at":"2024-12-11T12:39:01.000Z","size":1451,"stargazers_count":334,"open_issues_count":22,"forks_count":74,"subscribers_count":24,"default_branch":"main","last_synced_at":"2026-01-31T14:41:37.410Z","etag":null,"topics":["fusesoc","swerv","tools","veer"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chipsalliance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-07T15:24:36.000Z","updated_at":"2026-01-13T11:20:05.000Z","dependencies_parsed_at":"2023-07-12T23:13:49.131Z","dependency_job_id":"ff877831-1f6f-472a-bd16-19d1e0fda47f","html_url":"https://github.com/chipsalliance/VeeRwolf","commit_stats":null,"previous_names":["chipsalliance/cores-swervolf"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/chipsalliance/VeeRwolf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chipsalliance%2FVeeRwolf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chipsalliance%2FVeeRwolf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chipsalliance%2FVeeRwolf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chipsalliance%2FVeeRwolf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chipsalliance","download_url":"https://codeload.github.com/chipsalliance/VeeRwolf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chipsalliance%2FVeeRwolf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29611063,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T10:52:55.328Z","status":"ssl_error","status_checked_at":"2026-02-19T10:52:26.323Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fusesoc","swerv","tools","veer"],"created_at":"2024-11-05T21:36:47.301Z","updated_at":"2026-02-19T11:31:17.582Z","avatar_url":"https://github.com/chipsalliance.png","language":"Verilog","funding_links":[],"categories":[],"sub_categories":[],"readme":"VeeRwolf\n========\n\nVeeRwolf is a [FuseSoC](https://github.com/olofk/fusesoc)-based reference platform for the VeeR family of RISC-V cores. Currently, [VeeR EH1](https://github.com/chipsalliance/Cores-VeeR-EH1) and [VeeR EL2](https://github.com/chipsalliance/Cores-VeeR-EL2) are supported. See [CPU configuration](#cpu-configuration) to learn how to switch between them.\n\nThis can be used to run the [RISC-V compliance tests](https://github.com/riscv/riscv-compliance), [Zephyr OS](https://www.zephyrproject.org), [TockOS](https://github.com/tock/tock/tree/master/boards/swervolf) or other software in simulators or on FPGA boards. Focus is on portability, extendability and ease of use; to allow VeeR users to quickly get software running, modify the SoC to their needs or port it to new target devices.\n\nThis project was previously called SweRVolf. The last released version using the old name is v0.7.5\n\n# Structure\n\nTo ease portability, the SoC consists of a portable technology-agnostic core with target-specific wrappers. This chapter describes the functionality of the core and the technology-specific targets.\n\n## VeeRwolf Core\n\nThe core of VeeRwolf consists of the VeeR CPU with a boot ROM, AXI4 interconnect, UART, SPI, RISC-V timer and GPIO. The core doesn't include any RAM but instead exposes a memory bus that the target-specific wrapper will connect to an appropriate memory controller. Other external connections are clock, reset, UART, GPIO, SPI and DMI (Debug Module Interface).\n\n![](veerwolf_core.png)\n\n*VeeRwolf Core*\n\n\n### Memory map\n\n| Core     | Address               |\n| -------- | --------------------- |\n| RAM      | 0x00000000-0x07FFFFFF |\n| Boot ROM | 0x80000000-0x80000FFF |\n| syscon   | 0x80001000-0x80001FFF |\n| UART     | 0x80002000-0x80002FFF |\n\n#### RAM\n\nThe VeeRwolf core does not contain a memory controller but allocates the first 128MiB of the address for RAM that can be used by a target application and exposes an AXI bus to the wrapper.\n\n#### Boot ROM\n\nThe boot ROM contains a first-stage bootloader. After system reset, VeeR will start fetching its first instructions from this area.\n\nTo select a bootloader, set the `bootrom_file` parameter. See the [Booting](#booting) chapter for more information about available bootloaders.\n\n#### System controller\n\nThe system controller contains common system functionality such as keeping register with the SoC version information, RAM initialization status and the RISC-V machine timer. Below is the memory map of the system controller\n\n\n| Address  | Register              | Description |\n| -------- | --------------------- | -----------\n| 0x00     | version_patch | VeeRwolf patch version |\n| 0x01     | version_minor | VeeRwolf minor version |\n| 0x02     | version_major |VeeRwolf major version |\n| 0x03     | version_misc | Bit 7 is set when VeeRwolf was built from modified sources |\n|          |              | Bit 6:0 revision since last patch version |\n| 0x04-0x07     | version_sha | SHA hash of the build\n| 0x08     | sim_print | Outputs a character in simulation. No effect on hardware\n| 0x09     | sim_exit | Exits a simulation. No effect on hardware\n| 0x0A     | init_status | Bit 0 = RAM initialization complete. Bit 1 = RAM initialization reported errors\n| 0x0B     | sw_irq                | Software-controlled external interrupts\n| 0x0C-0x0F | nmi_vec | Interrupt vector for NMI |\n| 0x10-0x13 | gpio0 | 32 readable and writable GPIO bits |\n| 0x18-0x1B | gpio1 | 32 readable and writable GPIO bits |\n| 0x20-0x27 | mtime | mtime from RISC-V privilege spec |\n| 0x28-0x2f | mtimecmp |mtimecmp from RISC-V privilege spec |\n| 0x30-0x33 | irq_timer_cnt | IRQ timer counter |\n| 0x34      | irq_timer_ctrl | IRQ timer control |\n| 0x3C-0x3F | clk_freq_hz | Clock frequency of main clock in Hz |\n| 0x40     | SPI_SPCR | Simple SPI Control register |\n| 0x48     | SPI_SPSR | Simple SPI status register |\n| 0x50     | SPI_SPDR | Simple SPI data register |\n| 0x58     | SPI_SPER | Simple SPI extended register |\n| 0x60     | SPI_SPSS | Simple SPI slave select register |\n\n\n##### syscon_base+0x000B sw_irq\n\n![](veerwolf_irq.png)\n\nThis register allows configuration and assertion of IRQ line 3 and 4, for testing the VeeR PIC or having two extra software-controllable interrupt sources. Interrupts can be triggered by writing to the sw_irq*n* bits when the timer bit is set to 0, or by a timeout of the irq_timer, when the timer bit is set to one. If both sw_irq3_timer and sw_irq4_timer are set to 0, the IRQ timer instead asserts an NMI when it reaches 0.\n\nIf sw_irq3_timer or sw_irq4_timer are asserted, the interrupt trigger is connected to\n\n| Bits | Name         | Description |\n| ---- | ------------ | -----------\n|    7 | sw_irq4      | Trigger IRQ line 4\n|    6 | sw_irq4_edge | 0 = IRQ4 is asserted until sw_irq4 is cleared, 1 = Writing to sw_irq4 only asserts IRQ4 for one clock cycle\n|    5 | sw_irq4_pol  | IRQ4 polarity. 0 = Active high, 1 = active low\n|    4 | sw_irq4_timer| 0 = IRQ4 is triggered by sw_irq4, 1 = IRQ4 is triggered by irq_timer timeout\n|    3 | sw_irq3      | Trigger IRQ line 3\n|    2 | sw_irq3_edge | 0 = IRQ3 is asserted until sw_irq3 is cleared, 1 = Writing to sw_irq3 only asserts IRQ3 for one clock cycle\n|    1 | sw_irq3_pol  | IRQ3 polarity. 0 = Active high, 1 = active low\n|    0 | sw_irq3_timer| 0 = IRQ3 is triggered by sw_irq3, 1 = IRQ3 is triggered by irq_timer timeout\n\n##### syscon_base+0x0030 irq_timer_cnt\n\nSet or read the IRQ timer counter value. Granularity is in system clock frequency cycles.\n\n##### syscon_base+0x0034 irq_timer_en\n\nBit 0 enables or disables one-shot IRQ countdown timer. Automatically disables itself when reaching zero\n\n#### UART\n\nVeeRwolf contains a ns16550-compatible UART\n\n## VeeRwolf sim\n\nVeeRwolf sim is a simulation target that wraps the VeeRwolf core in a testbench to be used by verilator or event-driven simulators such as QuestaSim. It can be used for full-system simulations that executes programs running on VeeR. It also supports connecting a debugger through OpenOCD and JTAG VPI. The [Debugging](#debugging) chapter contains more information on how to connect a debugger.\n\n![](veerwolf_sim.png)\n\n*VeeRwolf Simulation target*\n\nThe simulation target exposes a number of parameters for compile-time and run-time configuration. These parameters are all exposed as FuseSoC parameters. The most relevant parameters are:\n\n* `--jtag_vpi_enable` : Enables the JTAG server which OpenOCD can connect to\n* `--ram_init_file` : Loads a Verilog hex file to use as initial on-chip RAM contents\n* `--vcd` : Enable VCD dumping\n\nMemory files suitable for loading with `--ram_init_file` can be created from binary files with the `sw/makehex.py` script\n\n## VeeRwolf Nexys\n\nVeeRwolf Nexys is a version of the VeeRwolf SoC created for the Digilent Nexys A7 board. It uses the on-board 128MB DDR2 for RAM, has GPIO connected to LED, supports booting from SPI Flash and uses the microUSB port for UART and JTAG communication. The default bootloader for the VeeRwolf Nexys target will attempt to load a program stored in SPI Flash by default.\n\n![](veerwolf_nexys.png)\n\n*VeeRwolf Nexys A7 target*\n\n### I/O\n\nThe active on-board I/O consists of a LED, a switch and the microUSB connector for UART, JTAG and power.\n\n#### LEDs\n\n16 LEDs are controlled by memory-mapped GPIO at address 0x80001010-0x80001011\n\n#### Switches\n\n16 Switches are mapped GPIO addresses at 0x80001012-0x80001013\n\nDuring boot up, the two topmost switches (sw14, sw15) control the boot mode.\n\n| sw15 | sw14 | Boot mode                  |\n| ---- | ---- | -------------------------- |\n|  off |  off | Boot from SPI Flash        |\n|  off |   on | Boot from serial           |\n|   on |  off | Boot from address 0 in RAM |\n|   on |   on | Undefined                  |\n\n*Note: Switch 0 has a dual purpose and selects whether to output serial communication from the SoC (0=off) or from the embedded self-test program in the DDR2 controller (1=on).*\n\n#### micro USB\n\nUART and JTAG communication is tunneled through the microUSB port on the board and will appear as `/dev/ttyUSB0`, `/dev/ttyUSB1` or similar depending on OS configuration. A terminal emulator can be used to connect to the UART (e.g. by running `screen /dev/ttyUSB0 115200`) and OpenOCD can connect to the JTAG port to program the FPGA or connect the debug proxy. The [debugging](#debugging) chapter goes into more detail on how to connect a debugger.\n\n#### SPI Flash\n\nAn SPI controller is connected to the on-board SPI Flash. This can be used for storing data such as program to be loaded into memory during boot. The [SPI uImage loader](#spi-uimage-loader) chapter goes into more detail on how to prepare, write and boot a program stored in SPI Flash\n\n## VeeRwolf Basys 3\n\nVeeRwolf Basys 3 is a version of the VeeRwolf SoC created for the Digilent Basys 3 board. It uses 64kB on-chip memory for RAM, has GPIO connected to LEDs and switches, supports booting from SPI Flash and uses the microUSB port for UART and JTAG communication. The default bootloader for the VeeRwolf Basys 3 target will attempt to load a program stored in SPI Flash by default.\n\n![](veerwolf_basys3.png)\n\n*VeeRwolf Basys 3 target*\n\n### I/O\n\nThe active on-board I/O consists of LEDs, switches and the microUSB connector for UART, JTAG and power.\n\n#### LEDs\n\n16 LEDs are controlled by memory-mapped GPIO at address 0x80001010-0x80001011\n\n#### Switches\n\n16 Switches are mapped GPIO addresses at 0x80001012-0x80001013\n\nDuring boot up, the two topmost switches (sw14, sw15) control the boot mode.\n\n| sw15 | sw14 | Boot mode                  |\n| ---- | ---- | -------------------------- |\n|  off |  off | Boot from SPI Flash        |\n|  off |   on | Boot from serial           |\n|   on |  off | Boot from address 0 in RAM |\n|   on |   on | Undefined                  |\n\n#### micro USB\n\nUART and JTAG communication is tunneled through the microUSB port on the board and will appear as `/dev/ttyUSB0`, `/dev/ttyUSB1` or similar depending on OS configuration. A terminal emulator can be used to connect to the UART (e.g. by running `screen /dev/ttyUSB0 115200`) and OpenOCD can connect to the JTAG port to program the FPGA or connect the debug proxy. The [debugging](#debugging) chapter goes into more detail on how to connect a debugger.\n\n#### SPI Flash\n\nAn SPI controller is connected to the on-board SPI Flash. This can be used for storing data such as program to be loaded into memory during boot. The [SPI uImage loader](#spi-uimage-loader) chapter goes into more detail on how to prepare, write and boot a program stored in SPI Flash\n\n# How to use\n\n## Prerequisites\n\nInstall [verilator](https://www.veripool.org/wiki/verilator)\n\nCreate an empty directory, e.g. named veerwolf, to use as the root of the project. This directory will from now on be called `$WORKSPACE`. All further commands will be run from `$WORKSPACE` unless otherwise stated. After entering the workspace directory, run `export WORKSPACE=$(pwd)` to set the $WORKSPACE shell variable.\n\n1. Make sure you have [FuseSoC](https://github.com/olofk/fusesoc) version 1.12 or newer installed or install it with `pip install fusesoc`\n2. Add the FuseSoC base library to the workspace with `fusesoc library add fusesoc-cores https://github.com/fusesoc/fusesoc-cores`\n3. Add the veerwolf library with `fusesoc library add veerwolf https://github.com/chipsalliance/VeeRwolf`\n4. Make sure you have verilator installed to run the simulation. **Note** This requires at least version 3.918. The version that is shipped with Ubuntu 18.04 will NOT work\n\nYour workspace shall now look like this:\n\n    $WORKSPACE\n    └──fusesoc_libraries\n       ├──fusesoc-cores\n       └──veerwolf\n\nAfter step 3, the VeeRwolf sources will be located in `$WORKSPACE/fusesoc_libraries/veerwolf`. For convenience, this directory will from now on be refered to as `$VEERWOLF_ROOT`. Run `export VEERWOLF_ROOT=$WORKSPACE/fusesoc_libraries/veerwolf` to set this as a shell variable\n\nInstall [Zephyr SDK](https://github.com/zephyrproject-rtos/sdk-ng/tags)\n\nIn order to  build zephyr application the zephyr SDK must be installed.  Attempting to build with west build will tell you which version is needed (if not already installed).  It is probably best to go with the oldest recommended version, since it is possible to fail by using a too new SDK (e.g. a compiler that needs options the build system (which is part of the OS release, not the SDK) does not yet know how to provide).\n\nDifferent versions of the zephyr SDK can be found at (https://github.com/zephyrproject-rtos/sdk-ng/tags).  Installation details differ between the versions, but tend to be either a self-contained installer script (e.g. zephyr-sdk-0.13.2-linux-aarch64-setup.run that is applied by\n\nchmod a+x zephyr-sdk-0.13.2-linux-aarch64-setup.run\n\n./zephyr-sdk-0.13.2-linux-aarch64-setup.run\n\nor an archive with an installer script (e.g. zephyr-sdk-0.16.1_linux-x86_64_minimal.tar.xz) which needs to be extracted and the installer run by\ntar xvf zephyr-sdk-0.16.1_linux-x86_64_minimal.tar.xz\ncd zephyr-sdk-0.16.1\n./setup.sh\n\nInstall [Vivado](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools)\n\nVivado is needed to synthesize the design for the nexys A7 target.  The standard edition is available free of charge from Xilinx/AMD, but the user needs to register and fill out an export license form.  A good place to start is probably https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools.html.  Someone doing this for the first time can probably expand on these notes, I already had a registered xilinx user so probably short-circuited part of the process.\n\n## Running the SoC\n\nThe VeeRwolf SoC can be run in simulation or on hardware (Digilent Nexys A7 currently supported). In either case FuseSoC is used to launch the simulation or build and run the FPGA build. To select what to run, use the `fusesoc run` command with the `--target` parameter. To run in simulation use\n\n    fusesoc run --target=sim veerwolf\n\nThis will load a small example program that prints a string and exits. If you want to rerun the program without rebuilding the simulation model, you can add the --run parameter\n\n    fusesoc run --target=sim --run veerwolf\n\nTo build (and optionally program) an image for a Nexys A7 board, run\n\n    fusesoc run --target=nexys_a7 veerwolf\n\nAll targets support different compile- and run-time options. To see all options for a target run\n\n    fusesoc run --target=$TARGET veerwolf --help\n\nTo list all available targets, run\n\n    fusesoc core show veerwolf\n\nTo build and run on Riviera-Pro simulator\n\n    fusesoc run --target=sim --tool=rivierapro veerwolf\n\nAfter building any of the targets, there will now be a `build` in your workspace. This directory contains everything needed to rebuild the target. It can be safely removed and gets rebuilt when building a target again. To use a different build directory, pass `--build-root=\u003coutput dir\u003e` to the run arguments.\n\n### Run a precompiled example in simulation\n\nIn simulation, VeeRwolf supports preloading an application to memory with the `--ram_init_file` parameter. VeeRwolf comes bundled with some example applications in the `sw` directory.\n\nTo build the simulation model and run the bundled Zephyr Hello world example in a simulator. `fusesoc run --target=sim veerwolf --ram_init_file=$VEERWOLF_ROOT/sw/zephyr_hello.vh`.\nTo build and run this example on Riviera-Pro: `fusesoc run --target=sim --tool=rivierapro veerwolf --ram_init_file=$VEERWOLF_ROOT/sw/zephyr_hello.vh`.\n\nAfter running the above command, the simulation model should be built and run. At the end it will output\n\n    Releasing reset\n    ***** Booting Zephyr OS zephyr-v1.14.0 *****\n    Hello World! veerwolf_nexys\n\nAt this point the simulation can be aborted with `Ctrl-C`.\n\nAnother example to run is the Zephyr philosophers demo.\n\n    fusesoc run --run --target=sim veerwolf --ram_init_file=$VEERWOLF_ROOT/sw/zephyr_philosophers.vh\n\n* Note the `--run` option which will prevent rebuilding the simulator model\n\n### Run RISC-V compliance tests\n\n**Note:** The following instructions are valid for version 1.0 of the RISC-V compliance tests. The target-specific support for VeeRwolf has not yet been ported to newer versions.\n\n1. Build the simulation model, if that hasn't already been done, with `fusesoc run --target=sim --setup --build veerwolf`\n2. Download the RISC-V compliance tests to the workspace with `git clone https://github.com/riscv/riscv-compliance --branch 1.0`. Your directory structure should now look like this:\n\n        $WORKSPACE\n        ├──build\n        ├──fusesoc_libraries\n        └──riscv-compliance\n\n3. Enter the riscv-compliance directory and run `make TARGETDIR=$VEERWOLF_ROOT/riscv-target RISCV_TARGET=veer RISCV_DEVICE=rv32i RISCV_ISA=rv32i TARGET_SIM=$WORKSPACE/build/veerwolf_0.7.5/sim-verilator/Vveerwolf_core_tb`\n\n*Note: Other test suites can be run by replacing RISCV_ISA=rv32imc with rv32im or rv32i*\n\n*Note: The `TARGET_SIM` path needs to be updated to reflect the actual location of `Vveerwolf_core_tb`*\n\n### Run on hardware\n\nThe VeeRwolf SoC can be built for a Digilent Nexys A7 board with\n\n    fusesoc run --target=nexys_a7 veerwolf\n\nIf the board is connected, it will automatically be programmed when the FPGA image has been built. It can also be programmed manually afterwards by running `fusesoc run --target=nexys_a7 --run veerwolf` or running OpenOCD as described in the debugging chapter.\n\nThe default bootloader will boot from SPI Flash, RAM or serial depending on the boot mode set by the switches. The default bootloader can be replaced with the `--bootrom_file` parameter. Note that the boot ROM is not connected to the data port, so it can only execute instructions. Data can not be read or written to this segment. The below example will compile the memtest application and use that as boot ROM instead.\n\n    make -C ../$VEERWOLF_ROOT/sw memtest.vh\n    fusesoc run --target=nexys_a7 veerwolf --bootrom_file=$VEERWOLF_ROOT/sw/memtest.vh\n\n## Build Zephyr applications\n\n        $WORKSPACE\n        ├──fusesoc_libraries\n        ├──...\n        └──zephyr\n\n1.Create a West (Zephyr's build tool) workspace in the same directory as the FuseSoC workspace by running\n    west init\n2. Add the VeeRwolf-specific drivers and BSP with\n\n    west config manifest.path fusesoc_libraries/veerwolf\n    west update\n\n   The workspace should now look like this\n\n        $WORKSPACE\n        ├──fusesoc_libraries\n        |  ├──...\n        |  └──veerwolf\n        ├──...\n        └──zephyr\n\n3. Enter the directory of the application to build. Zephyr comes with a number of example applications in the samples directory (`$WORKSPACE/zephyr/samples`), e.g. `$WORKSPACE/zephyr/samples/basic/blinky` contains the Zephyr blinky example. From now on, the program to build and run will be called `$APP`\n4. Build the code with `west build -b veerwolf_nexys`\n\nAfter building the code there will now be an executable .elf file in `build/zephyr/zephyr.elf` and a binary file in `build/zephyr/zephyr.bin`. The executable file can be loaded into VeeRwolf with a debugger and the binary file can be further converted and loaded into RAM for simulations.\n\nTo load the .elf file with a debugger, see [Loading programs with OpenOCD](#loading-programs-with-openocd)\n\nTo use the .bin file in a simulator, it must first be converted into a suitable verilog hex file. From the directory where the application was built, run\n    `python3 $VEERWOLF_ROOT/sw/makehex.py build/zephyr/zephyr.bin \u003e $WORKSPACE/$APP.hex` to create a hex file in the workspace directory. This can now be loaded into a simulator with\n\n    fusesoc run --target=sim veerwolf --ram_init_file=$APP.hex\n\nThe VeeRwolf demo application in `$VEERWOLF_ROOT/sw/veerwolf_zephyr_demo` is also a Zephyr program and can be built in the same way\n\n## Debugging\n\nVeeRwolf supports debugging both on hardware and in simulation. There are different procedures on how to connect the debugger, but once connected, the same commands can be used (although it's a lot slower in simulations).\n\n### Prerequisites\n\nInstall the RISC-V-specific version of OpenOCD. (The OpenOCD code shall be no older than commit 22d771d2 from Sep 14, 2020.)\n\n    git clone https://github.com/riscv/riscv-openocd\n    cd riscv-openocd\n    ./bootstrap\n    ./configure --enable-jtag_vpi --enable-ftdi\n    make\n    sudo make install\n\n### Connecting debugger to simulation\n\nWhen a VeeRwolf simulation is launched with the `--jtag_vpi_enable`, it will start a JTAG server waiting for a client to connect and send JTAG commands.\n\n    fusesoc run --target=sim veerwolf --jtag_vpi_enable\n\nAfter compilation, the simulation should now say\n\n    Listening on port 5555\n\nThis means that it's ready to accept a JTAG client.\n\nOpen a new terminal, navigate to the workspace directory and run `openocd -f $VEERWOLF_ROOT/data/veerwolf_sim.cfg` to connect OpenOCD to the simulation instance. If successful, OpenOCD should output\n\n    Info : only one transport option; autoselect 'jtag'\n    Info : Set server port to 5555\n    Info : Set server address to 127.0.0.1\n    Info : Connection to 127.0.0.1 : 5555 succeed\n    Info : This adapter doesn't support configurable speed\n    Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (\u003cinvalid\u003e), part: 0x0000, ver: 0x0)\n    Info : datacount=2 progbufsize=0\n    Warn : We won't be able to execute fence instructions on this target. Memory may not always appear consistent. (progbufsize=0, impebreak=0)\n    Info : Examined RISC-V core; found 1 harts\n    Info :  hart 0: XLEN=32, misa=0x40001104\n    Info : Listening on port 3333 for gdb connections\n    Info : Listening on port 6666 for tcl connections\n    Info : Listening on port 4444 for telnet connections\n\nand the simulation should report\n\n    Waiting for client connection...ok\n    Preloading TOP.veerwolf_core_tb.veerwolf.bootrom.ram from jumptoram.vh\n    Releasing reset\n\nOpen a third terminal and connect to the debug session through OpenOCD with `telnet localhost 4444`. From this terminal, it is now possible to view and control the state of of the CPU and memory. Try this by running `mwb 0x80001010 1`. This will write to the GPIO register. To verify that it worked, there should now be a message from the simulation instance saying `gpio0 is on`. By writing 0 to the same register (`mwb 0x80001010 0`), the gpio will be turned off.\n\n### Connecting debugger to Nexys A7\n\nVeeRwolf can be debugged using the same USB cable that is used for programming the FPGA, communicating over UART and powering the board. There is however one restriction. If the Vivado programmer has been used, it will have exclusive access to the JTAG channel. For that reason it is recommended to avoid using the Vivado programming tool and instead use OpenOCD for programming the FPGA as well. Unplugging and plugging the USB cable back will make Vivado lose the grip on the JTAG port.\n\nProgramming the board with OpenOCD can be performed by running (from $WORKSPACE)\n\n    openocd -f $VEERWOLF_ROOT/data/veerwolf_nexys_program.cfg\n\nTo change the default FPGA image to load, add `-c \"set BITFILE /path/to/bitfile\"` as the first argument to openocd.\n\nIf everything goes as expected, this should output\n\n    Info : ftdi: if you experience problems at higher adapter clocks, try the command \"ftdi_tdo_sample_edge falling\"\n    Info : clock speed 10000 kHz\n    Info : JTAG tap: xc7.tap tap/device found: 0x13631093 (mfg: 0x049 (Xilinx), part: 0x3631, ver: 0x1)\n    Warn : gdb services need one or more targets defined\n    loaded file build/veerwolf_0/nexys_a7-vivado/veerwolf_0.bit to pld device 0 in 3s 201521us\n    shutdown command invoked\n\nOpenOCD can now be connected to VeeRwolf by running\n\n    openocd -f $VEERWOLF_ROOT/data/veerwolf_nexys_debug.cfg\n\nThis should output\n\n    Info : ftdi: if you experience problems at higher adapter clocks, try the command \"ftdi_tdo_sample_edge falling\"\n    Info : clock speed 10000 kHz\n    Info : JTAG tap: riscv.cpu tap/device found: 0x13631093 (mfg: 0x049 (Xilinx), part: 0x3631, ver: 0x1)\n    Info : datacount=2 progbufsize=0\n    Warn : We won't be able to execute fence instructions on this target. Memory may not always appear consistent. (progbufsize=0, impebreak=0)\n    Info : Examined RISC-V core; found 1 harts\n    Info :  hart 0: XLEN=32, misa=0x40001104\n    Info : Listening on port 3333 for gdb connections\n    Info : Listening on port 6666 for tcl connections\n    Info : Listening on port 4444 for telnet connections\n\nOpen a third terminal and connect to the debug session through OpenOCD with `telnet localhost 4444`. From this terminal, it is now possible to view and control the state of of the CPU and memory. Try this by running `mwb 0x80001010 1`. This will write to the GPIO register. To verify that it worked, LED0 should light up. By writing 0 to the same register (`mwb 0x80001010 0`), the LED will be turned off.\n\n### Loading programs with OpenOCD\n\nOpenOCD support loading ELF program files by running `load_image /path/to/file.elf`. Remember that the path is relative to the directory from where OpenOCD was launched.\n\nAfter the program has been loaded, set the program counter to address zero with `reg pc 0` and run `resume` to start the program.\n\n## Booting\n\nVeeRwolf is set up by default to read its initial instructions from address 0x80000000 which point to the on-chip boot ROM. A default bootloader is provided which has the capability to boot from SPI Flash, RAM or serial depending on the GPIO pins connected to bits 7:6 in register 0x80001013. The table below summarizes the boot modes\n\n| bit7 | bit6 | Boot mode         |\n| ---- | ---- | ----------------- |\n|    0 |    0 | SPI uImage loader |\n|    0 |    1 | Jump to RAM       |\n|    1 |    0 | Serial boot       |\n|    1 |    1 | Undefined         |\n\n### Jump to RAM\n\nFor simulations, the most common option is to load a program into the on-chip RAM and start executing from there. The default bootloader in such cases is a single instruction that jumps to address 0x0 and continues execution from there.\n\n### SPI uImage loader\n\nFor most applications on real hardware it is preferred to store them in an on-board SPI Flash memory. The SPI uImage loader can read an image in the u-boot uImage format, copy it to RAM and start executing. This process requires creating a suitable image, writing it to Flash and set up the SPI uImage loader to read from the correct address in Flash.\n\n#### Create a flash image\n\nThe `mkimage` tool available from u-boot is used to prepare an image to be written to Flash. `mkimage` expects a `.bin` file, which has been created with `iscv64-unknown-elf-objcopy -O binary`. Given a `$IMAGE.bin` we can now create `$IMAGE.ub` with the following command:\n\n    mkimage -A riscv -C none -T standalone -a 0x0 -e 0x0 -n '' -d $IMAGE.bin $IMAGE.ub\n\nRefer to the uimage manual for a description of each parameter. There are also Makefile targets in `$VEERWOLF_ROOT/sw/Makefile` that can be used as reference.\n\n### Writing SPI Flash\n\n#### Simulation\n\nIn order to test the SPI image loading mechanism in simulation, a specific FuseSoC target, `spi_tb` is available. If no run-time parameters are supplied it will load a prebuilt image containing the `hello` program (source available in `sw/hello.S`) from Flash, execute it and exit. This testbench will not work in Verilator as it uses a non synthesizable model of the SPI Flash. The default simulator is instead ModelSim. Other simulators can be used by adding the `--tool=$TOOL` argument to the command-line.\n\n    fusesoc run --target=spi_tb veerwolf\n\nThe simulated Flash contents can be changed at compile-time with the `--flash_init_file` parameter. The model expects a uImage in verilog hex format. Such files can be created by running\n\n    objcopy -I binary -O verilog $IMAGE.ub $IMAGE.hex\n\n#### Nexys A7\n\nFor Nexys A7, OpenOCD is used to write to Flash. As the connection to the SPI Flash goes through the FPGA, this consists of a two-stage process where a proxy FPGA image is first written, which will handle communication between OpenOCD and the SPI Flash\n\n1. Obtain the proxy FPGA image from [here](https://github.com/quartiq/bscan_spi_bitstreams/blob/master/bscan_spi_xc7a100t.bit) and place it in `$WORKSPACE`\n2. Run `openocd -c \"set BINFILE $IMAGE\" -f $VEERWOLF_ROOT/data/veerwolf_nexys_write_flash.cfg`, where `$IMAGE` is the path to the uImage file that should be written to Flash\n\n### Set up SPI uImage loader\n\nThe final step is to prepare the bootloader for VeeRwolf which will be responsible for reading the image from Flash, copy it to RAM and execute it. This process is the same for both simulation and hardware targets. Note that both the `spi_tb` target and `nexys_a7` target will have this as the default boot loader so in most cases nothing else needs to be done. There are however a couple of defines in `sw/spi_uimage_loader.S` that might need to be adjusted if the SPI controller is mapped to another base address or if the image is not stored at address 0 in the Flash.\n\n### Serial boot\n\nIn serial boot mode, the UART waits for a program in Intel Hex format to be sent to the UART. Upon completion, the program will be launched.\n\n## CPU configuration\n\nVeeRwolf currently supports the VeeR EH1 and EL2 cores. For all targets VeeR EH1 is used by default unless there are hardware limitations (e.g. FPGA size) that only allows using VeeR EL2. All targets can optionally use VeeR EL2 by passing  `--flag=cpu_el2` as a run option to FuseSoC, e.g. `fusesoc run --target=sim --flag=cpu_el2 veerwolf` will run the default simulation example using VeeR EL2. Also note that the max frequency of the processors can differ. E.g. on the Nexys A7 board VeeR EH1 will run at 50MHz while VeeR EL2 runs at 25MHz. The `clk_freq_hz` register in the system controller will always show the correct value. The bootloader and Zephyr board support is also set up to automatically adapt timer and UART speeds to the runtime-detected clock speed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchipsalliance%2Fveerwolf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchipsalliance%2Fveerwolf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchipsalliance%2Fveerwolf/lists"}