From 2f6159bd9a013d83f847f777f9f183c8c209d19d Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Thu, 27 Jul 2023 16:47:51 +0200 Subject: [PATCH 01/16] Update synthesis docs. --- docs/synthesis/Synthesis.md | 39 ++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 7f3112be1..755702ed5 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -3,25 +3,48 @@ CoreBlocks synthesizes `Core` circuit to test how many resources it consumes as the project grows and more functionalities are added. + +## Benchmarks + +For each commit on `master` branch, CI runs the synthesis and saves the parameters collected by `parse_benchmark_info` script. + +Graphs generated from this information are available on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). + ## Documentation +### Using pre-build container + +There is a pre-build container available that is being used in CI. You can +download it and start the synthesis in it locally by executing the following commands: + +```bash +sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 +sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 +git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git +cd coreblocks +python3 -m pip install --upgrade pip +pip3 install -r requirements-dev.txt +PYTHONHASHSEED=0 ./scripts/synthesize.py --verbose --config +./scripts/parse_benchmark_info.py +cat benchmark.json +``` + ### Requirements -In order to perform synthesis you will need to install following tools: +In order to perform synthesis without using the ready container you will need to install following tools: * [yosys](https://github.com/YosysHQ/yosys) * [prjtrellis](https://github.com/YosysHQ/prjtrellis) * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) These tools may need manual compilation from git repository, that can take some time. -You can use docker images that have installed all required tools to perform synthesis: - * [vuush/amaranth-synth:ecp5](https://hub.docker.com/r/vuush/amaranth-synth/tags) - -To build the `AmaranthSynthECP5.Dockerfile` yourself use following command: +We also provides a dockerfile which can be used to reproduce image used in CI. +To do that, build the `AmaranthSynthECP5.Dockerfile` yourself using following command: ``` docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . ``` + ### Usage Script named `synthesize.py` is used to perform the `Core` synthesis. @@ -41,9 +64,3 @@ following information: - Number of carry cells used - Number of RAM cells used - Number of DFF cells used - -## Benchmarks - -For each commit on `master` branch, CI runs the synthesis and saves the parameters collected by `parse_benchmark_info` script. - -Graphs generated from this information are available on a dedicated [subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). From f663a2435736e04352eddbb72ff7f2679413f184 Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Mon, 13 Nov 2023 19:29:19 +0100 Subject: [PATCH 02/16] Update syntax errors --- docs/synthesis/Synthesis.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 755702ed5..ad3c84234 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -6,15 +6,18 @@ grows and more functionalities are added. ## Benchmarks -For each commit on `master` branch, CI runs the synthesis and saves the parameters collected by `parse_benchmark_info` script. - -Graphs generated from this information are available on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). +On each commit to the `master` branch, CI runs the synthesis and saves the parameters collected by the `parse_benchmark_info` script. +The properties collected are: +- IPC +- Fmax +- LUT/RAM usage +The graphs generated from this data are available on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). ## Documentation ### Using pre-build container -There is a pre-build container available that is being used in CI. You can +There is a pre-built container available that is being used in CI. You can download it and start the synthesis in it locally by executing the following commands: ```bash From ebae77dccaccee14dd0d2f8ea297279c96443b62 Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Mon, 13 Nov 2023 19:30:55 +0100 Subject: [PATCH 03/16] Fix errors --- docs/synthesis/Synthesis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index ad3c84234..733182bb3 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -41,8 +41,8 @@ In order to perform synthesis without using the ready container you will need to These tools may need manual compilation from git repository, that can take some time. -We also provides a dockerfile which can be used to reproduce image used in CI. -To do that, build the `AmaranthSynthECP5.Dockerfile` yourself using following command: +We also provide a dockerfile that can be used to recreate the image used in the CI. +To do this, build the `AmaranthSynthECP5.Dockerfile` yourself using the following command: ``` docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . ``` From 59635ed547a9f17d843e7ad424037902cd93cb41 Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:15:28 +0100 Subject: [PATCH 04/16] Apply suggestions from code review Co-authored-by: Marek Materzok Co-authored-by: Kristopher38 --- docs/synthesis/Synthesis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 733182bb3..6aa16b637 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -15,7 +15,7 @@ The graphs generated from this data are available on a dedicated [benchmark subp ## Documentation -### Using pre-build container +### Using pre-built container There is a pre-built container available that is being used in CI. You can download it and start the synthesis in it locally by executing the following commands: @@ -34,7 +34,7 @@ cat benchmark.json ### Requirements -In order to perform synthesis without using the ready container you will need to install following tools: +In order to perform synthesis without using a pre-made container you will need to install following tools: * [yosys](https://github.com/YosysHQ/yosys) * [prjtrellis](https://github.com/YosysHQ/prjtrellis) * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) From d7ba0bce9359b3dbd443fe72d9177840eed34412 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sat, 18 Nov 2023 20:22:26 +0100 Subject: [PATCH 05/16] WIP. Reformat Synthesise page withe the goal to describe all verification jobs. --- docs/synthesis/Synthesis.md | 91 +++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 6aa16b637..c78f3f01d 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -1,69 +1,74 @@ -# Synthesis +# Core verification -CoreBlocks synthesizes `Core` circuit to test how many resources it consumes as the project -grows and more functionalities are added. +Coreblocks is verified at several levels of abstraction. Beside of unit tests and module tests, we also +synthesise the core to the ECP5 FPGA target, to check that it can work in reality. Performance is verified +using synthesis results and a set of benchmarks simulated with cycle precision in cocotb. We also verify +correctness of the core behaviour by running assembler tests from riscv-tests and riscv-arch-tests. +These three verification steps are automatically run by CI on every commit delivered to the `master` branch. Running +the checks in CI allow us to collect historical data, which are available in the form of the graphs +on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). -## Benchmarks +In CI we use pre-built docker containers, which are publicly available on our github page . In the following +subsections we provide the instructions on how to manually run verification steps using these containers. They can be +recreated using standard docker build commands: -On each commit to the `master` branch, CI runs the synthesis and saves the parameters collected by the `parse_benchmark_info` script. -The properties collected are: -- IPC -- Fmax -- LUT/RAM usage -The graphs generated from this data are available on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). +``` +docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . +``` -## Documentation +## Synthesis -### Using pre-built container +The basic step in verification is to see if it is possible to synthesise the `Core` circuit. This allows us to +control the level of complexity of the core. Although Coreblocks is an educational core, we want it to be practical, not theoretical, +so it should have an acceptable maximum frequency and shouldn't use too many resources, so it can be run +on a FPGA. The synthesis step ensures that these requirements are met. In addition, it checks whether the code that is acceptable +for the Amaranth is also acceptable for the synthesis tools. -There is a pre-built container available that is being used in CI. You can -download it and start the synthesis in it locally by executing the following commands: +The main properties collected in the synthesis step: + - Max clock frequency + - Number of logic cells used + - Number of carry cells used + - Number of RAM cells used + - Number of DFF cells used + +The configuration of the docker container is described in the `AmaranthSynthECP5.Dockerfile`, which can be found in our repo . + +### Manual reproduction ```bash sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks +python3 -m venv venv +. venv/bin/activate python3 -m pip install --upgrade pip pip3 install -r requirements-dev.txt -PYTHONHASHSEED=0 ./scripts/synthesize.py --verbose --config +PYTHONHASHSEED=0 ./scripts/synthesize.py --verbose --config full ./scripts/parse_benchmark_info.py cat benchmark.json ``` -### Requirements - -In order to perform synthesis without using a pre-made container you will need to install following tools: - * [yosys](https://github.com/YosysHQ/yosys) - * [prjtrellis](https://github.com/YosysHQ/prjtrellis) - * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) +The main point of the above listing is the `synthesize.py` script, which creates an instance of the `Core` object with +the configuration provided by the user and then passes it to the Amaranth to generate a Verilog description from that instance. +This description is then processed by the Yosys and nextpnr-ecp5 to generate the ECP5 bitstream. -These tools may need manual compilation from git repository, that can take some time. +The strength of the Coreblocks is its modularity, so we can provide different configurations with little effort. You can choose +a configuration to synthesise using the `--config` argument to the `synthesise.py` script. -We also provide a dockerfile that can be used to recreate the image used in the CI. -To do this, build the `AmaranthSynthECP5.Dockerfile` yourself using the following command: -``` -docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . -``` +### Dependencies +In order to perform synthesis we use: + * [yosys](https://github.com/YosysHQ/yosys) - to synthesise the Verilog generated by Amaranth up to gate level + * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) - to perform the "Place and Route" step + * [prjtrellis](https://github.com/YosysHQ/prjtrellis) - provides the description of the ECP5 bitstream format -### Usage +## Benchmarking -Script named `synthesize.py` is used to perform the `Core` synthesis. - -Example usage: -``` -./scripts/synthesize.py --help -./scripts/synthesize.py --platform ecp5 --verbose -``` +TODO -To collect synthesis information we use script named `parse_benchmark_info.py`. +## Regression tests -This script parses the output of the synthesis tool and extracts the -following information: - - Max clock frequency - - Number of logic cells used - - Number of carry cells used - - Number of RAM cells used - - Number of DFF cells used +TODO From 761a624115d64119ea63254dfbb754f02a036523 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 10:44:24 +0100 Subject: [PATCH 06/16] Add links --- docs/synthesis/Synthesis.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index c78f3f01d..7c87f1826 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -3,15 +3,16 @@ Coreblocks is verified at several levels of abstraction. Beside of unit tests and module tests, we also synthesise the core to the ECP5 FPGA target, to check that it can work in reality. Performance is verified using synthesis results and a set of benchmarks simulated with cycle precision in cocotb. We also verify -correctness of the core behaviour by running assembler tests from riscv-tests and riscv-arch-tests. +correctness of the core behaviour by running assembler tests from [riscv-tests](https://github.com/riscv-software-src/riscv-tests/tree/master) +and [riscv-arch-tests](https://github.com/riscv-non-isa/riscv-arch-test). These three verification steps are automatically run by CI on every commit delivered to the `master` branch. Running the checks in CI allow us to collect historical data, which are available in the form of the graphs on a dedicated [benchmark subpage](https://kuznia-rdzeni.github.io/coreblocks/dev/benchmark/). -In CI we use pre-built docker containers, which are publicly available on our github page . In the following -subsections we provide the instructions on how to manually run verification steps using these containers. They can be -recreated using standard docker build commands: +In CI we use pre-built docker containers, which are publicly available on our [github page](https://github.com/orgs/kuznia-rdzeni/packages). +In the following subsections we provide the instructions on how to manually run verification steps using these containers. +They can be recreated using standard docker build commands: ``` docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . @@ -32,8 +33,8 @@ The main properties collected in the synthesis step: - Number of RAM cells used - Number of DFF cells used -The configuration of the docker container is described in the `AmaranthSynthECP5.Dockerfile`, which can be found in our repo . +The configuration of the docker container is described in the `AmaranthSynthECP5.Dockerfile`, which can be found in +[our repo](https://github.com/orgs/kuznia-rdzeni/packages/container/package/amaranth-synth). ### Manual reproduction From 9322ff83a9c63cad16191da154c448e6f7a0a3c7 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 11:12:11 +0100 Subject: [PATCH 07/16] First version about benchmarking --- docs/synthesis/Synthesis.md | 45 ++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 7c87f1826..cc15546d0 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -39,8 +39,8 @@ The configuration of the docker container is described in the `AmaranthSynthECP5 ### Manual reproduction ```bash -sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 -sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5 +sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 +sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks python3 -m venv venv @@ -68,7 +68,46 @@ In order to perform synthesis we use: ## Benchmarking -TODO +The maximum clock frequency determined by synthesis isn't the only performance measurement. Theoretically there is always a +possibility to increase Fmax by increasing the latency. So to avoid pitfall of too big latency we introduced monitoring +of instructions executed per clock cycle (IPC). This is done by simulating the core with cycle accuracy and executing +benchmarks written in C on such core. As benchmarking programs we use +[embench](https://github.com/embench/embench-iot/tree/master). + +Benchmarking is done in two steps. First we compile C programs to binary format and next binaries are executed on +simulated core. Compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with +glibc compiled to different architectural subsets of RiscV extensions. The configuration of riscv-gnu-toolchain used in +Coreblocks is described in [riscv-toolchain.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/riscv-toolchain.Dockerfile). +Benchmarks can be compiled once and used repeatedly as long as there will be no need for adding support for the new +RiscV extensions or the embench wouldn't be updated. + +Having binaries we can execute them in simulation. This is done using [Cocotb](https://github.com/cocotb/cocotb) and +[Verilator](https://github.com/verilator/verilator). First we generate Verilog code which describes Coreblocks instance. +Then it is passed to Verilator for compilation and Cocotb controls execution of program, by stubbing external +interfaces. Compiled Verilator in compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). + +### Benchmarks manual compilation +```bash +sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +sudo docker run -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git +cd coreblocks/test/external/embench +make +``` + +### Benchmarks manual execution +```bash +sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +sudo docker run -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git +cd coreblocks +python3 -m venv venv +. venv/bin/activate +python3 -m pip install --upgrade pip +pip3 install -r requirements-dev.txt +PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full +./scripts/run_benchmarks.py +``` ## Regression tests From 7b06a8179c359cbb6f2ac8c0cc8884677948ae36 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 11:22:14 +0100 Subject: [PATCH 08/16] Benchmarking commands before verification. --- docs/synthesis/Synthesis.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index cc15546d0..544f26f1f 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -86,21 +86,25 @@ Having binaries we can execute them in simulation. This is done using [Cocotb](h Then it is passed to Verilator for compilation and Cocotb controls execution of program, by stubbing external interfaces. Compiled Verilator in compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). -### Benchmarks manual compilation +### Benchmarks manual execution ```bash -sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v -sudo docker run -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +# ========== STEP 1: Compilation ========== +# Clone coreblocks into host file system git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git -cd coreblocks/test/external/embench +sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +# Run docker with coreblocks directory mounted into it +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +cd /coreblocks/test/external/embench +# Compilation with make will save binaries to the /coreblocks directory which is shared with host +# so binaries will survive after closing the docker container make -``` +exit -### Benchmarks manual execution -```bash +# ========== STEP 2: Execution ========== sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 -sudo docker run -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 -git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git -cd coreblocks +# Run docker with coreblocks directory mounted into it. This directory contains +# benchmarks binaries after execution of first step. +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 python3 -m venv venv . venv/bin/activate python3 -m pip install --upgrade pip From d7644568089e9ad55671125ac564ab2edb1c1ef6 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 12:06:58 +0100 Subject: [PATCH 09/16] Fixes in commands --- docs/synthesis/Synthesis.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 544f26f1f..f8b635b0d 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -43,6 +43,8 @@ sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks +apt update +apt install python3.11-venv python3 -m venv venv . venv/bin/activate python3 -m pip install --upgrade pip @@ -91,6 +93,9 @@ interfaces. Compiled Verilator in compatible version is available in [Verilator. # ========== STEP 1: Compilation ========== # Clone coreblocks into host file system git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git +cd coreblocks +git submodule update --init --recursive +cd .. sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v # Run docker with coreblocks directory mounted into it sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v @@ -105,9 +110,12 @@ sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 # Run docker with coreblocks directory mounted into it. This directory contains # benchmarks binaries after execution of first step. sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +apt update +apt install python3.11-venv python3 -m venv venv . venv/bin/activate python3 -m pip install --upgrade pip +cd coreblocks pip3 install -r requirements-dev.txt PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full ./scripts/run_benchmarks.py From 79d6aeafe8c6e51e4faeeeced98382271d39bfc4 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 12:17:03 +0100 Subject: [PATCH 10/16] Add section about regression. --- docs/synthesis/Synthesis.md | 38 ++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index f8b635b0d..779bf64b7 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -123,4 +123,40 @@ PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full ## Regression tests -TODO +Regressions rests should ensure that Coreblocks is complaint with RiscV specification requirements. Tests contains +assembler programs which tests whole RISC-V instruction set. We execute these programs in similar way as benchmarks. +So as the first step we compile the programs to the binary format and then we run them on core simulated by Verilator +and Cocotb. + +### Regression tests manual execution +```bash +# ========== STEP 1: Compilation ========== +# Clone coreblocks into host file system +git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git +cd coreblocks +git submodule update --init --recursive +cd .. +sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +# Run docker with coreblocks directory mounted into it +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +cd /coreblocks/test/external/riscv-tests +# Compilation with make will save binaries to the /coreblocks directory which is shared with host +# so binaries will survive after closing the docker container +make +exit + +# ========== STEP 2: Execution ========== +sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +# Run docker with coreblocks directory mounted into it. This directory contains +# benchmarks binaries after execution of first step. +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +apt update +apt install python3.11-venv +python3 -m venv venv +. venv/bin/activate +python3 -m pip install --upgrade pip +cd coreblocks +pip3 install -r requirements-dev.txt +PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full +./scripts/run_tests.py -a regression +``` From 18f447e12ac3ad75e832892cb3880beb80e7838e Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 12:31:05 +0100 Subject: [PATCH 11/16] Fix typos. --- docs/synthesis/Synthesis.md | 50 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 779bf64b7..d0b543870 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -70,23 +70,23 @@ In order to perform synthesis we use: ## Benchmarking -The maximum clock frequency determined by synthesis isn't the only performance measurement. Theoretically there is always a -possibility to increase Fmax by increasing the latency. So to avoid pitfall of too big latency we introduced monitoring -of instructions executed per clock cycle (IPC). This is done by simulating the core with cycle accuracy and executing +The maximum clock frequency determined by synthesis isn't the only measure of performance. Theoretically, there is always a +possibility to increase Fmax by increasing the latency. To avoid the pitfall of too big latency, we have introduced the monitoring +of instructions executed per clock cycle (IPC). This is done by simulating the core with cycle accuracy and running benchmarks written in C on such core. As benchmarking programs we use [embench](https://github.com/embench/embench-iot/tree/master). -Benchmarking is done in two steps. First we compile C programs to binary format and next binaries are executed on -simulated core. Compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with -glibc compiled to different architectural subsets of RiscV extensions. The configuration of riscv-gnu-toolchain used in +The benchmarking is done in two steps. First, we compile C programs into binary format and then run the binaries on +simulated core. The compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with +glibc compiled for different architectural subsets of RISC-V extensions. The configuration of the riscv-gnu-toolchain used in Coreblocks is described in [riscv-toolchain.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/riscv-toolchain.Dockerfile). -Benchmarks can be compiled once and used repeatedly as long as there will be no need for adding support for the new -RiscV extensions or the embench wouldn't be updated. +Benchmarks can be compiled once and used repeatedly as long as there is no need to add support for the new +RISC-V extensions or the embench isn't be updated. -Having binaries we can execute them in simulation. This is done using [Cocotb](https://github.com/cocotb/cocotb) and -[Verilator](https://github.com/verilator/verilator). First we generate Verilog code which describes Coreblocks instance. -Then it is passed to Verilator for compilation and Cocotb controls execution of program, by stubbing external -interfaces. Compiled Verilator in compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). +Once we have binaries, we can execute them in simulation. This is done with [Cocotb](https://github.com/cocotb/cocotb) and +[Verilator](https://github.com/verilator/verilator). First we generate Verilog code describing Coreblocks instance. +Then it is passed to Verilator for compilation and Cocotb controls the execution of the program, by stubbing external +interfaces. Compiled Verilator in a compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). ### Benchmarks manual execution ```bash @@ -97,18 +97,18 @@ cd coreblocks git submodule update --init --recursive cd .. sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v -# Run docker with coreblocks directory mounted into it +# Run docker with the coreblocks directory mounted into it sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v cd /coreblocks/test/external/embench -# Compilation with make will save binaries to the /coreblocks directory which is shared with host -# so binaries will survive after closing the docker container +# Compilation will put binaries in the subdirectory of the /coreblocks directory, which is shared with the host +# so that binaries survive after the docker container is closed make exit # ========== STEP 2: Execution ========== sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 -# Run docker with coreblocks directory mounted into it. This directory contains -# benchmarks binaries after execution of first step. +# Run docker with the coreblocks directory mounted into it. This directory contains +# benchmark binaries after running the first step. sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 apt update apt install python3.11-venv @@ -123,9 +123,9 @@ PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full ## Regression tests -Regressions rests should ensure that Coreblocks is complaint with RiscV specification requirements. Tests contains -assembler programs which tests whole RISC-V instruction set. We execute these programs in similar way as benchmarks. -So as the first step we compile the programs to the binary format and then we run them on core simulated by Verilator +Regression tests should ensure that Coreblocks is complaint with RISC-V specification requirements. Tests include +assembler programs that tests entire RISC-V instruction set. We execute these programs in a similar way to benchmarks. +So, as a first step, we compile the programs to the binary format and then we run them on core simulated by Verilator and Cocotb. ### Regression tests manual execution @@ -137,18 +137,18 @@ cd coreblocks git submodule update --init --recursive cd .. sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v -# Run docker with coreblocks directory mounted into it +# Run docker with the coreblocks directory mounted into it sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v cd /coreblocks/test/external/riscv-tests -# Compilation with make will save binaries to the /coreblocks directory which is shared with host -# so binaries will survive after closing the docker container +# Compilation will put binaries in the subdirectory of the /coreblocks directory, which is shared with the host +# so that binaries survive after the docker container is closed make exit # ========== STEP 2: Execution ========== sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 -# Run docker with coreblocks directory mounted into it. This directory contains -# benchmarks binaries after execution of first step. +# Run docker with the coreblocks directory mounted into it. This directory contains +# regression test binaries after running the first step. sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 apt update apt install python3.11-venv From a26262157e5f1d15da5cfa4e3700b25485fa3548 Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:55:49 +0100 Subject: [PATCH 12/16] Apply suggestions from code review Co-authored-by: Marek Materzok --- docs/synthesis/Synthesis.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index d0b543870..ac609a955 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -21,8 +21,8 @@ docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/Amarant ## Synthesis The basic step in verification is to see if it is possible to synthesise the `Core` circuit. This allows us to -control the level of complexity of the core. Although Coreblocks is an educational core, we want it to be practical, not theoretical, -so it should have an acceptable maximum frequency and shouldn't use too many resources, so it can be run +control the level of complexity of the core. Although Coreblocks is an educational core, we want it to be practical. +It should have an acceptable maximum frequency and shouldn't use too many resources, so it can be run on a FPGA. The synthesis step ensures that these requirements are met. In addition, it checks whether the code that is acceptable for the Amaranth is also acceptable for the synthesis tools. @@ -55,29 +55,29 @@ cat benchmark.json ``` The main point of the above listing is the `synthesize.py` script, which creates an instance of the `Core` object with -the configuration provided by the user and then passes it to the Amaranth to generate a Verilog description from that instance. -This description is then processed by the Yosys and nextpnr-ecp5 to generate the ECP5 bitstream. +the configuration provided by the user and then passes it to Amaranth to generate a Verilog description from that instance. +This description is then processed by Yosys and nextpnr-ecp5 to generate the ECP5 bitstream. -The strength of the Coreblocks is its modularity, so we can provide different configurations with little effort. You can choose +A strength of Coreblocks is its modularity, so we can provide different configurations with little effort. You can choose a configuration to synthesise using the `--config` argument to the `synthesise.py` script. ### Dependencies In order to perform synthesis we use: - * [yosys](https://github.com/YosysHQ/yosys) - to synthesise the Verilog generated by Amaranth up to gate level - * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) - to perform the "Place and Route" step - * [prjtrellis](https://github.com/YosysHQ/prjtrellis) - provides the description of the ECP5 bitstream format + * [yosys](https://github.com/YosysHQ/yosys) - to synthesise the Verilog generated by Amaranth up to gate level; + * [nextpnr-ecp5](https://github.com/YosysHQ/nextpnr.git) - to perform the "Place and Route" step; + * [prjtrellis](https://github.com/YosysHQ/prjtrellis) - provides the description of the ECP5 bitstream format. ## Benchmarking The maximum clock frequency determined by synthesis isn't the only measure of performance. Theoretically, there is always a -possibility to increase Fmax by increasing the latency. To avoid the pitfall of too big latency, we have introduced the monitoring +possibility to increase Fmax by increasing the latency. To avoid the pitfall of too long latency, we have introduced the monitoring of instructions executed per clock cycle (IPC). This is done by simulating the core with cycle accuracy and running -benchmarks written in C on such core. As benchmarking programs we use +benchmarks written in C inside the simulation. As benchmarking programs we use [embench](https://github.com/embench/embench-iot/tree/master). The benchmarking is done in two steps. First, we compile C programs into binary format and then run the binaries on -simulated core. The compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with +the simulated core. The compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with glibc compiled for different architectural subsets of RISC-V extensions. The configuration of the riscv-gnu-toolchain used in Coreblocks is described in [riscv-toolchain.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/riscv-toolchain.Dockerfile). Benchmarks can be compiled once and used repeatedly as long as there is no need to add support for the new From ff2cdb4a6f5fb29970b1153846f72f5b0963c1e1 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 15:19:42 +0100 Subject: [PATCH 13/16] Done some magic to correct Benchmarking section. --- docs/synthesis/Synthesis.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index ac609a955..e095d5972 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -24,7 +24,7 @@ The basic step in verification is to see if it is possible to synthesise the `Co control the level of complexity of the core. Although Coreblocks is an educational core, we want it to be practical. It should have an acceptable maximum frequency and shouldn't use too many resources, so it can be run on a FPGA. The synthesis step ensures that these requirements are met. In addition, it checks whether the code that is acceptable -for the Amaranth is also acceptable for the synthesis tools. +for Amaranth is also acceptable for the synthesis tools. The main properties collected in the synthesis step: - Max clock frequency @@ -70,23 +70,22 @@ In order to perform synthesis we use: ## Benchmarking -The maximum clock frequency determined by synthesis isn't the only measure of performance. Theoretically, there is always a -possibility to increase Fmax by increasing the latency. To avoid the pitfall of too long latency, we have introduced the monitoring -of instructions executed per clock cycle (IPC). This is done by simulating the core with cycle accuracy and running -benchmarks written in C inside the simulation. As benchmarking programs we use +The maximum clock frequency determined by synthesis isn't the only measure of performance. In theory, it is always +possible to increase Fmax by increasing latency. To avoid the pitfall of too long a latency, that cannot be compensated +by out-of-order execution, we monitor the number of instructions executed per clock cycle (IPC). We simulate the core +with cycle accuracy and run benchmarks written in C inside the simulation. The benchmarks are taken from [embench](https://github.com/embench/embench-iot/tree/master). -The benchmarking is done in two steps. First, we compile C programs into binary format and then run the binaries on -the simulated core. The compilation is done using [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with -glibc compiled for different architectural subsets of RISC-V extensions. The configuration of the riscv-gnu-toolchain used in -Coreblocks is described in [riscv-toolchain.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/riscv-toolchain.Dockerfile). -Benchmarks can be compiled once and used repeatedly as long as there is no need to add support for the new -RISC-V extensions or the embench isn't be updated. - -Once we have binaries, we can execute them in simulation. This is done with [Cocotb](https://github.com/cocotb/cocotb) and -[Verilator](https://github.com/verilator/verilator). First we generate Verilog code describing Coreblocks instance. -Then it is passed to Verilator for compilation and Cocotb controls the execution of the program, by stubbing external -interfaces. Compiled Verilator in a compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). +The benchmarking is done in two steps. First, we compile the C programs into binary format. Second, we run the binaries +on the simulated core. To compile the code we use [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), +with glibc configured for different architectural subsets of RISC-V extensions (you can check the exact configuration in +[riscv-toolchain.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/riscv-toolchain.Dockerfile)). + +Once we have the binaries, we can run them in simulation. This is done using [Cocotb](https://github.com/cocotb/cocotb) and +[Verilator](https://github.com/verilator/verilator). We use Amaranth features to generate Verilog code describing Coreblocks instance, +which is passed to Verilator for compilation. Cocotb controls the simulation and execution of the program by stubbing external +interfaces. Pre-compiled Verilator in a compatible version is available in [Verilator.Dockerfile](https://github.com/kuznia-rdzeni/coreblocks/blob/master/docker/Verilator.Dockerfile). + ### Benchmarks manual execution ```bash From 363609d7871e048e7f412ffdeee4075468419d37 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 19 Nov 2023 15:23:42 +0100 Subject: [PATCH 14/16] Fix IPC introduction --- docs/synthesis/Synthesis.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index e095d5972..5e2e5a003 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -71,11 +71,12 @@ In order to perform synthesis we use: ## Benchmarking The maximum clock frequency determined by synthesis isn't the only measure of performance. In theory, it is always -possible to increase Fmax by increasing latency. To avoid the pitfall of too long a latency, that cannot be compensated -by out-of-order execution, we monitor the number of instructions executed per clock cycle (IPC). We simulate the core -with cycle accuracy and run benchmarks written in C inside the simulation. The benchmarks are taken from +possible to increase Fmax by increasing latency. To avoid the pitfall of too long latency affecting the core +throughput, we monitor the number of instructions executed per clock cycle (IPC). We simulate the core with cycle +accuracy and run benchmarks written in C inside the simulation. The benchmarks are taken from [embench](https://github.com/embench/embench-iot/tree/master). + The benchmarking is done in two steps. First, we compile the C programs into binary format. Second, we run the binaries on the simulated core. To compile the code we use [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain), with glibc configured for different architectural subsets of RISC-V extensions (you can check the exact configuration in From 5d89258ed94b99156ba85e275523e4bca4646de6 Mon Sep 17 00:00:00 2001 From: Marek Materzok Date: Fri, 1 Dec 2023 23:21:12 +0100 Subject: [PATCH 15/16] Update docs/synthesis/Synthesis.md --- docs/synthesis/Synthesis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/synthesis/Synthesis.md b/docs/synthesis/Synthesis.md index 5e2e5a003..16ce52ba6 100644 --- a/docs/synthesis/Synthesis.md +++ b/docs/synthesis/Synthesis.md @@ -123,7 +123,7 @@ PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full ## Regression tests -Regression tests should ensure that Coreblocks is complaint with RISC-V specification requirements. Tests include +Regression tests should ensure that Coreblocks is compliant with RISC-V specification requirements. Tests include assembler programs that tests entire RISC-V instruction set. We execute these programs in a similar way to benchmarks. So, as a first step, we compile the programs to the binary format and then we run them on core simulated by Verilator and Cocotb. From 262b6f424aa5e0417bbce0cd8886f5287407c133 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 3 Dec 2023 20:02:33 +0100 Subject: [PATCH 16/16] Update docker tags to latest --- docs/synthesis/synthesis.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/synthesis/synthesis.md b/docs/synthesis/synthesis.md index 16ce52ba6..c1286fd6c 100644 --- a/docs/synthesis/synthesis.md +++ b/docs/synthesis/synthesis.md @@ -15,7 +15,7 @@ In the following subsections we provide the instructions on how to manually run They can be recreated using standard docker build commands: ``` -docker build --platform linux/amd64 -t "amaranth-synth:ecp5" -f ./docker/AmaranthSynthECP5.Dockerfile . +docker build --platform linux/amd64 -t "amaranth-synth:latest" -f ./docker/AmaranthSynthECP5.Dockerfile . ``` ## Synthesis @@ -39,8 +39,8 @@ The configuration of the docker container is described in the `AmaranthSynthECP5 ### Manual reproduction ```bash -sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 -sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:ecp5-3.11 +sudo docker pull ghcr.io/kuznia-rdzeni/amaranth-synth:latest +sudo docker run -it --rm ghcr.io/kuznia-rdzeni/amaranth-synth:latest git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks apt update @@ -96,9 +96,9 @@ git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks git submodule update --init --recursive cd .. -sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:latest # Run docker with the coreblocks directory mounted into it -sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:latest cd /coreblocks/test/external/embench # Compilation will put binaries in the subdirectory of the /coreblocks directory, which is shared with the host # so that binaries survive after the docker container is closed @@ -106,10 +106,10 @@ make exit # ========== STEP 2: Execution ========== -sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +sudo docker pull ghcr.io/kuznia-rdzeni/verilator:latest # Run docker with the coreblocks directory mounted into it. This directory contains # benchmark binaries after running the first step. -sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:latest apt update apt install python3.11-venv python3 -m venv venv @@ -136,9 +136,9 @@ git clone --depth=1 https://github.com/kuznia-rdzeni/coreblocks.git cd coreblocks git submodule update --init --recursive cd .. -sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +sudo docker pull ghcr.io/kuznia-rdzeni/riscv-toolchain:latest # Run docker with the coreblocks directory mounted into it -sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/riscv-toolchain:latest cd /coreblocks/test/external/riscv-tests # Compilation will put binaries in the subdirectory of the /coreblocks directory, which is shared with the host # so that binaries survive after the docker container is closed @@ -146,10 +146,10 @@ make exit # ========== STEP 2: Execution ========== -sudo docker pull ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +sudo docker pull ghcr.io/kuznia-rdzeni/verilator:latest # Run docker with the coreblocks directory mounted into it. This directory contains # regression test binaries after running the first step. -sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:v5.008-3.11 +sudo docker run -v ./coreblocks:/coreblocks -it --rm ghcr.io/kuznia-rdzeni/verilator:latest apt update apt install python3.11-venv python3 -m venv venv