{"id":13408580,"url":"https://github.com/SpinalHDL/VexRiscv","last_synced_at":"2025-03-14T13:31:45.220Z","repository":{"id":37706333,"uuid":"84366787","full_name":"SpinalHDL/VexRiscv","owner":"SpinalHDL","description":"A FPGA friendly 32 bit RISC-V CPU implementation","archived":false,"fork":false,"pushed_at":"2024-10-21T15:25:33.000Z","size":13442,"stargazers_count":2474,"open_issues_count":106,"forks_count":416,"subscribers_count":101,"default_branch":"master","last_synced_at":"2024-10-22T02:15:35.315Z","etag":null,"topics":["cpu","fpga","riscv","soc","softcore","spinalhdl","verilog","vhdl"],"latest_commit_sha":null,"homepage":"","language":"Assembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SpinalHDL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-03-08T21:14:28.000Z","updated_at":"2024-10-21T15:25:37.000Z","dependencies_parsed_at":"2023-02-10T15:31:31.733Z","dependency_job_id":"33ce7d39-3400-41db-bd47-38eaef1da6ef","html_url":"https://github.com/SpinalHDL/VexRiscv","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpinalHDL%2FVexRiscv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpinalHDL%2FVexRiscv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpinalHDL%2FVexRiscv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpinalHDL%2FVexRiscv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SpinalHDL","download_url":"https://codeload.github.com/SpinalHDL/VexRiscv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243584353,"owners_count":20314739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cpu","fpga","riscv","soc","softcore","spinalhdl","verilog","vhdl"],"created_at":"2024-07-30T20:00:53.803Z","updated_at":"2025-03-14T13:31:45.201Z","avatar_url":"https://github.com/SpinalHDL.png","language":"Assembly","readme":"## Index\n\n- [Index](#index)\n- [Description](#description)\n- [Area usage and maximal frequency](#area-usage-and-maximal-frequency)\n- [Dependencies](#dependencies)\n- [CPU generation](#cpu-generation)\n- [Regression tests](#regression-tests)\n- [Interactive debug of the simulated CPU via GDB OpenOCD and Verilator](#interactive-debug-of-the-simulated-cpu-via-gdb-openocd-and-verilator)\n- [Using Eclipse to run and debug the software](#using-eclipse-to-run-and-debug-the-software)\n  - [By using gnu-mcu-eclipse](#by-using-gnu-mcu-eclipse)\n  - [By using Zylin plugin (old)](#by-using-zylin-plugin-old)\n- [Briey SoC](#briey-soc)\n- [Murax SoC](#murax-soc)\n- [Running Linux](#running-linux)\n- [Build the RISC-V GCC](#build-the-risc-v-gcc)\n- [CPU parametrization and instantiation example](#cpu-parametrization-and-instantiation-example)\n- [Add a custom instruction to the CPU via the plugin system](#add-a-custom-instruction-to-the-cpu-via-the-plugin-system)\n- [Adding a new CSR via the plugin system](#adding-a-new-csr-via-the-plugin-system)\n- [CPU clock and resets](#cpu-clock-and-resets)\n- [VexRiscv Architecture](#vexriscv-architecture)\n  - [FPU](#fpu)\n  - [Plugins](#plugins)\n    - [IBusSimplePlugin](#ibussimpleplugin)\n    - [IBusCachedPlugin](#ibuscachedplugin)\n    - [DecoderSimplePlugin](#decodersimpleplugin)\n    - [RegFilePlugin](#regfileplugin)\n    - [HazardSimplePlugin](#hazardsimpleplugin)\n    - [SrcPlugin](#srcplugin)\n    - [IntAluPlugin](#intaluplugin)\n    - [LightShifterPlugin](#lightshifterplugin)\n    - [FullBarrelShifterPlugin](#fullbarrelshifterplugin)\n    - [BranchPlugin](#branchplugin)\n      - [Prediction NONE](#prediction-none)\n      - [Prediction STATIC](#prediction-static)\n      - [Prediction DYNAMIC](#prediction-dynamic)\n      - [Prediction DYNAMIC_TARGET](#prediction-dynamic_target)\n    - [DBusSimplePlugin](#dbussimpleplugin)\n    - [DBusCachedPlugin](#dbuscachedplugin)\n    - [MulPlugin](#mulplugin)\n    - [DivPlugin](#divplugin)\n    - [MulDivIterativePlugin](#muldiviterativeplugin)\n    - [CsrPlugin](#csrplugin)\n    - [StaticMemoryTranslatorPlugin](#staticmemorytranslatorplugin)\n    - [MmuPlugin](#mmuplugin)\n    - [PmpPlugin](#pmpplugin)\n      - [PmpPluginNapot](#pmppluginnapot)\n    - [DebugPlugin](#debugplugin)\n    - [EmbeddedRiscvJtag](#embeddedRiscvJtag)\n    - [YamlPlugin](#yamlplugin)\n    - [FpuPlugin](#fpuplugin)\n    - [AesPlugin](#aesplugin)\n\n\n\n## Description\n\nThis repository hosts a RISC-V implementation written in SpinalHDL. Here are some specs :\n\n- RV32I[M][A][F[D]][C] instruction set\n- Pipelined from 2 to 5+ stages ([Fetch*X], Decode, Execute, [Memory], [WriteBack])\n- 1.44 DMIPS/MHz --no-inline when nearly all features are enabled (1.57 DMIPS/MHz when the divider lookup table is enabled)\n- Optimized for FPGA, does not use any vendor specific IP block / primitive\n- AXI4, Avalon, wishbone ready\n- Optional MUL/DIV extensions\n- Optional F32/F64 FPU (require data cache for now)\n- Optional instruction and data caches\n- Optional hardware refilled MMU\n- Optional debug extension allowing Eclipse debugging via a GDB \u003e\u003e openOCD \u003e\u003e JTAG connection\n- Optional interrupts and exception handling with Machine, [Supervisor] and [User] modes as defined in the [RISC-V Privileged ISA Specification v1.10](https://riscv.org/specifications/privileged-isa/).\n- Two implementations of shift instructions: single cycle (full barrel shifter) and shiftNumber cycles\n- Each stage can have optional bypass or interlock hazard logic\n- Linux compatible (SoC : https://github.com/enjoy-digital/linux-on-litex-vexriscv)\n- Zephyr compatible\n- [FreeRTOS port](https://github.com/Dolu1990/FreeRTOS-RISCV)\n- Support tightly coupled memory on I$ D$ (see GenFullWithTcm / GenFullWithTcmIntegrated)\n\nThe hardware description of this CPU is done by using a very software oriented approach\n(without any overhead in the generated hardware). Here is a list of software concepts used:\n\n- There are very few fixed things. Nearly everything is plugin based. The PC manager is a plugin, the register file is a plugin, the hazard controller is a plugin, ...\n- There is an automatic a tool which allows plugins to insert data in the pipeline at a given stage, and allows other plugins to read it in another stage through automatic pipelining.\n- There is a service system which provides a very dynamic framework. For instance, a plugin could provide an exception service which can then be used by other plugins to emit exceptions from the pipeline.\n\nThere is a gitter channel for all questions about VexRiscv :\u003cbr\u003e\n[![Gitter](https://badges.gitter.im/SpinalHDL/VexRiscv.svg)](https://gitter.im/SpinalHDL/VexRiscv?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\nFor commercial support, please contact spinalhdl@gmail.com.\n\nNote you may be interested VexiiRiscv (https://github.com/SpinalHDL/VexiiRiscv).\n\n## Area usage and maximal frequency\n\nThe following numbers were obtained by synthesizing the CPU as toplevel on the fastest speed grade without any specific synthesis options to save area or to get better maximal frequency (neutral).\u003cbr\u003e\nThe clock constraint is set to an unattainable value, which tends to increase the design area.\u003cbr\u003e\nThe dhrystone benchmark was compiled with the `-O3 -fno-inline` option.\u003cbr\u003e\nAll the cached configurations have some cache trashing during the dhrystone benchmark except the `VexRiscv full max perf` one. This, of course, reduces the performance. It is possible to produce\ndhrystone binaries which fit inside a 4KB I$ and 4KB D$ (I already had this case once) but currently it isn't the case.\u003cbr\u003e\nThe CPU configurations used below can be found in the `src/scala/vexriscv/demo` directory.\n\n```\nVexRiscv small (RV32I, 0.52 DMIPS/MHz, no datapath bypass, no interrupt) -\u003e\n    Artix 7     -\u003e 243 MHz 504 LUT 505 FF \n    Cyclone V   -\u003e 174 MHz 352 ALMs\n    Cyclone IV  -\u003e 179 MHz 731 LUT 494 FF \n    iCE40       -\u003e 92 MHz 1130 LC\n\nVexRiscv small (RV32I, 0.52 DMIPS/MHz, no datapath bypass) -\u003e\n    Artix 7     -\u003e 240 MHz 556 LUT 566 FF \n    Cyclone V   -\u003e 194 MHz 394 ALMs\n    Cyclone IV  -\u003e 174 MHz 831 LUT 555 FF \n    iCE40       -\u003e 85 MHz 1292 LC\n\nVexRiscv small and productive (RV32I, 0.82 DMIPS/MHz)  -\u003e\n    Artix 7     -\u003e 232 MHz 816 LUT 534 FF \n    Cyclone V   -\u003e 155 MHz 492 ALMs\n    Cyclone IV  -\u003e 155 MHz 1,111 LUT 530 FF \n    iCE40       -\u003e 63 MHz 1596 LC\n\nVexRiscv small and productive with I$ (RV32I, 0.70 DMIPS/MHz, 4KB-I$)  -\u003e\n    Artix 7     -\u003e 220 MHz 730 LUT 570 FF \n    Cyclone V   -\u003e 142 MHz 501 ALMs\n    Cyclone IV  -\u003e 150 MHz 1,139 LUT 536 FF \n    iCE40       -\u003e 66 MHz 1680 LC\n\nVexRiscv full no cache (RV32IM, 1.21 DMIPS/MHz 2.30 Coremark/MHz, single cycle barrel shifter, debug module, catch exceptions, static branch) -\u003e\n    Artix 7     -\u003e 216 MHz 1418 LUT 949 FF \n    Cyclone V   -\u003e 133 MHz 933 ALMs\n    Cyclone IV  -\u003e 143 MHz 2,076 LUT 972 FF \n\nVexRiscv full (RV32IM, 1.21 DMIPS/MHz 2.30 Coremark/MHz with cache trashing, 4KB-I$,4KB-D$, single cycle barrel shifter, debug module, catch exceptions, static branch) -\u003e\n    Artix 7     -\u003e 199 MHz 1840 LUT 1158 FF \n    Cyclone V   -\u003e 141 MHz 1,166 ALMs\n    Cyclone IV  -\u003e 131 MHz 2,407 LUT 1,067 FF \n\nVexRiscv full max perf (HZ*IPC) -\u003e (RV32IM, 1.38 DMIPS/MHz 2.57 Coremark/MHz, 8KB-I$,8KB-D$, single cycle barrel shifter, debug module, catch exceptions, dynamic branch prediction in the fetch stage, branch and shift operations done in the Execute stage) -\u003e\n    Artix 7     -\u003e 200 MHz 1935 LUT 1216 FF \n    Cyclone V   -\u003e 130 MHz 1,166 ALMs\n    Cyclone IV  -\u003e 126 MHz 2,484 LUT 1,120 FF \n\nVexRiscv full with MMU (RV32IM, 1.24 DMIPS/MHz 2.35 Coremark/MHz, with cache trashing, 4KB-I$, 4KB-D$, single cycle barrel shifter, debug module, catch exceptions, dynamic branch, MMU) -\u003e\n    Artix 7     -\u003e 151 MHz 2021 LUT 1541 FF \n    Cyclone V   -\u003e 124 MHz 1,368 ALMs\n    Cyclone IV -\u003e 128 MHz 2,826 LUT 1,474 FF \n\nVexRiscv linux balanced (RV32IMA, 1.21 DMIPS/MHz 2.27 Coremark/MHz, with cache trashing, 4KB-I$, 4KB-D$, single cycle barrel shifter, catch exceptions, static branch, MMU, Supervisor, Compatible with mainstream linux) -\u003e\n    Artix 7     -\u003e 180 MHz 2883 LUT 2130 FF \n    Cyclone V   -\u003e 131 MHz 1,764 ALMs\n    Cyclone IV  -\u003e 121 MHz 3,608 LUT 2,082 FF \n```\n\nThe following configuration results in 1.44 DMIPS/MHz:\n\n- 5 stage: F -\u003e D -\u003e E -\u003e M  -\u003e WB\n- single cycle ADD/SUB/Bitwise/Shift ALU\n- branch/jump done in the E stage\n- memory load values are bypassed in the WB stage (late result)\n- 33 cycle division with bypassing in the M stage (late result)\n- single cycle multiplication with bypassing in the WB stage (late result)\n- dynamic branch prediction done in the F stage with a direct mapped target buffer cache (no penalties on correct predictions)\n\nNote that, recently, the capability to remove the Fetch/Memory/WriteBack stage was added to reduce the area of the CPU, which ends up with a smaller CPU and a better DMIPS/MHz for the small configurations.\n\n## Dependencies\n\nOn Ubuntu 14:\n\n```sh\n# JAVA JDK 8\nsudo add-apt-repository -y ppa:openjdk-r/ppa\nsudo apt-get update\nsudo apt-get install openjdk-8-jdk -y\nsudo update-alternatives --config java\nsudo update-alternatives --config javac\n\n# Install SBT - https://www.scala-sbt.org/\necho \"deb https://repo.scala-sbt.org/scalasbt/debian all main\" | sudo tee /etc/apt/sources.list.d/sbt.list\necho \"deb https://repo.scala-sbt.org/scalasbt/debian /\" | sudo tee /etc/apt/sources.list.d/sbt_old.list\ncurl -sL \"https://keyserver.ubuntu.com/pks/lookup?op=get\u0026search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823\" | sudo apt-key add\nsudo apt-get update\nsudo apt-get install sbt\n\n# Verilator (for sim only, really needs 3.9+, in general apt-get will give you 3.8)\nsudo apt-get install git make autoconf g++ flex bison\ngit clone http://git.veripool.org/git/verilator   # Only first time\nunsetenv VERILATOR_ROOT  # For csh; ignore error if on bash\nunset VERILATOR_ROOT  # For bash\ncd verilator\ngit pull        # Make sure we're up-to-date\ngit checkout v4.216\nautoconf        # Create ./configure script\n./configure\nmake\nsudo make install\n```\n\n## CPU generation\nWe now have twenty-two CPU configurations [in this directory](./src/main/scala/vexriscv/demo).  Look at the files called Gen*.scala.  Here is the [full configuration](./src/main/scala/vexriscv/demo/GenFull.scala), and the [smallest configuration](./src/main/scala/vexriscv/demo/GenSmallest.scala). \n\nTo generate the corresponding RTL as a `VexRiscv.v` file, run the following commands in the root directory of this repository:\n\n```sh\nsbt \"runMain vexriscv.demo.GenFull\"\n```\n\nor\n\n```sh\nsbt \"runMain vexriscv.demo.GenSmallest\"\n```\n\nNOTES:\n- It could take time the first time you run it.\n- The VexRiscv project may need an unreleased master-head of the SpinalHDL repo. If it fails to compile, just get the SpinalHDL repository and\n   do a \"sbt clean compile publishLocal\" in it as described in the dependencies chapter.\n\n## Regression tests\n\n[![Build Status](https://travis-ci.org/SpinalHDL/VexRiscv.svg?branch=master)](https://travis-ci.org/SpinalHDL/VexRiscv)\n\nTo run tests (need java, scala, verilator), just do :\n\n```sh\nexport VEXRISCV_REGRESSION_SEED=42\nexport VEXRISCV_REGRESSION_TEST_ID=\nsbt \"testOnly vexriscv.TestIndividualFeatures\"\n```\n\nThis will generate random VexRiscv configuration and test them with: \n- ISA tests from https://github.com/riscv/riscv-tests/tree/master/isa and  https://github.com/riscv/riscv-compliance\n- Dhrystone benchmark\n- Coremark benchmark\n- Zephyr os\n- Buildroot/Linux os\n- Some handwritten tests to check the CSR, debug module and MMU plugins\n\nYou can rerun some specific test by setting VEXRISCV_REGRESSION_TEST_ID by their id. For instance, if you want to rerun :\n- test_id_5_test_IBus_CachedS1024W1BPL32Relaxvexriscv.plugin.DYNAMIC_DBus_CachedS8192W2BPL16_MulDiv_MulDivFpga_Shift_FullLate_Branch_Late_Hazard_BypassAll_RegFile_SyncDR_Src__Csr_AllNoException_Decoder__Debug_None_DBus_NoMmu\n- test_id_9_test_IBus_Simple1S2InjStagevexriscv.plugin.STATIC_DBus_SimpleLate_MulDiv_MulDivFpgaSimple_Shift_FullEarly_Branch_Late_Hazard_Interlock_RegFile_AsyncER_Src_AddSubExecute_Csr_None_Decoder__Debug_None_DBus_NoMmu\n\nthen :\n\n```\nexport VEXRISCV_REGRESSION_TEST_ID=5,9\n```\n\nAlso there is a few environnement variable that you can use to modulate the random generation : \n\n| Parameters                                  | range              | description |\n| ------------------------------------------- | ------------------ | ----------- |\n| VEXRISCV_REGRESSION_SEED                    | Int                | Seed used to generate the random configurations |        \n| VEXRISCV_REGRESSION_TEST_ID                 | \\[Int\\[,\\Int\\]\\*\\] | Random configuration that should be keeped and tested |                        \n| VEXRISCV_REGRESSION_CONFIG_COUNT            | Int                | Number of random configurations |                        \n| VEXRISCV_REGRESSION_CONFIG_RVC_RATE         | 0.0-1.0            | Chance to generate a RVC config |                               \n| VEXRISCV_REGRESSION_CONFIG_LINUX_RATE       | 0.0-1.0            | Chance to generate a linux ready config |            \n| VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE  | 0.0-1.0            | Chance to generate a machine mode OS ready config |            \n| VEXRISCV_REGRESSION_LINUX_REGRESSION        | yes/no             | Enable the linux test |           \n| VEXRISCV_REGRESSION_COREMARK                | yes/no             | Enable the Coremark test |           \n| VEXRISCV_REGRESSION_ZEPHYR_COUNT            | Int                | Number of zephyr tests to run on capable configs |        \n| VEXRISCV_REGRESSION_CONFIG_DEMW_RATE        | 0.0-1.0            | Chance to generate a config with writeback stage |            \n| VEXRISCV_REGRESSION_CONFIG_DEM_RATE         | 0.0-1.0            | Chance to generate a config with memory stage |            \n\n## Basic Verilator simulation\n\nTo run basic simulation with stdout and no tracing, loading a binary directly is supported with the `RUN_HEX` variable of `src/test/cpp/regression/makefile`. This has a significant performance advantage over using GDB over OpenOCD with JTAG over TCP. VCD tracing is supported with the makefile variable `TRACE`.\n\n## Interactive debug of the simulated CPU via GDB OpenOCD and Verilator\n\nTo use this, you just need to use the same command as with running tests, but adding `DEBUG_PLUGIN_EXTERNAL=yes` in the make arguments.\nThis works for the `GenFull` configuration, but not for `GenSmallest`, as this configuration has no debug module.\n\nThen, you can use the [OpenOCD RISC-V](https://github.com/SpinalHDL/openocd_riscv) tool to create a GDB server connected to the target (the simulated CPU), as follows:\n\n```sh\n#In the VexRiscv repository, to run the simulation on which one OpenOCD can connect itself =\u003e\nsbt \"runMain vexriscv.demo.GenFull\"\ncd src/test/cpp/regression\nmake run DEBUG_PLUGIN_EXTERNAL=yes\n\n#In the openocd git, after building it =\u003e\nsrc/openocd -c \"set VEXRISCV_YAML PATH_TO_THE_GENERATED_CPU0_YAML_FILE\" -f tcl/target/vexriscv_sim.cfg\n\n#Run a GDB session with an elf RISCV executable (GenFull CPU)\nYourRiscvToolsPath/bin/riscv32-unknown-elf-gdb VexRiscvRepo/src/test/resources/elf/uart.elf\ntarget remote localhost:3333\nmonitor reset halt\nload\ncontinue\n\n# Now it should print messages in the Verilator simulation of the CPU\n```\n\n## Using Eclipse to run and debug the software\n\n### By using gnu-mcu-eclipse\n\nYou can download releases of the IDE here: \u003chttps://github.com/gnu-mcu-eclipse/org.eclipse.epp.packages/releases\u003e\n\nIn the IDE, you can import a makefile project by:\n- file -\u003e import -\u003e C/C++ -\u003e existing Code as Makefile Project\n- Select the folder which contains the makefile, then select \"Cross GCC\" (not \"RISC-V Cross GCC\")\n\nTo create a new debug configuration:\n- run -\u003e Debug Configurations -\u003e GDB OpenOCD Debugging double click\n- Look at https://drive.google.com/open?id=1c46tyEV0xLwOsk76b0y2qqs8CYy7Zq3f for a configuration example\n\n### By using Zylin plugin (old)\nYou can use the Eclipse + Zylin embedded CDT plugin to do it (http://opensource.zylin.com/embeddedcdt.html). Tested with Helios Service Release 2 (http://www.Eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/helios/SR2/Eclipse-cpp-helios-SR2-linux-gtk-x86_64.tar.gz) and the corresponding zylin plugin.\n\nTo following commands will download Eclipse and install the plugin.\n\n```sh\nwget http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/helios/SR2/eclipse-cpp-helios-SR2-linux-gtk-x86_64.tar.gz\ntar -xvzf download.php?file=%2Ftechnology%2Fepp%2Fdownloads%2Frelease%2Fhelios%2FSR2%2Feclipse-cpp-helios-SR2-linux-gtk-x86_64.tar.gz\ncd eclipse\n./eclipse -application org.eclipse.equinox.p2.director -repository http://opensource.zylin.com/zylincdt -installIU com.zylin.cdt.feature.feature.group/\n```\n\nSee https://drive.google.com/drive/folders/1NseNHH05B6lmIXqQFVwK8xRjWE4ydeG-?usp=sharing to import a makefile project and create a debug configuration.\n\nNote that sometimes Eclipse needs to be restarted in order to be able to place new breakpoints.\n\nIf you want to get more information about how all this JTAG / GDB stuff work, you can find great blog about it here : \n\n\u003chttps://tomverbeure.github.io/2021/07/18/VexRiscv-OpenOCD-and-Traps.html\u003e\n\n## Briey SoC\nAs a demonstration, a SoC named Briey is implemented in `src/main/scala/vexriscv/demo/Briey.scala`. This SoC is very similar to\nthe [Pinsec SoC](https://spinalhdl.github.io/SpinalDoc-RTD/v1.3.1/SpinalHDL/Legacy/pinsec/hardware_toplevel.html):\n\n![Briey SoC](assets/brieySoc.png?raw=true \"\")\n\nTo generate the Briey SoC Hardware:\n\n```sh\nsbt \"runMain vexriscv.demo.Briey\"\n```\n\nTo run the verilator simulation of the Briey SoC, which can then be connected to OpenOCD/GDB, first get these dependencies:\n\n```sh\nsudo apt-get install build-essential xorg-dev libudev-dev libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libpulse-dev libopenal-dev libogg-dev libvorbis-dev libaudiofile-dev libpng12-dev libfreetype6-dev libusb-dev libdbus-1-dev zlib1g-dev libdirectfb-dev libsdl2-dev\n```\n\nThen go in `src/test/cpp/briey` and run the simulation with (UART TX is printed in the terminal, VGA is displayed in a GUI):\n\n```sh\nmake clean run\n```\n\nTo connect OpenOCD (https://github.com/SpinalHDL/openocd_riscv) to the simulation :\n\n```sh\nsrc/openocd -f tcl/interface/jtag_tcp.cfg -c \"set BRIEY_CPU0_YAML /home/spinalvm/Spinal/VexRiscv/cpu0.yaml\" -f tcl/target/briey.cfg\n```\nTo connect OpenOCD to Altera FPGAs (Intel VJTAG) see here: https://github.com/SpinalHDL/VexRiscv/tree/master/doc/vjtag\n\nYou can find multiple software examples and demos here: \u003chttps://github.com/SpinalHDL/VexRiscvSocSoftware/tree/master/projects/briey\u003e\n\nYou can find some FPGA projects which instantiate the Briey SoC here (DE1-SoC, DE0-Nano): https://drive.google.com/drive/folders/0B-CqLXDTaMbKZGdJZlZ5THAxRTQ?usp=sharing\n\n\nHere are some measurements of Briey SoC timings and area:\n\n```\nArtix 7     -\u003e 181 MHz 3220 LUT 3181 FF \nCyclone V   -\u003e 142 MHz 2,222 ALMs\nCyclone IV  -\u003e 130 MHz 4,538 LUT 3,211 FF \n```\n\n## Murax SoC\n\nMurax is a very light SoC (it fits in an ICE40 FPGA) which can work without any external components:\n- VexRiscv RV32I[M]\n- JTAG debugger (Eclipse/GDB/openocd ready)\n- 8 kB of on-chip ram\n- Interrupt support\n- APB bus for peripherals\n- 32 GPIO pin\n- one 16 bits prescaler, two 16 bits timers\n- one UART with tx/rx fifo\n\nDepending on the CPU configuration, on the ICE40-hx8k FPGA with icestorm for synthesis, the full SoC has the following area/performance:\n- RV32I interlocked stages =\u003e 51 MHz, 2387 LC 0.45 DMIPS/MHz\n- RV32I bypassed stages    =\u003e 45 MHz, 2718 LC 0.65 DMIPS/MHz\n\nIts implementation can be found here: `src/main/scala/vexriscv/demo/Murax.scala`.\n\nTo generate the Murax SoC Hardware:\n\n```sh\n# To generate the SoC without any content in the ram\nsbt \"runMain vexriscv.demo.Murax\"\n\n# To generate the SoC with a demo program already in ram\nsbt \"runMain vexriscv.demo.MuraxWithRamInit\"\n```\n\nThe demo program included by default with `MuraxWithRamInit` will blink the\nLEDs and echo characters received on the UART back to the user. To see this\nwhen running the Verilator sim, type some text and press enter.\n\nThen go in `src/test/cpp/murax` and run the simulation with:\n\n```sh\nmake clean run\n```\n\nTo connect OpenOCD (https://github.com/SpinalHDL/openocd_riscv) to the simulation:\n\n```sh\nsrc/openocd -f tcl/interface/jtag_tcp.cfg -c \"set MURAX_CPU0_YAML /home/spinalvm/Spinal/VexRiscv/cpu0.yaml\" -f tcl/target/murax.cfg\n```\n\nYou can find multiple software examples and demos here: https://github.com/SpinalHDL/VexRiscvSocSoftware/tree/master/projects/murax\n\nHere are some timing and area measurements of the Murax SoC:\n\n```\nMurax interlocked stages (0.45 DMIPS/MHz, 8 bits GPIO) -\u003e\n    Artix 7     -\u003e 216 MHz 1109 LUT 1201 FF \n    Cyclone V   -\u003e 182 MHz 725 ALMs\n    Cyclone IV  -\u003e 147 MHz 1,551 LUT 1,223 FF \n    iCE40       -\u003e  64 MHz 2422 LC (nextpnr)\n\nMuraxFast bypassed stages (0.65 DMIPS/MHz, 8 bits GPIO) -\u003e\n    Artix 7     -\u003e 224 MHz 1278 LUT 1300 FF \n    Cyclone V   -\u003e 173 MHz 867 ALMs\n    Cyclone IV  -\u003e 143 MHz 1,755 LUT 1,258 FF \n    iCE40       -\u003e  66 MHz 2799 LC (nextpnr)\n```\n\nSome scripts to generate the SoC and call the icestorm toolchain can be found here: `scripts/Murax/`\n\nA top level simulation testbench with the same features + a GUI are implemented with SpinalSim. You can find it in `src/test/scala/vexriscv/MuraxSim.scala`.\n\nTo run it :\n\n```sh\n# This will generate the Murax RTL + run its testbench. You need Verilator 3.9xx installated.\nsbt \"test:runMain vexriscv.MuraxSim\"\n```\n\n## Build all above with mill\n\nMill is a simple tool to build Scala/Java, also fits in off-line environment very well.\n\nGithub url is here: https://github.com/com-lihaoyi/mill\n\nDocument is here: https://mill-build.com/mill/Intro_to_Mill.html\n\nDownload executable mill: \n\n```sh\ncurl --fail -L -o mill https://github.com/com-lihaoyi/mill/releases/download/0.11.6/0.11.6-assembly\nchmod +x mill\n```\nUsing mill to generate the corresponding RTL as a `VexRiscv.v` file, run the following commands in the root directory of this repository:\n\n```sh\n./mill VexRiscv.runMain vexriscv.demo.GenFull\n```\nor\n\n```sh\n./mill VexRiscv.runMain vexriscv.demo.GenSmallest\n```\n\nUsing mill to run tests (need java, scala, verilator), do :\n\n```sh\nexport VEXRISCV_REGRESSION_SEED=42\nexport VEXRISCV_REGRESSION_TEST_ID=\n./mill VexRiscv.test.testOnly vexriscv.TestIndividualFeatures\n```\n\nUsing mill to generate the Briey SoC Hardware:\n\n```sh\n./mill VexRiscv.runMain vexriscv.demo.Briey\n```\n\nUsing mill to generate the Murax SoC Hardware:\n\n```sh\n# To generate the SoC without any content in the ram\n./mill VexRiscv.runMain vexriscv.demo.Murax\n\n# To generate the SoC with a demo program already in ram\n./mill VexRiscv.runMain vexriscv.demo.MuraxWithRamInit\n\n# This will generate the Murax RTL + run its testbench. You need Verilator 3.9xx installated.\n./mill VexRiscv.test.runMain vexriscv.MuraxSim\n```\n\nMill's IDE supports:\n\n```sh\n# Build Server Protocol (BSP)\n./mill mill.bsp.BSP/install\n\n# IntelliJ IDEA Support\n./mill mill.idea.GenIdea/idea\n```\n\n\n## Running Linux\n\nA default configuration is located in `src/main/scala/vexriscv/demo/Linux.scala`.\n\nThis file also contains \n- The commands to compile the buildroot image\n- How to run the Verilator simulation in interative mode\n\nThere is currently no SoC to run it on hardware, it is WIP. But the CPU simulation can already boot linux and run user space applications (even python).\n\nNote that VexRiscv can run Linux on both cache full and cache less design.\n\n## Build the RISC-V GCC\n\nA prebuild GCC toolsuite can be found here:\n\n- https://www.sifive.com/software/  =\u003e Prebuilt RISC‑V GCC Toolchain and Emulator\n\nThe VexRiscvSocSoftware makefiles are expecting to find a Sifive GCC toolchain in /opt/riscv/__contentOfThisPreBuild__ .\n\nYou can manualy download it via https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz\n\n```sh\n# Download and install the Sifive GCC toolchain\nversion=riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14\nwget -O riscv64-unknown-elf-gcc.tar.gz riscv https://static.dev.sifive.com/dev-tools/$version.tar.gz\ntar -xzvf riscv64-unknown-elf-gcc.tar.gz\nsudo mv $version /opt/riscv\necho 'export PATH=/opt/riscv/bin:$PATH' \u003e\u003e ~/.bashrc\n```\n\nIf you want to compile the rv32i and rv32im GCC toolchain from source code and install them in `/opt/`, do the following (will take one hour):\n\n```sh\n# Be carefull, sometime the git clone has issue to successfully clone riscv-gnu-toolchain.\nsudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev -y\n\ngit clone --recursive https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain\ncd riscv-gnu-toolchain\n\necho \"Starting RISC-V Toolchain build process\"\n\nARCH=rv32im\nrmdir -rf $ARCH\nmkdir $ARCH; cd $ARCH\n../configure  --prefix=/opt/$ARCH --with-arch=$ARCH --with-abi=ilp32\nsudo make -j4\ncd ..\n\n\nARCH=rv32i\nrmdir -rf $ARCH\nmkdir $ARCH; cd $ARCH\n../configure  --prefix=/opt/$ARCH --with-arch=$ARCH --with-abi=ilp32\nsudo make -j4\ncd ..\n\necho -e \"\\\\nRISC-V Toolchain installation completed!\"\n```\n\n## CPU parametrization and instantiation example\n\nYou can find many examples of different configurations in the https://github.com/SpinalHDL/VexRiscv/tree/master/src/main/scala/vexriscv/demo folder.\n\nHere is one such example:\n\n```scala\nimport vexriscv._\nimport vexriscv.plugin._\n\n//Instanciate one VexRiscv\nval cpu = new VexRiscv(\n  //Provide a configuration instance\n  config = VexRiscvConfig(\n    //Provide a list of plugins which will futher add their logic into the CPU\n    plugins = List(\n      new IBusSimplePlugin(\n        resetVector = 0x00000000l,\n        cmdForkOnSecondStage = true,\n        cmdForkPersistence  = true\n      ),\n      new DBusSimplePlugin(\n        catchAddressMisaligned = false,\n        catchAccessFault = false\n      ),\n      new DecoderSimplePlugin(\n        catchIllegalInstruction = false\n      ),\n      new RegFilePlugin(\n        regFileReadyKind = Plugin.SYNC,\n        zeroBoot = true\n      ),\n      new IntAluPlugin,\n      new SrcPlugin(\n        separatedAddSub = false,\n        executeInsertion = false\n      ),\n      new LightShifterPlugin,\n      new HazardSimplePlugin(\n        bypassExecute           = false,\n        bypassMemory            = false,\n        bypassWriteBack         = false,\n        bypassWriteBackBuffer   = false\n      ),\n      new BranchPlugin(\n        earlyBranch = false,\n        catchAddressMisaligned = false\n      ),\n      new YamlPlugin(\"cpu0.yaml\")\n    )\n  )\n)\n```\n\n## Add a custom instruction to the CPU via the plugin system\n\nHere is an example of a simple plugin which adds a simple SIMD_ADD instruction:\n\n```scala\nimport spinal.core._\nimport vexriscv.plugin.Plugin\nimport vexriscv.{Stageable, DecoderService, VexRiscv}\n\n//This plugin example will add a new instruction named SIMD_ADD which does the following:\n//\n//RD : Regfile Destination, RS : Regfile Source\n//RD( 7 downto  0) = RS1( 7 downto  0) + RS2( 7 downto  0)\n//RD(16 downto  8) = RS1(16 downto  8) + RS2(16 downto  8)\n//RD(23 downto 16) = RS1(23 downto 16) + RS2(23 downto 16)\n//RD(31 downto 24) = RS1(31 downto 24) + RS2(31 downto 24)\n//\n//Instruction encoding :\n//0000011----------000-----0110011\n//       |RS2||RS1|   |RD |\n//\n//Note :  RS1, RS2, RD positions follow the RISC-V spec and are common for all instruction of the ISA\n\nclass SimdAddPlugin extends Plugin[VexRiscv]{\n  //Define the concept of IS_SIMD_ADD signals, which specify if the current instruction is destined for this plugin\n  object IS_SIMD_ADD extends Stageable(Bool)\n\n  //Callback to setup the plugin and ask for different services\n  override def setup(pipeline: VexRiscv): Unit = {\n    import pipeline.config._\n\n    //Retrieve the DecoderService instance\n    val decoderService = pipeline.service(classOf[DecoderService])\n\n    //Specify the IS_SIMD_ADD default value when instructions are decoded\n    decoderService.addDefault(IS_SIMD_ADD, False)\n\n    //Specify the instruction decoding which should be applied when the instruction matches the 'key' parttern\n    decoderService.add(\n      //Bit pattern of the new SIMD_ADD instruction\n      key = M\"0000011----------000-----0110011\",\n\n      //Decoding specification when the 'key' pattern is recognized in the instruction\n      List(\n        IS_SIMD_ADD              -\u003e True,\n        REGFILE_WRITE_VALID      -\u003e True, //Enable the register file write\n        BYPASSABLE_EXECUTE_STAGE -\u003e True, //Notify the hazard management unit that the instruction result is already accessible in the EXECUTE stage (Bypass ready)\n        BYPASSABLE_MEMORY_STAGE  -\u003e True, //Same as above but for the memory stage\n        RS1_USE                  -\u003e True, //Notify the hazard management unit that this instruction uses the RS1 value\n        RS2_USE                  -\u003e True  //Same as above but for RS2.\n      )\n    )\n  }\n\n  override def build(pipeline: VexRiscv): Unit = {\n    import pipeline._\n    import pipeline.config._\n\n    //Add a new scope on the execute stage (used to give a name to signals)\n    execute plug new Area {\n      //Define some signals used internally by the plugin\n      val rs1 = execute.input(RS1).asUInt\n      //32 bits UInt value of the regfile[RS1]\n      val rs2 = execute.input(RS2).asUInt\n      val rd = UInt(32 bits)\n\n      //Do some computations\n      rd(7 downto 0) := rs1(7 downto 0) + rs2(7 downto 0)\n      rd(16 downto 8) := rs1(16 downto 8) + rs2(16 downto 8)\n      rd(23 downto 16) := rs1(23 downto 16) + rs2(23 downto 16)\n      rd(31 downto 24) := rs1(31 downto 24) + rs2(31 downto 24)\n\n      //When the instruction is a SIMD_ADD, write the result into the register file data path.\n      when(execute.input(IS_SIMD_ADD)) {\n        execute.output(REGFILE_WRITE_DATA) := rd.asBits\n      }\n    }\n  }\n}\n```\n\nIf you want to add this plugin to a given CPU, you just need to add it to its parameterized plugin list.\n\nThis example is a very simple one, but each plugin can really have access to the whole CPU:\n- Halt a given stage of the CPU\n- Unschedule instructions\n- Emit an exception\n- Introduce a new instruction decoding specification\n- Ask to jump the PC somewhere\n- Read signals published by other plugins\n- Override published signals values\n- Provide an alternative implementation\n- ...\n\nAs a demonstration, this SimdAddPlugin was integrated in the `src/main/scala/vexriscv/demo/GenCustomSimdAdd.scala` CPU configuration\nand is self-tested by the `src/test/cpp/custom/simd_add` application by running the following commands:\n\n```sh\n# Generate the CPU\nsbt \"runMain vexriscv.demo.GenCustomSimdAdd\"\n\ncd src/test/cpp/regression/\n\n# Optionally add TRACE=yes if you want to get the VCD waveform from the simulation.\n# Also you have to know that, by default, the testbench introduce instruction/data bus stall.\n# Note the CUSTOM_SIMD_ADD flag is set to yes.\nmake clean run IBUS=SIMPLE DBUS=SIMPLE CSR=no MMU=no DEBUG_PLUGIN=no MUL=no DIV=no DHRYSTONE=no REDO=2 CUSTOM_SIMD_ADD=yes\n```\n\nTo retrieve the plugin related signals in your waveform viewer, just filter with `simd`.\n\n## Adding a new CSR via the plugin system\n\nHere are two examples about how to add a custom CSR to the CPU via the plugin system:\nhttps://github.com/SpinalHDL/VexRiscv/blob/master/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala\n\nThe first one (`CustomCsrDemoPlugin`) adds an instruction counter and a clock cycle counter into the CSR mapping (and also do tricky stuff as a demonstration).\n\nThe second one (`CustomCsrDemoGpioPlugin`) creates a GPIO peripheral directly mapped into the CSR.\n\n## CPU clock and resets\n\nWithout the debug plugin, the CPU will have a standard `clk` input and a `reset` input. But with the debug plugin the situation is the following:\n\n- `clk`: as before, the clock which drives the whole CPU design, including the debug logic\n- `reset`: reset all the CPU states except the debug logic\n- `debugReset`: reset the debug logic of the CPU\n- `debug_resetOut`: a CPU output signal which allows the JTAG to reset the CPU + the memory interconnect + the peripherals\n\nSo here is the reset interconnect, in case you use the debug plugin:\n\n```\n                                VexRiscv\n                            +------------------+\n                            |                  |\ntoplevelReset \u003e----+--------\u003e debugReset       |\n                   |        |                  |\n                   |  +-----\u003c debug_resetOut   |\n                   |  |     |                  |\n                   +--or\u003e-+-\u003e reset            |\n                          | |                  |\n                          | +------------------+\n                          |\n                          +-\u003e Interconnect / Peripherals\n```\n\n\n## VexRiscv Architecture\n\nVexRiscv is implemented via a 5 stage in-order pipeline on which many optional and complementary plugins add functionalities to provide a functional RISC-V CPU.\nThis approach is completely unconventional and only possible through meta hardware description languages (SpinalHDL, in the current case) but has proven its advantages\nvia the VexRiscv implementation:\n\n- You can swap/turn on/turn off parts of the CPU directly via the plugin system\n- You can add new functionalities/instructions without having to modify any of the sources of the CPU\n- It allows the CPU configuration to cover a very large spectrum of implementations without cooking spaghetti code\n- It allows your codebase to truly produce a parametrized CPU design\n\nIf you generate the CPU without any plugin, it will only contain the definition of the 5 pipeline stages and their basic arbitration, but nothing else,\nand everything else, including the program counter is added into the CPU via plugins.\n\n### FPU\n\nFeatures : \n\n- Support IEEE 754 float and optionaly double\n- Implement Subnormal (few cycles lost in case of subnormal load/store)\n- Implement exceptions flags\n- The FPU can be shared between multiple CPU\n- Can be integrated inside or outside the CPU via the FpuPlugin\n- Fully pipelined, can produce one result per cycle for most operations (add,sub, mul, fma, load, store), as long there is no inter-dependancies\n- Implement multiplication using multiple sub multiplication operations in parallel (\"FPGA friendly\")\n- Division done with radix 4 (2 bits per cycle)\n- Square root done with radix 2 (1 bit per cycle)\n- Currently only compatible with the DBusCachedPlugin for load and store\n- 64 bits Load and store can be done in one cycle via the DBusCachedPlugin (even if VexRiscv is RV32)\n\nAccuracy, roundings (RNE, RTZ, RDN, RUP, RMM) and compliance: \n\n- Fully implemented excepted in the cases specified bellow\n- In FMA, the result of the multiplication is rounded before the addition (keep mantissa width + 2 bits)\n- A very special corner case of underflow flag do not follow IEEE 754 (rounding from subnormal to normal number)\n- Very specific, but SGNJ instruction will not mutate the value from/to F32/F64 (no NaN-boxing mutation)\n \n There is a diagram of the FPU design and its CPU integration : \n \n ![fpuDesign](assets/fpuDesign.png?raw=true \"\")\n \n The FPU can be parametrized with FpuParameter data structure : \n \n | Parameters | type | description |\n | ------ | ----------- | ------ |\n | withDouble   | Boolean | Enable 64 bits floating point (32 bits always enabled) |\n | asyncRegFile   | Boolean | Implement the register file using combinatorial reads (instead of syncronous reads) |\n | mulWidthA   | Boolean | Specify the width of the left operand of multiplication blocks |\n | mulWidthB   | Boolean | Same than above but the the right operand |\n\nSynthesis results of the FPU itself, without the CPU integration, on the fast speed grade : \n\n```\nFpu 32 bits -\u003e\n  Artix 7 relaxed -\u003e 135 MHz 1786 LUT 1778 FF \n  Artix 7 FMax    -\u003e 205 MHz 2101 LUT 1778 FF \nFpu 64/32 bits -\u003e\n  Artix 7 relaxed -\u003e 101 MHz 3336 LUT 3033 FF \n  Artix 7 FMax    -\u003e 165 MHz 3728 LUT 3175 FF \n```\n\nNote that if you want to debug FPU code via the openocd_riscv.vexriscv target, you need to use the GDB from : \n\nhttps://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6.tar.gz\n\nMore recent versions of gdb will not detect the FPU. Also, the openocd_riscv.vexriscv can't read CSR/FPU registers, so to have visibility on the floating points values, you need to compile your code in -O0, which will force values to be stored in memory (and so, be visible)\n\n### Plugins\n\nThis chapter describes the currently implemented plugins.\n\n- [IBusSimplePlugin](#ibussimpleplugin)\n- [IBusCachedPlugin](#ibuscachedplugin)\n- [DecoderSimplePlugin](#decodersimpleplugin)\n- [RegFilePlugin](#regfileplugin)\n- [HazardSimplePlugin](#hazardsimpleplugin)\n- [SrcPlugin](#srcplugin)\n- [IntAluPlugin](#intaluplugin)\n- [LightShifterPlugin](#lightshifterplugin)\n- [FullBarrelShifterPlugin](#fullbarrelshifterplugin)\n- [BranchPlugin](#branchplugin)\n- [DBusSimplePlugin](#dbussimpleplugin)\n- [DBusCachedPlugin](#dbuscachedplugin)\n- [MulPlugin](#mulplugin)\n- [DivPlugin](#divplugin)\n- [MulDivIterativePlugin](#muldiviterativeplugin)\n- [CsrPlugin](#csrplugin)\n- [StaticMemoryTranslatorPlugin](#staticmemorytranslatorplugin)\n- [MemoryTranslatorPlugin](#memorytranslatorplugin)\n- [DebugPlugin](#debugplugin)\n- [EmbeddedRiscvJtag](#embeddedRiscvJtag)\n- [YamlPlugin](#yamlplugin)\n- [FpuPlugin](#fpuplugin)\n\n\n#### IBusSimplePlugin\n\nThis plugin implements the CPU frontend (instruction fetch) via a very simple and neutral memory interface going outside the CPU.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| catchAccessFault | Boolean | When true, an instruction read response with read error asserted results in a CPU exception trap. |\n| resetVector | BigInt | Address of the program counter after the reset. |\n| cmdForkOnSecondStage | Boolean | When false, branches immediately update the program counter. This minimizes branch penalties but might reduce FMax because the instruction bus address signal is a combinatorial path. When true, this combinatorial path is removed and the program counter is updated one cycle after a branch is detected. While FMax may improve, an additional branch penalty will be incurred as well. |\n| cmdForkPersistence  | Boolean | When false, requests on the iBus can disappear/change before they are acknowledged. This reduces area but isn't safe/supported by many arbitration/slaves. When true, once initiated, iBus requests will stay until they are acknowledged. |\n| compressedGen | Boolean | Enable RISC-V compressed instruction (RVC) support. |\n| busLatencyMin | Int | Specifies the minimal latency between the iBus.cmd and iBus.rsp. A corresponding number of stages are added to the frontend to keep the IPC to 1.|\n| injectorStage | Boolean | When true, a stage between the frontend and the decode stage of the CPU is added to improve FMax. (busLatencyMin + injectorStage) should be at least two. |\n| prediction | BranchPrediction | Can be set to NONE/STATIC/DYNAMIC/DYNAMIC_TARGET to specify the branch predictor implementation. See below for more details. |\n| historyRamSizeLog2 | Int | Specify the number of entries in the direct mapped prediction cache of DYNAMIC/DYNAMIC_TARGET implementation. 2 pow historyRamSizeLog2 entries. |\n\nHere is the SimpleBus interface definition:\n\n```scala\ncase class IBusSimpleCmd() extends Bundle{\n  val pc = UInt(32 bits)\n}\n\ncase class IBusSimpleRsp() extends Bundle with IMasterSlave{\n  val error = Bool\n  val inst  = Bits(32 bits)\n\n  override def asMaster(): Unit = {\n    out(error,inst)\n  }\n}\n\ncase class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMasterSlave{\n  var cmd = Stream(IBusSimpleCmd())\n  var rsp = Flow(IBusSimpleRsp())\n\n  override def asMaster(): Unit = {\n    master(cmd)\n    slave(rsp)\n  }\n}\n```\n\n**Important** : check out the cmdForkPersistence parameter, because if it is not set, it can break the iBus compatibility with your memory system (unless you externaly add some buffers).\n\nSetting cmdForkPersistence and cmdForkOnSecondStage improves iBus cmd timings.\n\nThe iBusSimplePlugin includes bridges to convert from the IBusSimpleBus to AXI4, Avalon, and Wishbone interfaces.\n\nThis plugin implements a jump interface that allows all other plugins to issue a jump:\n\n```scala\ntrait JumpService{\n  def createJumpInterface(stage : Stage) : Flow[UInt]\n}\n```\n\nThe stage argument specifies the stage from which the jump is asked. This allows the PcManagerSimplePlugin plugin to manage priorities between jump requests from\ndiffent stages.\n\n#### IBusCachedPlugin\n\nSimple and light multi-way instruction cache.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| resetVector | BigInt | Address of the program counter after the reset. |\n| relaxedPcCalculation | Boolean | When false, branches immediately update the program counter. This minimizes branch penalties but might reduce FMax because the instruction bus address signal is a combinatorial path. When true, this combinatorial path is removed and the program counter is updated one cycle after a branch is detected. While FMax may improve, an additional branch penalty will be incurred as well. |\n| prediction | BranchPrediction | Can be set to NONE/STATIC/DYNAMIC/DYNAMIC_TARGET to specify the branch predictor implementation. See below for more details. |\n| historyRamSizeLog2 | Int | Specify the number of entries in the direct mapped prediction cache of DYNAMIC/DYNAMIC_TARGET implementation. 2 pow historyRamSizeLog2 entries |\n| compressedGen | Boolean | Enable RISC-V compressed instruction (RVC) support. |\n| config.cacheSize  | Int | Total storage capacity of the cache in bytes. |\n| config.bytePerLine  | Int | Number of bytes per cache line  |\n| config.wayCount  | Int | Number of cache ways |\n| config.twoCycleRam  | Boolean | Check the tags values in the decode stage instead of the fetch stage to relax timings |\n| config.asyncTagMemory  | Boolean | Read the cache tags in an asynchronous manner instead of syncronous one |\n| config.addressWidth  | Int | CPU address width. Should be 32 |\n| config.cpuDataWidth  | Int | CPU data width. Should be 32 |\n| config.memDataWidth  | Int | Memory data width. Could potentialy be something else than 32, but only 32 is currently tested |\n| config.catchIllegalAccess  | Boolean  | Catch when a memory access is done on non-valid memory address (MMU) |\n| config.catchAccessFault  | Boolean | Catch when the memeory bus is responding with an error  |\n| config.catchMemoryTranslationMiss  | Boolean  |  Catch when the MMU miss a TLB |\n\nNote: If you enable the twoCycleRam option and if wayCount is bigger than one, then the register file plugin should be configured to read the regFile in an asynchronous manner.\n\nThe memory bus is defined as :\n\n```scala\ncase class InstructionCacheMemCmd(p : InstructionCacheConfig) extends Bundle{\n  val address = UInt(p.addressWidth bit)\n  val size = UInt(log2Up(log2Up(p.bytePerLine) + 1) bits)\n}\n\ncase class InstructionCacheMemRsp(p : InstructionCacheConfig) extends Bundle{\n  val data = Bits(p.memDataWidth bit)\n  val error = Bool\n}\n\ncase class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle with IMasterSlave{\n  val cmd = Stream (InstructionCacheMemCmd(p))\n  val rsp = Flow (InstructionCacheMemRsp(p))\n\n  override def asMaster(): Unit = {\n    master(cmd)\n    slave(rsp)\n  }\n}\n```\n\nThe address is in byte and aligned to the bytePerLine config, the size will always be equal to log2(bytePerLine). \n\nNote that the cmd stream transaction need to be consumed before starting to send back some rsp transactions (1 cycle minimal latency)\n\nSome documentation about Stream here : \n\nhttps://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Libraries/stream.html?highlight=stream\n\nFlow are the same as Stream but without ready signal.\n\n\n#### DecoderSimplePlugin\n\nThis plugin provides instruction decoding capabilities to other plugins.\n\nFor instance, for a given instruction, the pipeline hazard plugin needs to know if it uses the register file source 1/2 in order to stall the pipeline until the hazard is gone.\nEach plugin that implements an instruction provides this kind of information to the DecoderSimplePlugin plugin.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| catchIllegalInstruction | Boolean | When true, instructions that don't match a decoding specification will generate a trap exception  |\n\nHere is a usage example:\n\n```scala\n    //Specify the instruction decoding which should be applied when the instruction matches the 'key' pattern\n    decoderService.add(\n      //Bit pattern of the new instruction\n      key = M\"0000011----------000-----0110011\",\n\n      //Decoding specification when the 'key' pattern is recognized in the instruction\n      List(\n        IS_SIMD_ADD              -\u003e True, //Inform the pipeline that the current instruction is a SIMD_ADD instruction\n        REGFILE_WRITE_VALID      -\u003e True, //Notify the hazard management unit that this instruction writes to the register file\n        BYPASSABLE_EXECUTE_STAGE -\u003e True, //Notify the hazard management unit that the instruction result is already accessible in the EXECUTE stage (Bypass ready)\n        BYPASSABLE_MEMORY_STAGE  -\u003e True, //Same as above but for the memory stage\n        RS1_USE                  -\u003e True, //Notify the hazard management unit that this instruction uses the RS1 value\n        RS2_USE                  -\u003e True  //Same than above but for RS2.\n      )\n    )\n  }\n```\n\nThis plugin operates in the Decode stage.\n\n#### RegFilePlugin\n\nThis plugin implements the register file.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| regFileReadyKind | RegFileReadKind | Can be set to ASYNC or SYNC. Specifies the kind of memory read used to implement the register file. ASYNC means zero cycle latency memory read, while SYNC means one cycle latency memory read which can be mapped into standard FPGA memory blocks   |\n| zeroBoot | Boolean | Load all registers with zeroes at the beginning of the simulation to keep everything deterministic in logs/traces|\n\nThis register file use a `don't care` read-during-write policy, so the bypassing/hazard plugin should take care of this.\n\nIf you get a `Missing inserts : INSTRUCTION_ANTICIPATE` error, that's because the RegFilePlugin is configured to use SYNC memory read ports to access the register file, but the IBus plugin configuration can't provide the instruction's register file read address one cycle before the decode stage. To workaround that you can :\n\n- Configure the RegFilePlugin to implement the register file read in a asyncronus manner (ASYNC), if your target device support such things\n- If you use the IBusSimplePlugin, you need to enable the injectorStage configuration\n- If you use the IBusCachedPlugin, you can either enable the injectorStage, or set twoCycleCache + twoCycleRam to false.\n\n#### HazardSimplePlugin\n\nThis plugin checks the pipeline instruction dependencies and, if necessary or possible, will stop the instruction in the decoding stage or bypass the instruction results\nfrom the later stages of the decode stage.\n\nSince the register file is implemented with a `don't care` read-during-write policy, this plugin also manages these kind of hazards.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| bypassExecute | Boolean | Enable the bypassing of instruction results coming from the Execute stage |\n| bypassMemory | Boolean | Enable the bypassing of instruction results coming from the Memory stage |\n| bypassWriteBack | Boolean | Enable the bypassing of instruction results coming from the WriteBack stage |\n| bypassWriteBackBuffer | Boolean | Enable the bypassing of the previous cycle register file written value  |\n\n#### SrcPlugin\n\nThis plugin muxes different input values to produce SRC1/SRC2/SRC_ADD/SRC_SUB/SRC_LESS values which are common values used by many plugins in the execute stage (ALU/Branch/Load/Store).\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| separatedAddSub | RegFileReadKind | By default SRC_ADD/SRC_SUB are generated from a single controllable adder/substractor, but if this is set to true, it use separate adder/substractors |\n| executeInsertion | Boolean | By default SRC1/SRC2 are generated in the Decode stage, but if this parameter is true, it is done in the Execute stage (It will relax the bypassing network) |\n\nExcept for SRC1/SRC2, this plugin does everything at the begining of Execute stage.\n\n#### IntAluPlugin\n\nThis plugin implements all ADD/SUB/SLT/SLTU/XOR/OR/AND/LUI/AUIPC instructions in the execute stage by using the SrcPlugin outputs. It is a really simple plugin.\n\nThe result is injected into the pipeline directly at the end of the execute stage.\n\n#### LightShifterPlugin\n\nImplements SLL/SRL/SRA instructions by using an iterative shifter register, while using one cycle per bit shift.\n\nThe result is injected into the pipeline directly at the end of the execute stage.\n\n#### FullBarrelShifterPlugin\n\nImplements SLL/SRL/SRA instructions by using a full barrel shifter, so it executes all shifts in a single cycle.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| earlyInjection | Boolean | By default the result of the shift is injected into the pipeline in the Memory stage to relax timings, but if this option is true it will be done in the Execute stage |\n\n#### BranchPlugin\n\nThis plugin implements all branch/jump instructions (JAL/JALR/BEQ/BNE/BLT/BGE/BLTU/BGEU) with primitives used by the cpu frontend plugins to implement branch prediction. The prediction implementation is set in the frontend plugins (IBusX).\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| earlyBranch | Boolean | By default the branch is done in the Memory stage to relax timings, but if this option is set it's done in the Execute stage|\n| catchAddressMisaligned | Boolean | If a jump/branch is done in an unaligned PC address, it will fire an trap exception |\n\nEach miss predicted jumps will produce between 2 and 4 cycles penalty depending the `earlyBranch` and the `PcManagerSimplePlugin.relaxedPcCalculation` configurations\n\n##### Prediction NONE\n\nNo prediction: each PC change due to a jump/branch will produce a penalty.\n\n##### Prediction STATIC\n\nIn the decode stage, a conditional branch pointing backwards or a JAL is branched speculatively. If the speculation is right, the branch penalty is reduced to a single cycle,\notherwise the standard penalty is applied.\n\n##### Prediction DYNAMIC\n\nSame as the STATIC prediction, except that to do the prediction, it uses a direct mapped 2 bit history cache (BHT) which remembers if the branch is more likely to be taken or not.\n\n##### Prediction DYNAMIC_TARGET\n\nThis predictor uses a direct mapped branch target buffer (BTB) in the Fetch stage which stores the PC of the instruction, the target PC of the instruction and a 2 bit history to remember\nif the branch is more likely to be taken or not. This is actually the most efficient branch predictor implemented on VexRiscv, because when the branch prediction is right, it produces no branch penalty.\nThe downside is that this predictor has a long combinatorial path coming from the prediction cache read port to the programm counter, passing through the jump interface.\n\n#### DBusSimplePlugin\n\nThis plugin implements the load and store instructions (LB/LH/LW/LBU/LHU/LWU/SB/SH/SW) via a simple memory bus going out of the CPU.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| catchAddressMisaligned | Boolean | If a memory access is done to an unaligned memory address, it will fire a trap exception |\n| catchAccessFault | Boolean | If a memory read returns an error, it will fire a trap exception  |\n| earlyInjection | Boolean | By default, the memory read values are injected into the pipeline in the WriteBack stage to relax the timings. If this parameter is true, it's done in the Memory stage |\n\nHere is the DBusSimpleBus\n\n```scala\ncase class DBusSimpleCmd() extends Bundle{\n  val wr = Bool\n  val address = UInt(32 bits)\n  val data = Bits(32 bit)\n  val size = UInt(2 bit)\n}\n\ncase class DBusSimpleRsp() extends Bundle with IMasterSlave{\n  val ready = Bool\n  val error = Bool\n  val data = Bits(32 bit)\n\n  override def asMaster(): Unit = {\n    out(ready,error,data)\n  }\n}\n\n\ncase class DBusSimpleBus() extends Bundle with IMasterSlave{\n  val cmd = Stream(DBusSimpleCmd())\n  val rsp = DBusSimpleRsp()\n\n  override def asMaster(): Unit = {\n    master(cmd)\n    slave(rsp)\n  }\n}\n```\n\nNote that there are bridges available that can convert this interface into AXI4 and Avalon.\n\nThere is at least one cycle latency between a cmd and the corresponding rsp. The rsp.ready flag should be false after a read cmd until the rsp is present.\n\n#### DBusCachedPlugin\n\nMulti way cache implementation with writh-through and allocate on read strategy. (Documentation is WIP)\n\nYou can invalidate the whole cache via the 0x500F instruction, and you can invalidate a address range (single line size) via the instruction 0x500F | RS1 \u003c\u003c 15 where RS1 should not be X0 and point to one byte of the desired address to invalidate.\n\n\nThe memory bus is defined as :\n\n```scala\ncase class DataCacheMemCmd(p : DataCacheConfig) extends Bundle{\n  val wr = Bool\n  val uncached = Bool\n  val address = UInt(p.addressWidth bit)\n  val data = Bits(p.cpuDataWidth bits)\n  val mask = Bits(p.cpuDataWidth/8 bits)\n  val size   = UInt(p.sizeWidth bits) //... 1 =\u003e 2 bytes ... 2 =\u003e 4 bytes ...\n  val exclusive = p.withExclusive generate Bool()\n  val last = Bool\n}\ncase class DataCacheMemRsp(p : DataCacheConfig) extends Bundle{\n  val aggregated = UInt(p.aggregationWidth bits)\n  val last = Bool()\n  val data = Bits(p.memDataWidth bit)\n  val error = Bool\n  val exclusive = p.withExclusive generate Bool()\n}\ncase class DataCacheInv(p : DataCacheConfig) extends Bundle{\n  val enable = Bool()\n  val address = UInt(p.addressWidth bit)\n}\ncase class DataCacheAck(p : DataCacheConfig) extends Bundle{\n  val hit = Bool()\n}\n\ncase class DataCacheSync(p : DataCacheConfig) extends Bundle{\n  val aggregated = UInt(p.aggregationWidth bits)\n}\n\ncase class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{\n  val cmd = Stream (DataCacheMemCmd(p))\n  val rsp = Flow (DataCacheMemRsp(p))\n\n  val inv = p.withInvalidate generate Stream(Fragment(DataCacheInv(p)))\n  val ack = p.withInvalidate generate Stream(Fragment(DataCacheAck(p)))\n  val sync = p.withInvalidate generate Stream(DataCacheSync(p))\n\n  override def asMaster(): Unit = {\n    master(cmd)\n    slave(rsp)\n\n    if(p.withInvalidate) {\n      slave(inv)\n      master(ack)\n      slave(sync)\n    }\n  }\n}\n```\n\nIf you don't use memory coherency you can ignore the inv/ack/sync streams, also write cmd should not generate any rsp transaction.\n\nAs the cache is write through, there is no write burst but only individual write transactions.\n\nThe address is in byte and aligned to the bytePerLine config, the size will is encoded as log2(number of bytes in the burst). \nlast should be set only on the last transaction of a burst.\n\nNote that the cmd stream transaction need to be consumed before starting to send back some rsp transactions (1 cycle minimal latency)\n\nSome documentation about Stream here : \n\nhttps://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Libraries/stream.html?highlight=stream\n\nFlow are the same as Stream but without ready signal.\n\n#### MulPlugin\n\nImplements the multiplication instruction from the RISC-V M extension. Its implementation was done in a FPGA friendly way by using 4 17*17 bit multiplications.\nThe processing is fully pipelined between the Execute/Memory/Writeback stage. The results of the instructions are always inserted in the WriteBack stage.\n\n#### DivPlugin\n\nImplements the division/modulo instruction from the RISC-V M extension. It is done in a simple iterative way which always takes 34 cycles. The result is inserted into the\nMemory stage.\n\nThis plugin is now based on MulDivIterativePlugin.\n\n#### MulDivIterativePlugin\n\nThis plugin implements the multiplication, division and modulo of the RISC-V M extension in an iterative way, which is friendly for small FPGAs that don't have DSP blocks.\n\nThis plugin is able to unroll the iterative calculation process to reduce the number of cycles used to execute mul/div instructions.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| genMul    | Boolean | Enables multiplication support. Can be set to false if you want to use the MulPlugin instead |\n| genDiv    | Boolean |  Enables division support |\n| mulUnrollFactor    | Int | Number of combinatorial stages used to speed up the multiplication, should be \u003e 0 |\n| divUnrollFactor    | Int | Number of combinatorial stages used to speed up the division, should be \u003e 0 |\n\nThe number of cycles used to execute a multiplication is '32/mulUnrollFactor'\nThe number of cycles used to execute a division is '32/divUnrollFactor + 1'\n\nBoth mul/div are processed in the memory stage (late result).\n\n#### CsrPlugin\n\nImplements most of the Machine mode and a few of the User mode registers, as specified in the RISC-V priviledged spec.\nThe access mode of most of the CSR is parameterizable to reduce the area usage of unneeded features.\n\n(CsrAccess can be `NONE/READ_ONLY/WRITE_ONLY/READ_WRITE`)\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| catchIllegalAccess   | Boolean |  |\n| mvendorid            | BigInt |  |\n| marchid              | BigInt |  |\n| mimpid               | BigInt |  |\n| mhartid              | BigInt |  |\n| misaExtensionsInit   | Int |  |\n| misaAccess           | CsrAccess |  |\n| mtvecAccess          | CsrAccess |  |\n| mtvecInit            | BigInt |  |\n| mepcAccess           | CsrAccess |  |\n| mscratchGen          | Boolean |  |\n| mcauseAccess         | CsrAccess |  |\n| mbadaddrAccess       | CsrAccess |  |\n| mcycleAccess         | CsrAccess |  |\n| minstretAccess       | CsrAccess |  |\n| ucycleAccess         | CsrAccess |  |\n| wfiGen               | Boolean |  |\n| ecallGen             | Boolean |  |\n\nIf an interrupt occurs, before jumping to mtvec, the plugin will stop the Prefetch stage and wait for all the instructions in the later pipeline stages to complete their execution.\n\nIf an exception occur, the plugin will kill the corresponding instruction, flush all previous instructions, and wait until the previously killed instructions reach the WriteBack\nstage before jumping to mtvec.\n\n#### StaticMemoryTranslatorPlugin\n\nStatic memory translator plugin which allows to specify which range of the memory addresses is I/O mapped and shouldn't be cached.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| ioRange   | UInt =\u003e Bool | Function reference which eat an address and return true if the address should be uncached. ex : ioRange= _(31 downto 28) === 0xF =\u003e all 0xFXXXXXXX will be uncached|\n\n\n#### MmuPlugin\n\nHardware refilled MMU implementation. Allows other plugins such as DBusCachedPlugin/IBusCachedPlugin to instanciate memory address translation ports. Each port has a small dedicated\nfully associative TLB cache which is refilled automaticaly via a dbus access sharing.\n\n#### PmpPlugin\n\nThis is a physical memory protection (PMP) plugin which conforms to the v1.12 RISC-V privilege specification, without ePMP (`Smepmp`) extension support. PMP is configured by writing two special CSRs: `pmpcfg#` and `pmpaddr#`. The former contains the permissions and addressing modes for four protection regions, and the latter contains the encoded start address for a single region. Since the actual region bounds must be computed from the values written to these registers, writing them takes a few CPU cylces. This delay is necessary in order to centralize all of the decoding logic into a single component. Otherwise, it would have to be duplicated for each region, even though the decoding operation happens only when PMP is reprogrammed (e.g., on some context switches).\n\n##### PmpPluginNapot\n\nThe `PmpPluginNapot` is a specialized PMP implementation, providing only the `NAPOT` (naturally-aligned poser-of-2 regions) addressing mode. It requires fewer resources and has a less significant timing impact compared to the full `PmpPlugin`.\n\n#### DebugPlugin\n\nThis plugin implements enough CPU debug features to allow comfortable GDB/Eclipse debugging. To access those debug features, it provides a simple memory bus interface.\nThe JTAG interface is provided by another bridge, which makes it possible to efficiently connect multiple CPUs to the same JTAG.\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| debugClockDomain   | ClockDomain | As the debug unit is able to reset the CPU itself, it should use another clock domain to avoid killing itself (only the reset wire should differ) |\n\nThe internals of the debug plugin are done in a manner which reduces the area usage and the FMax impact of this plugin.\n\nHere is the simple bus to access it, the rsp comes one cycle after the request:\n\n```scala\ncase class DebugExtensionCmd() extends Bundle{\n  val wr = Bool\n  val address = UInt(8 bit)\n  val data = Bits(32 bit)\n}\ncase class DebugExtensionRsp() extends Bundle{\n  val data = Bits(32 bit)\n}\n\ncase class DebugExtensionBus() extends Bundle with IMasterSlave{\n  val cmd = Stream(DebugExtensionCmd())\n  val rsp = DebugExtensionRsp()\n\n  override def asMaster(): Unit = {\n    master(cmd)\n    in(rsp)\n  }\n}\n```\n\n\nHere is the register mapping:\n\n```\nRead address 0x00 -\u003e\n  bit 0  : resetIt\n  bit 1  : haltIt\n  bit 2  : isPipBusy\n  bit 3  : haltedByBreak\n  bit 4  : stepIt\nWrite address 0x00 -\u003e\n  bit 4  : stepIt\n  bit 16 : set resetIt\n  bit 17 : set haltIt\n  bit 24 : clear resetIt\n  bit 25 : clear haltIt and haltedByBreak\n\nRead Address 0x04 -\u003e\n  bits (31 downto 0) : Last value written into the register file\nWrite Address 0x04 -\u003e\n  bits (31 downto 0) : Instruction that should be pushed into the CPU pipeline for debug purposes\n```\n\nThe OpenOCD port is here: \u003chttps://github.com/SpinalHDL/openocd_riscv\u003e\n\n#### EmbeddedRiscvJtag\n\nVexRiscv also support the official RISC-V debug specification (Thanks Efinix for the funding !).\n\nTo enable it, you need to add the EmbeddedRiscvJtag to the plugin list : \n\n```scala\nnew EmbeddedRiscvJtag(\n  p = DebugTransportModuleParameter(\n    addressWidth = 7,\n    version      = 1,\n    idle         = 7\n  ),\n  withTunneling = false,\n  withTap = true\n)\n```\n\nAnd turn on the withPrivilegedDebug option in the CsrPlugin config.\n\nHere is an example of openocd tcl script to connect : \n\n```tcl\n# ADD HERE YOUR JTAG ADAPTER SETTINGS\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10002FFF\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n\ninit\nhalt\n```\n\nA full example can be found in GenFullWithOfficialRiscvDebug.scala\n\n##### Tunneled JTAG\n\nThe EmbeddedRiscvJtag plugin can also be used with tunneled JTAG. This allows debugging with the same cable used to configure an FPGA.\n\nThis uses an FPGA-specific primitive for JTAG access (e.g. Xilinx BSCANE2):\n```scala\nval xilJtag = BSCANE2(userId = 4) // must be userId = 4\nval jtagClockDomain = ClockDomain(\n  clock = xilJtag.TCK\n)\n```\n\nThen, the EmbeddedRiscvJtag plugin must be configured for tunneling without a TAP. Note, the debug clock domain must have a separate reset from the CPU clock domain.\n\n```scala\n// in plugins\nnew EmbeddedRiscvJtag(\n  p = DebugTransportModuleParameter(\n    addressWidth = 7,\n    version      = 1,\n    idle         = 7\n  ),\n  withTunneling = true,\n  withTap = false,\n  debugCd = debugClockDomain,\n  jtagCd = jtagClockDomain\n)\n```\n\nThen connect the EmbeddedRiscvJtag to the FPGA-specific JTAG primitive:\n\n```scala\nfor (plugin \u003c- cpuConfig.plugins) plugin match {\n  case plugin: EmbeddedRiscvJtag =\u003e {\n    plugin.jtagInstruction \u003c\u003e xilJtag.toJtagTapInstructionCtrl()\n  }\n  case _ =\u003e\n}\n```\n\nHere is an example OpenOCD TCL script to connect on a Xilinx 7-Series FPGA: \n\n```tcl\n# ADD HERE YOUR JTAG ADAPTER SETTINGS\n\nsource [find cpld/xilinx-xc7.cfg]\nset TAP_NAME xc7.tap\n\nset _TARGETNAME cpu\ntarget create $_TARGETNAME.0 riscv -chain-position $TAP_NAME\nriscv use_bscan_tunnel 6 1\n\ninit\nhalt\n```\n\n#### YamlPlugin\n\nThis plugin offers a service to other plugins to generate a useful Yaml file describing the CPU configuration. It contains, for instance, the sequence of instructions required\nto flush the data cache (information used by openocd).\n\n\n#### FpuPlugin\n\nAllow the integration of a internal or a external FPU into VexRiscv (See the FPU chapter)\n\n| Parameters | type | description |\n| ------ | ----------- | ------ |\n| externalFpu   | Boolean | When false the FPU is instanciated in Vex, else the plugin has a `port` interface to which you can connect an external FPU |\n| p   | FpuParameter | Parameter with which the connected FPU will be created |\n\n#### AesPlugin\n\nThis plugin allow to accelerate AES encryption/decryption by using an internal ROM to solve SBOX and permutations, allowing in practice to execute one AES round in about 21 cycles.\n\nFor more documentation, check src/main/scala/vexriscv/plugin/AesPlugin.scala, a software C driver can be found here : \u003chttps://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/software/standalone/driver/aes_custom.h\u003e\n\nIt was also ported on libressl via the following patch :\n\u003chttps://github.com/SpinalHDL/buildroot-spinal-saxon/blob/main/patches/libressl/0000-vexriscv-aes.patch\u003e\n\nSpeed up of 4 was observed in libressl running in linux. \u003chttps://github.com/SpinalHDL/SaxonSoc/pull/53#issuecomment-730133020\u003e\n","funding_links":[],"categories":["Projects and IPs","Opensource ядра на базе RISC-V","Assembly","Cores","CPU RISC-V","Open Source implementations","Applications","Open Source Core Implementations","CPU"],"sub_categories":["Information Technology","Industry","网络服务_其他"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSpinalHDL%2FVexRiscv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSpinalHDL%2FVexRiscv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSpinalHDL%2FVexRiscv/lists"}