From 841194b851b6c07878bbd3e0d8470aaff4c1f329 Mon Sep 17 00:00:00 2001 From: Juan Sapriza Date: Mon, 16 Oct 2023 10:18:38 +0200 Subject: [PATCH] Updated the initial readme to point to read the docs --- README.md | 548 +----------------------- docs/logo/x-heep-outline.png | Bin 0 -> 42485 bytes {logo => docs/logo}/x-heep.png | Bin docs/source/old_documentation/README.md | 513 ++++++++++++++++++++++ 4 files changed, 535 insertions(+), 526 deletions(-) create mode 100644 docs/logo/x-heep-outline.png rename {logo => docs/logo}/x-heep.png (100%) create mode 100644 docs/source/old_documentation/README.md diff --git a/README.md b/README.md index e63003cfc..0c825a11a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ +
+

+ +`X-HEEP` (eXtendable Heterogeneous Energy-Efficient Platform) is a `RISC-V` microcontroller described in `SystemVerilog` +that can be configured to target small and tiny platforms as well as extended to support accelerators. +The cool thing about `X-HEEP` is that we provide a simple customizable MCU, so CPUs, common peripherals, memories, etc. +so that you can extend it with your own accelerator without modifying the MCU, but just instantiating it in your design. +By doing so, you inherit an IP capable of booting RTOS (such as `freeRTOS`) with the whole FW stack, including `HAL` drivers and `SDK`, +and you can focus on building your special HW supported by the microcontroller. + +`X-HEEP` supports simulation with Verilator, Questasim, etc. Morever, FW can be built and linked by using `CMake` either with gcc or with clang. It can be implemented on FPGA, and it supports implementation in Silicon, which is its main (but not only) target. See below for more details. + +The block diagram below shows the `X-HEEP` MCU + +

+ + +> :bookmark_tabs: Please refer to the documentation in [Read the Docs](https://x-heep.readthedocs.io/en/latest/index.html) + +The original `README` is still available in `docs/source/old_documentation/READAME.md`. + # Repository folder structure . @@ -21,529 +42,4 @@ │ └── vendor ├── tb ├── util - └── README.md - -
-

- -`X-HEEP` (eXtendable Heterogeneous Energy-Efficient Platform) is a `RISC-V` microcontroller described in `SystemVerilog` -that can be configured to target small and tiny platforms as well as extended to support accelerators. -The cool thing about `X-HEEP` is that we provide a simple customizable MCU, so CPUs, common peripherals, memories, etc. -so that you can extend it with your own accelerator without modifying the MCU, but just instantiating it in your design. -By doing so, you inherit an IP capable of booting RTOS (such as `freeRTOS`) with the whole FW stack, including `HAL` drivers and `SDK`, -and you can focus on building your special HW supported by the microcontroller. - -`X-HEEP` supports simulation with Verilator, Questasim, etc. Morever, FW can be built and linked by using `CMake` either with gcc or with clang. It can be implemented on FPGA, and it supports implementation in Silicon, which is its main (but not only) target. See below for more details. - -The block diagram below shows the `X-HEEP` MCU - -

- -# Self-documented Makefile - -Note that under `util` folder, the file `generate-makefile-help` is employed to generate a self-documented helping output. In case of including any other target or command under the main `Makefile`, follow the same general and parameter descriptions as already provided for every target. Check the `help` output by doing `make` or `make help`. Moreover, **note that some of the parameters required for some of the targets are initiated with _default values_** - -# Prerequisite - -## 1. OS requirements - -To use `X-HEEP`, first make sure you have the following apt packages, or install them as: - -```bash -sudo apt install lcov libelf1 libelf-dev libftdi1-2 libftdi1-dev libncurses5 libssl-dev libudev-dev libusb-1.0-0 lsb-release texinfo autoconf cmake flex bison libexpat-dev gawk tree xterm python3-venv python3-dev -``` - -In general, have a look at the [Install required software](https://opentitan.org/guides/getting_started/index.html) section of the OpenTitan documentation. - -It has been tested only on `Ubuntu 20`, and we know it does NOT WORK on `Ubuntu 22`. - -## 2. Python - - -We rely on either (a) `miniconda`, or (b) `virtual environment` enviroment. - -Choose between `2.a` or `2.b` to setup your enviroment. - -### 2.a Miniconda - -Install [Miniconda](https://docs.conda.io/en/latest/miniconda.html#linux-installers) python 3.8 version as described in the link, -and create the Conda enviroment: - -```bash -make conda -``` - -You need to do it only the first time, then just activate the environment everytime you work with `X-HEEP` as - -```bash -conda activate core-v-mini-mcu -``` - - -### 2.b Virtual Environment - -Install the python virtual environment just as: - -```bash -make venv -``` - -You need to do it only the first time, then just activate the environment everytime you work with `X-HEEP` as - -```bash -source .venv/bin/activate -``` - -## 3. Install the RISC-V Compiler: - -``` -git clone --branch 2022.01.17 --recursive https://github.com/riscv/riscv-gnu-toolchain -cd riscv-gnu-toolchain -./configure --prefix=/home/$USER/tools/riscv --with-abi=ilp32 --with-arch=rv32imc --with-cmodel=medlow -make -``` - -Then, set the `RISCV` env variable as: - -``` -export RISCV=/home/$USER/tools/riscv -``` - -Optionally you can also compile with clang/LLVM instead of gcc. For that you must install the clang compiler into the same `RISCV` path. The binaries of gcc and clang do not collide so you can have both residing in the same `RISCV` directory. For this you can set the `-DCMAKE_INSTALL_PREFIX` cmake variable to `$RISCV` when building LLVM. This can be accomplished by doing the following: - -``` -git clone https://github.com/llvm/llvm-project.git -cd llvm-project -git checkout llvmorg-14.0.0 -mkdir build && cd build -cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$RISCV -DLLVM_TARGETS_TO_BUILD="RISCV" ../llvm -cmake --build . --target install -``` - -## 4. Install Verilator: - -``` -export VERILATOR_VERSION=4.210 - -git clone https://github.com/verilator/verilator.git -cd verilator -git checkout v$VERILATOR_VERSION - -autoconf -./configure --prefix=/home/$USER/tools/verilator/$VERILATOR_VERSION -make -make install -``` -Then, set the `PATH` env variable to as: - -``` -export PATH=/home/$USER/tools/verilator/$VERILATOR_VERSION/bin:$PATH -``` - -In general, have a look at the [Install Verilator](https://opentitan.org/guides/getting_started/setup_verilator.html) section of the OpenTitan documentation. - -If you want to see the vcd waveforms generated by the Verilator simulation, install GTKWAVE: - -``` -sudo apt install libcanberra-gtk-module libcanberra-gtk3-module -sudo apt-get install -y gtkwave -``` - -## Files are formatted with Verible - -We use version v0.0-1824-ga3b5bedf - -See: [Install Verible](https://opentitan.org/guides/getting_started/index.html#step-6a-install-verible-optional) - -To format your RTL code type: - -``` -make verible -``` -## Compilation Flow and Package Manager - -We use [FuseSoC](https://github.com/olofk/fusesoc) for all the tools we use. - -The `fusesoc` commands are inside the Makefile. - -# Adding external IPs - -This repository relies on [Vendor](https://opentitan.org/book/util/doc/vendor.html) to add new IPs. The `vendor.py` script in the [`./util`](./util/) folder implements what is describeb above, while [this](./ExternalDevices.md) file contains additional information on how to connect external devices to the system. - -# Compiling with Makefile - -You can compile the example applications and the platform using the Makefile. Type 'make help' or 'make' for more information. Moreover, please, check the different 'clean' commands to verify that you are using the corret one. - -## Generate core-v-mini-mcu package - -First, you have to generate the SystemVerilog package and C header file of the core-v-mini-mcu: - -``` -make mcu-gen -``` - -By default, `X-HEEP` deploys the [cv32e20](https://github.com/openhwgroup/cve2) RISC-V CPU. -Other supported CPUs are: the [cv32e40p](https://github.com/openhwgroup/cv32e40p), [cv32e40x](https://github.com/openhwgroup/cv32e40x), and the [cv32e40px](https://github.com/esl-epfl/cv32e40px). -The default bus type of `X-HEEP` is a single-master-at-a-time architecture, (called `onetoM`), but the cross-bar architecture is also supported by setting -the bus to `NtoM`. Also, the user can select the number of 32kB banks addressed in continuous mode and/or the interleaved mode. -By default, `X-HEEP` is generated with 2 continuous banks and 0 interleaved banks. - -Below an example that changes the default configuration: - -``` -make mcu-gen CPU=cv32e40p BUS=NtoM MEMORY_BANKS=12 MEMORY_BANKS_IL=4 -``` - -The last command generates x-heep with the cv32e40p core, with a parallel bus, and 16 memory banks (12 continuous and 4 interleaved), -each 32KB, for a total memory of 512KB. - -If you are using `X-HEEP` just as a controller for your own system and you do not need any peripheral, you can use the `minimal` configuration file -when generating the MCU as: - -``` -make mcu-gen MCU_CFG=mcu_cfg_minimal.hjson -``` - -The `minimal` configuration is a work-in-progress, thus not all the APPs have been tested. - - -## Compiling Software - -Don't forget to set the `RISCV` env variable to the compiler folder (without the `/bin` included). -To run 'hello world' application, just type 'make app'. - -``` -make app -``` - -To run any other application, please use the following command with appropiate parameters: - -``` -app PROJECT= TARGET=sim(default),pynq-z2 LINKER=on_chip(default),flash_load,flash_exec COMPILER=gcc(default),clang COMPILER_PREFIX=riscv32-unknown-(default) ARCH=rv32imc(default), - -Params: -- PROJECT (ex: , hello_world(default)) -- TARGET (ex: sim(default),pynq-z2) -- LINKER (ex: on_chip(default),flash_load,flash_exec) -- COMPILER (ex: gcc(default),clang) -- COMPILER_PREFIX (ex: riscv32-unknown-(default)) -- ARCH (ex: rv32imc(default),) -``` - -For instance, to run 'hello world' app for the pynq-z2 FPGA targets, just run: - -``` -make app TARGET=pynq-z2 -``` - -Or, if you use the OpenHW Group [GCC](https://www.embecosm.com/resources/tool-chain-downloads/#corev) compiler with CORE_PULP extensions, make sure to point the `RISCV` env variable to the OpenHW Group compiler, then just run: - - -``` -make app COMPILER_PREFIX=riscv32-corev- ARCH=rv32imc_zicsr_zifencei_xcvhwlp1p0_xcvmem1p0_xcvmac1p0_xcvbi1p0_xcvalu1p0_xcvsimd1p0_xcvbitmanip1p0 -``` - -This will create the executable file to be loaded into your target system (ASIC, FPGA, Simulation). -Remember that, `X-HEEP` is using CMake to compile and link. Thus, the generated files after having -compiled and linked are under `sw\build` - -Alternatively, in case you are doing pure FW development and you are used to developing using Integrated Development Evironments (IDEs), please check [the IDE readme](./IDEs.md). - -## FreeROTS based applications - -'X-HEEP' supports 'FreeRTOS' based applications. Please see `sw\applications\blinky_freertos`. - -After that, you can run the command to compile and link the FreeRTOS based application. Please also set 'LINKER' and 'TARGET' parameters if needed. - -``` -make app PROJECT=blinky_freertos -``` - -The main FreeRTOS configuration is allocated under `sw\freertos`, in `FreeRTOSConfig.h`. Please, change this file based on your application requirements. -Moreover, FreeRTOS is being fetch from 'https://github.com/FreeRTOS/FreeRTOS-Kernel.git' by CMake. Specifically, 'V10.5.1' is used. Finally, the fetch repository is located under `sw\build\_deps` after building. - -## Simulating - -This project supports simulation with Verilator, Synopsys VCS, and Siemens Questasim. -It relies on `fusesoc` to handle multiple EDA tools and parameters. -For example, if you want to set the `FPU` and `COREV_PULP` parameters of the `cv32e40p` CPU, -you need to add next to your compilation command `FUSESOC_PARAM="--COREV_PULP=1 --FPU=1"` -Below the different EDA examples commands. - -### Compiling for Verilator - -To simulate your application with Verilator, first compile the HDL: - -``` -make verilator-sim -``` - -then, go to your target system built folder - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-verilator -``` - -and type to run your compiled software: - -``` -./Vtestharness +firmware=../../../sw/build/main.hex -``` - -or to execute all these three steps type: - -``` -make run-helloworld -``` - - -### Compiling for VCS - -To simulate your application with VCS, first compile the HDL: - -``` -make vcs-sim -``` - -then, go to your target system built folder - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-vcs -``` - -and type to run your compiled software: - -``` -./openhwgroup.org_systems_core-v-mini-mcu_0 +firmware=../../../sw/build/main.hex -``` - -Waveforms can be viewed with Verdi. Make sure you have the env variable `VERDI_HOME` set to your Verdi install folder, then run your compiled software as above, but with the `-gui` flag: - -``` -./openhwgroup.org_systems_core-v-mini-mcu_0 +firmware=../../../sw/build/main.hex -gui -``` - -An Analog / Mixed-Signal simulation of X-HEEP, combining both the RTL system verilog files for the digital part and a SPICE file connected through a `control.init` file for the analog / mixed-signal part, can be ran by typing - -``` -make vcs-ams-sim -``` - -then going to the target system built folder - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-vcs -``` - -and running the same executable as for the digital simulation. Note that with Verdi you can view both the digital and the analog waveforms. - -Additional instructions on how to run an analog / mixed-signal simulation of X-HEEP can be found [here](AnalogMixedSignal.md). To try out the simulation, we provide an example SPICE netlist of an simple 1-bit ADC created by us and exported from [xschem](https://xschem.sourceforge.io/stefan/index.html) and which uses the PTM 65nm bulk CMOS model from [https://ptm.asu.edu](https://ptm.asu.edu/). - -### Compiling for Questasim - -To simulate your application with Questasim, first set the env variable `MODEL_TECH` to your Questasim bin folder, then compile the HDL: - -``` -make questasim-sim -``` - -then, go to your target system built folder - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-modelsim/ -``` - -and type to run your compiled software: - -``` -make run PLUSARGS="c firmware=../../../sw/build/main.hex" -``` - -You can also use vopt for HDL optimized compilation: - -``` -make questasim-sim-opt -``` - -then go to - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim_opt-modelsim/ -``` -and - -``` -make run RUN_OPT=1 PLUSARGS="c firmware=../../../sw/build/main.hex" -``` - -You can also compile with the UPF power domain description as: - -``` -make questasim-sim-opt-upf FUSESOC_PARAM="--USE_UPF" -``` - -and then execute software as: - -``` -make run RUN_OPT=1 RUN_UPF=1 PLUSARGS="c firmware=../../../sw/build/main.hex" -``` - -Questasim version must be >= Questasim 2020.4 - -### UART DPI - -To simulate the UART, we use the LowRISC OpenTitan [UART DPI](https://github.com/lowRISC/opentitan/tree/master/hw/dv/dpi/uartdpi). -Read how to interact with it in the Section "Running Software on a Verilator Simulation with Bazel" [here](https://opentitan.org/guides/getting_started/setup_verilator.html#running-software-on-a-verilator-simulation-with-bazel). -The output of the UART DPI module is printed in the `uart0.log` file in the simulation folder. - -For example, to see the "hello world!" output of the Verilator simulation: - -``` -cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-verilator -./Vtestharness +firmware=../../../sw/build/main.hex -cat uart0.log -``` - -## Automatic testing - -X-HEEP includes two tools to perform automatic tests over your modifications. - -### Github CIs - -Upon push, tests are run on Github runners, these include: -* The generated `.sv` files pushed are equal to those generated in the runner (the code does not depend on the modification of generated files) -* Vendor is up to date (the code does not depend on the modification of vendorized files) -* All applications can be built successfully using both gcc and clang - -All test must be successful before PRs can be merged. - -### Simulation script - -Additionally, a `test_all.sh` script is provided. Apart from compiling all apps with both gcc and clang, it will simulate them and check the result. - -The available parameters are: -* COMPILER: `gcc` (default) or `clang` (can provide more than one) -* SIMULATOR: `verilator` (default), `questasim` or disable simulation with `nosim` (only one, the last provided is used). -* LINKER: `on_chip`(default), `flash_load` or `flash_exec` (can provide more than one) -* TIMEOUT: Integer number of seconds (default 120) - - -#### Usage - -##### Comands -You can use two different commands to compile or simulate all the existing APPs: -``` -make app-compile-all -``` -``` -make app-simulate-all -``` -Note that both commands allow the previous parameters to specify compiling or simulation options. E.g.: -``` -make app-simulate-all LINKER=on_chip SIMULATOR=questasim COMPILER=clang TIMEOUT=150 -``` - -##### Manually -You can also **SOURCE** the script as -```bash -. util/test_all.sh on_chip questasim clang 150 -``` - -*Pay special attention to the first period in the command!* -You will be killing simulations that take too long, if you **EXECUTE** (`./test_all.sh`) this action kills the script. - -For both usages (commands or manual), the order of the arguments is irrelevant. - -> Note: Be sure to commit all your changes before running the script! - -* Applications that fail being built with gcc will not be simulated (skipped). -* Some applications are skipped by default for not being suitable for simulation. -* If a simulation takes too long (>timeout), it is killed. - -* Upon starting, the script will modify the `mcu_cfg.hjson` file to include all peripherals (so the largest number of apps can be run), re-generates the mcu and re-builds the simulation model for the chosen tool. -These changes can be reverted at the end of the execution (default). If changes were not commited, accepting this operation will revert them! - -The success of the script is not required for merging of a PR. - -## Debug - -Follow the [Debug](./Debug.md) guide to debug core-v-mini-mcu. - -Alternatively, in case you are used to developing using Integrated Development Environments (IDEs), please check [the IDE readme](./IDEs.md). - -## Execute From Flash - -Follow the [ExecuteFromFlash](./ExecuteFromFlash.md) guide to exxecute code directly from the FLASH with modelsim, FPGA, or ASIC. - -## Emulation on Xilinx FPGAs - -This project offers two different X-HEEP implementetions on the Xilinx FPGAs, called Standalone-FEMU and Linux-FEMU. - -### Standalone-FEMU (Standalone Fpga EMUlation) - -In this version, the X-HEEP architecture is implemented on the programmable logic (PL) side of the FPGA, and its input/output are connected to the available headers on the FPGA board. - -Make sure you have the FPGA board files installed in your Vivado. - -For example, for the Xilinx Pynq-Z2 board, use the documentation provided at the following [link](https://pynq.readthedocs.io/en/v2.5/overlay_design_methodology/board_settings.html) to download and install them: - -To build and program the bitstream for your FPGA with vivado, type: - -``` -make vivado-fpga FPGA_BOARD=pynq-z2 -``` - -or add the flag `use_bscane_xilinx` to use the native Xilinx scanchain: - -``` -make vivado-fpga FPGA_BOARD=pynq-z2 FUSESOC_FLAGS=--flag=use_bscane_xilinx -``` - -Only Vivado 2021.2 has been tried. - -To program the bitstream, open Vivado, - -``` -open --> Hardware Manager --> Open Target --> Autoconnect --> Program Device -``` - -and choose the file `openhwgroup.org_systems_core-v-mini-mcu_0.bit` - -To run SW, follow the [Debug](./Debug.md) guide -to load the binaries with the HS2 cable over JTAG, -or follow the [ExecuteFromFlash](./ExecuteFromFlash.md) -guide if you have a FLASH attached to the FPGA. - - -Do not forget that the `pynq-z2` board requires you to have the ethernet cable attached to the board while running. - - -### Linux-FEMU (Linux Fpga EMUlation) - -In this version, the X-HEEP architecture is implemented on the programmable logic (PL) side of the FPGA and Linux is run on the ARM-based processing system (PS) side of the same chip. - -Read the [following](./linux_femu/README.md) documentation to have more information about this implementation. - - -# ASIC Implementation - -This project can be implemented using standard cells based ASIC flow. - -## Synthesis with Synopsys Design Compiler - -First, you need to provide technology-dependent implementations of some of the cells which require specific instantiation. - -Then, please provide a set_libs.tcl and set_constraints.tcl scripts to set link and target libraries, and constraints as the clock. - -To generate the `analyze` script for the synthesis scripts with DC, execute: - -``` -make asic -``` - -## OpenRoad support for SkyWater 130nm - -We are working on supporting OpenRoad and SkyWater 130nm PDK, please refer to the -[OpenRoadFlow](./OpenRoadFlow.md) page. This is not ready yet, it has not been tested. - -This relies on a fork of [edalize](https://github.com/davideschiavone/edalize) that contains templates for Design Compiler and OpenRoad. + └── README.md \ No newline at end of file diff --git a/docs/logo/x-heep-outline.png b/docs/logo/x-heep-outline.png new file mode 100644 index 0000000000000000000000000000000000000000..b2aa5446f0cd09aedda76b5bf5b2e0529642e24d GIT binary patch literal 42485 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 TARGET=sim(default),pynq-z2 LINKER=on_chip(default),flash_load,flash_exec COMPILER=gcc(default),clang COMPILER_PREFIX=riscv32-unknown-(default) ARCH=rv32imc(default), + +Params: +- PROJECT (ex: , hello_world(default)) +- TARGET (ex: sim(default),pynq-z2) +- LINKER (ex: on_chip(default),flash_load,flash_exec) +- COMPILER (ex: gcc(default),clang) +- COMPILER_PREFIX (ex: riscv32-unknown-(default)) +- ARCH (ex: rv32imc(default),) +``` + +For instance, to run 'hello world' app for the pynq-z2 FPGA targets, just run: + +``` +make app TARGET=pynq-z2 +``` + +Or, if you use the OpenHW Group [GCC](https://www.embecosm.com/resources/tool-chain-downloads/#corev) compiler with CORE_PULP extensions, make sure to point the `RISCV` env variable to the OpenHW Group compiler, then just run: + + +``` +make app COMPILER_PREFIX=riscv32-corev- ARCH=rv32imc_zicsr_zifencei_xcvhwlp1p0_xcvmem1p0_xcvmac1p0_xcvbi1p0_xcvalu1p0_xcvsimd1p0_xcvbitmanip1p0 +``` + +This will create the executable file to be loaded into your target system (ASIC, FPGA, Simulation). +Remember that, `X-HEEP` is using CMake to compile and link. Thus, the generated files after having +compiled and linked are under `sw\build` + +Alternatively, in case you are doing pure FW development and you are used to developing using Integrated Development Evironments (IDEs), please check [the IDE readme](./IDEs.md). + +### FreeROTS based applications + +'X-HEEP' supports 'FreeRTOS' based applications. Please see `sw\applications\blinky_freertos`. + +After that, you can run the command to compile and link the FreeRTOS based application. Please also set 'LINKER' and 'TARGET' parameters if needed. + +``` +make app PROJECT=blinky_freertos +``` + +The main FreeRTOS configuration is allocated under `sw\freertos`, in `FreeRTOSConfig.h`. Please, change this file based on your application requirements. +Moreover, FreeRTOS is being fetch from 'https://github.com/FreeRTOS/FreeRTOS-Kernel.git' by CMake. Specifically, 'V10.5.1' is used. Finally, the fetch repository is located under `sw\build\_deps` after building. + +### Simulating + +This project supports simulation with Verilator, Synopsys VCS, and Siemens Questasim. +It relies on `fusesoc` to handle multiple EDA tools and parameters. +For example, if you want to set the `FPU` and `COREV_PULP` parameters of the `cv32e40p` CPU, +you need to add next to your compilation command `FUSESOC_PARAM="--COREV_PULP=1 --FPU=1"` +Below the different EDA examples commands. + +#### Compiling for Verilator + +To simulate your application with Verilator, first compile the HDL: + +``` +make verilator-sim +``` + +then, go to your target system built folder + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-verilator +``` + +and type to run your compiled software: + +``` +./Vtestharness +firmware=../../../sw/build/main.hex +``` + +or to execute all these three steps type: + +``` +make run-helloworld +``` + + +#### Compiling for VCS + +To simulate your application with VCS, first compile the HDL: + +``` +make vcs-sim +``` + +then, go to your target system built folder + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-vcs +``` + +and type to run your compiled software: + +``` +./openhwgroup.org_systems_core-v-mini-mcu_0 +firmware=../../../sw/build/main.hex +``` + +Waveforms can be viewed with Verdi. Make sure you have the env variable `VERDI_HOME` set to your Verdi install folder, then run your compiled software as above, but with the `-gui` flag: + +``` +./openhwgroup.org_systems_core-v-mini-mcu_0 +firmware=../../../sw/build/main.hex -gui +``` + +An Analog / Mixed-Signal simulation of X-HEEP, combining both the RTL system verilog files for the digital part and a SPICE file connected through a `control.init` file for the analog / mixed-signal part, can be ran by typing + +``` +make vcs-ams-sim +``` + +then going to the target system built folder + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-vcs +``` + +and running the same executable as for the digital simulation. Note that with Verdi you can view both the digital and the analog waveforms. + +Additional instructions on how to run an analog / mixed-signal simulation of X-HEEP can be found [here](AnalogMixedSignal.md). To try out the simulation, we provide an example SPICE netlist of an simple 1-bit ADC created by us and exported from [xschem](https://xschem.sourceforge.io/stefan/index.html) and which uses the PTM 65nm bulk CMOS model from [https://ptm.asu.edu](https://ptm.asu.edu/). + +#### Compiling for Questasim + +To simulate your application with Questasim, first set the env variable `MODEL_TECH` to your Questasim bin folder, then compile the HDL: + +``` +make questasim-sim +``` + +then, go to your target system built folder + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-modelsim/ +``` + +and type to run your compiled software: + +``` +make run PLUSARGS="c firmware=../../../sw/build/main.hex" +``` + +You can also use vopt for HDL optimized compilation: + +``` +make questasim-sim-opt +``` + +then go to + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim_opt-modelsim/ +``` +and + +``` +make run RUN_OPT=1 PLUSARGS="c firmware=../../../sw/build/main.hex" +``` + +You can also compile with the UPF power domain description as: + +``` +make questasim-sim-opt-upf FUSESOC_PARAM="--USE_UPF" +``` + +and then execute software as: + +``` +make run RUN_OPT=1 RUN_UPF=1 PLUSARGS="c firmware=../../../sw/build/main.hex" +``` + +Questasim version must be >= Questasim 2020.4 + +#### UART DPI + +To simulate the UART, we use the LowRISC OpenTitan [UART DPI](https://github.com/lowRISC/opentitan/tree/master/hw/dv/dpi/uartdpi). +Read how to interact with it in the Section "Running Software on a Verilator Simulation with Bazel" [here](https://opentitan.org/guides/getting_started/setup_verilator.html#running-software-on-a-verilator-simulation-with-bazel). +The output of the UART DPI module is printed in the `uart0.log` file in the simulation folder. + +For example, to see the "hello world!" output of the Verilator simulation: + +``` +cd ./build/openhwgroup.org_systems_core-v-mini-mcu_0/sim-verilator +./Vtestharness +firmware=../../../sw/build/main.hex +cat uart0.log +``` + +### Automatic testing + +X-HEEP includes two tools to perform automatic tests over your modifications. + +#### Github CIs + +Upon push, tests are run on Github runners, these include: +* The generated `.sv` files pushed are equal to those generated in the runner (the code does not depend on the modification of generated files) +* Vendor is up to date (the code does not depend on the modification of vendorized files) +* All applications can be built successfully using both gcc and clang + +All test must be successful before PRs can be merged. + +#### Simulation script + +Additionally, a `test_all.sh` script is provided. Apart from compiling all apps with both gcc and clang, it will simulate them and check the result. + +The available parameters are: +* COMPILER: `gcc` (default) or `clang` (can provide more than one) +* SIMULATOR: `verilator` (default), `questasim` or disable simulation with `nosim` (only one, the last provided is used). +* LINKER: `on_chip`(default), `flash_load` or `flash_exec` (can provide more than one) +* TIMEOUT: Integer number of seconds (default 120) + + +##### Usage + +###### Comands +You can use two different commands to compile or simulate all the existing APPs: +``` +make app-compile-all +``` +``` +make app-simulate-all +``` +Note that both commands allow the previous parameters to specify compiling or simulation options. E.g.: +``` +make app-simulate-all LINKER=on_chip SIMULATOR=questasim COMPILER=clang TIMEOUT=150 +``` + +###### Manually +You can also **SOURCE** the script as +```bash +. util/test_all.sh on_chip questasim clang 150 +``` + +*Pay special attention to the first period in the command!* +You will be killing simulations that take too long, if you **EXECUTE** (`./test_all.sh`) this action kills the script. + +For both usages (commands or manual), the order of the arguments is irrelevant. + +> Note: Be sure to commit all your changes before running the script! + +* Applications that fail being built with gcc will not be simulated (skipped). +* Some applications are skipped by default for not being suitable for simulation. +* If a simulation takes too long (>timeout), it is killed. + +* Upon starting, the script will modify the `mcu_cfg.hjson` file to include all peripherals (so the largest number of apps can be run), re-generates the mcu and re-builds the simulation model for the chosen tool. +These changes can be reverted at the end of the execution (default). If changes were not commited, accepting this operation will revert them! + +The success of the script is not required for merging of a PR. + +### Debug + +Follow the [Debug](./Debug.md) guide to debug core-v-mini-mcu. + +Alternatively, in case you are used to developing using Integrated Development Environments (IDEs), please check [the IDE readme](./IDEs.md). + +### Execute From Flash + +Follow the [ExecuteFromFlash](./ExecuteFromFlash.md) guide to exxecute code directly from the FLASH with modelsim, FPGA, or ASIC. + +### Emulation on Xilinx FPGAs + +This project offers two different X-HEEP implementetions on the Xilinx FPGAs, called Standalone-FEMU and Linux-FEMU. + +#### Standalone-FEMU (Standalone Fpga EMUlation) + +In this version, the X-HEEP architecture is implemented on the programmable logic (PL) side of the FPGA, and its input/output are connected to the available headers on the FPGA board. + +Make sure you have the FPGA board files installed in your Vivado. + +For example, for the Xilinx Pynq-Z2 board, use the documentation provided at the following [link](https://pynq.readthedocs.io/en/v2.5/overlay_design_methodology/board_settings.html) to download and install them: + +To build and program the bitstream for your FPGA with vivado, type: + +``` +make vivado-fpga FPGA_BOARD=pynq-z2 +``` + +or add the flag `use_bscane_xilinx` to use the native Xilinx scanchain: + +``` +make vivado-fpga FPGA_BOARD=pynq-z2 FUSESOC_FLAGS=--flag=use_bscane_xilinx +``` + +Only Vivado 2021.2 has been tried. + +To program the bitstream, open Vivado, + +``` +open --> Hardware Manager --> Open Target --> Autoconnect --> Program Device +``` + +and choose the file `openhwgroup.org_systems_core-v-mini-mcu_0.bit` + +To run SW, follow the [Debug](./Debug.md) guide +to load the binaries with the HS2 cable over JTAG, +or follow the [ExecuteFromFlash](./ExecuteFromFlash.md) +guide if you have a FLASH attached to the FPGA. + + +Do not forget that the `pynq-z2` board requires you to have the ethernet cable attached to the board while running. + + +#### Linux-FEMU (Linux Fpga EMUlation) + +In this version, the X-HEEP architecture is implemented on the programmable logic (PL) side of the FPGA and Linux is run on the ARM-based processing system (PS) side of the same chip. + +Read the [following](./linux_femu/README.md) documentation to have more information about this implementation. + + +## ASIC Implementation + +This project can be implemented using standard cells based ASIC flow. + +### Synthesis with Synopsys Design Compiler + +First, you need to provide technology-dependent implementations of some of the cells which require specific instantiation. + +Then, please provide a set_libs.tcl and set_constraints.tcl scripts to set link and target libraries, and constraints as the clock. + +To generate the `analyze` script for the synthesis scripts with DC, execute: + +``` +make asic +``` + +### OpenRoad support for SkyWater 130nm + +We are working on supporting OpenRoad and SkyWater 130nm PDK, please refer to the +[OpenRoadFlow](./OpenRoadFlow.md) page. This is not ready yet, it has not been tested. + +This relies on a fork of [edalize](https://github.com/davideschiavone/edalize) that contains templates for Design Compiler and OpenRoad.