├── .gitignore ├── figures └── Readme.md ├── out_rocket_state.log.tgz ├── out_rocket_state_cascade.log.tgz ├── design_repos.json ├── Makefile ├── step_descriptions.md ├── Readme.md ├── Dockerfile └── config-mixins.scala /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.png 3 | -------------------------------------------------------------------------------- /figures/Readme.md: -------------------------------------------------------------------------------- 1 | The figures should be copied into here using the `docker cp` commands described in `Readme.md`. 2 | -------------------------------------------------------------------------------- /out_rocket_state.log.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comsec-group/cascade-artifacts/HEAD/out_rocket_state.log.tgz -------------------------------------------------------------------------------- /out_rocket_state_cascade.log.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comsec-group/cascade-artifacts/HEAD/out_rocket_state_cascade.log.tgz -------------------------------------------------------------------------------- /design_repos.json: -------------------------------------------------------------------------------- 1 | { 2 | "cva6": "/cascade-cva6/cascade", 3 | "cva6-c1": "/cascade-cva6-c1/cascade", 4 | "cva6-y1": "/cascade-cva6-y1/cascade", 5 | "rocket": "/cascade-chipyard/cascade-rocket", 6 | "boom": "/cascade-chipyard/cascade-boom", 7 | "boom-b1": "/cascade-chipyard-b1/cascade-boom", 8 | "picorv32": "/cascade-picorv32/cascade", 9 | "picorv32-p5": "/cascade-picorv32-p5/cascade", 10 | "kronos": "/cascade-kronos/cascade", 11 | "kronos-k1": "/cascade-kronos-k1/cascade", 12 | "kronos-k2": "/cascade-kronos-k2/cascade", 13 | "vexriscv": "/cascade-vexriscv/cascade", 14 | "vexriscv-v1-7": "/cascade-vexriscv-v1-7/cascade", 15 | "vexriscv-v8-9-v15": "/cascade-vexriscv-v8-9-v15/cascade", 16 | "vexriscv-v10-11": "/cascade-vexriscv-v10-11/cascade", 17 | "vexriscv-v12": "/cascade-vexriscv-v12/cascade", 18 | "vexriscv-v13": "/cascade-vexriscv-v13/cascade" 19 | } 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Flavien Solt, ETH Zurich. 2 | # Licensed under the General Public License, Version 3.0, see LICENSE for details. 3 | # SPDX-License-Identifier: GPL-3.0-only 4 | 5 | DOCKER_CASCADE_MOUNTDIR = /cascade-mountdir 6 | # Wherever you want to mount the cascade-mountdir to share the files with the Docker container 7 | LOCAL_CASCADE_MOUNTDIR ?= /scratch/flsolt/dockerrungenelf/cascade-mountdir 8 | 9 | IMAGE_TAG ?= ethcomsec/cascade-artifacts 10 | 11 | out_rocket_state_cascade.log: 12 | tar -xzf out_rocket_state_cascade.log.tgz 13 | out_rocket_state.log: 14 | tar -xzf out_rocket_state.log.tgz 15 | 16 | build: out_rocket_state_cascade.log out_rocket_state.log 17 | # docker build -t $(IMAGE_TAG) . 18 | docker build -t $(IMAGE_TAG) . 2>&1 | tee build.log 19 | 20 | run: 21 | docker run -it $(IMAGE_TAG) 22 | 23 | rungenelf: 24 | docker run -v $(LOCAL_CASCADE_MOUNTDIR):/$(DOCKER_CASCADE_MOUNTDIR) -it $(IMAGE_TAG) bash -c "source /cascade-meta/env.sh && python3 /cascade-meta/fuzzer/do_genelfs_for_questa.py" 25 | 26 | push: 27 | docker login registry-1.docker.io 28 | docker push $(IMAGE_TAG) 29 | -------------------------------------------------------------------------------- /step_descriptions.md: -------------------------------------------------------------------------------- 1 | ## Mapping of the steps in the paper's Figure 3 to the artifact code 2 | 3 | The fuzzer code is present in the [cascade-meta](https://github.com/cascade-artifacts-designs/cascade-meta). 4 | 5 | ### High-level overview 6 | 7 | The function `run_rtl` from `cascade.fuzzfromdescriptor` regroups all steps until and including the DUT run. 8 | The function `reduce_program` from `cascade.reduce` regroups the remaining steps, which concern program reduction. 9 | 10 | ### Step 1: CPU params & calibration 11 | 12 | This step is twofold. 13 | 14 | #### Parameters 15 | 16 | For each design, a small set of parameters such as the supported RISC-V extensions, are exposed by each design repository in the respective `cascade/meta/cfg.json` file, for example [here](https://github.com/cascade-artifacts-designs/cascade-kronos/blob/master/cascade/meta/cfg.json). 17 | 18 | #### Calibration 19 | 20 | The calibration step aims at (a) calibrating the spike speed to estimate an expected upper bound of valid executions, and (b) finding which delegation bits are supported by the design. 21 | These two steps can be 22 | 23 | The first calibration step (a) is performed by the function `calibrate_spikespeed()`. 24 | The second calibration step (b) is performed by the function `profile_get_medeleg_mask(design_name)`. 25 | 26 | ### Step 2: Basic block generation 27 | 28 | The basic block generation step is performed by the function `gen_basicblocks(fuzzerstate)`, where fuzzerstate is a freshly instantiated `FuzzerState` object. 29 | This function returns the list of basic blocks that is used for the intermediate program in the asymmetric ISA pre-simulation. 30 | 31 | ### Steps 3 & 4: Asymmetric ISA pre-simulation 32 | 33 | The asymmetric ISA pre-simulation is performed by the function `spike_resolution(fuzzerstate)`, where fuzzerstate is the state of the fuzzer after the basic block generation step. 34 | This function is mainly composed of two parts, which represent the steps 3 and 4 of the paper's Figure 3. 35 | 36 | #### Step 3: ISS run 37 | 38 | The ISS run is itself composed of two main parts. 39 | First, the function `gen_regdump_reqs(fuzzerstate)` generates the register dump requests for the basic blocks in the intermediate program, that will be provided to the ISS for scheduling the architectural dumps at the key points of the program execution. 40 | Second, the function `run_trace_regs_at_pc_locs()`, based on the register dump requests generated by the previous function, runs the ISS and dumps the architectural register values at the key points of the program execution. 41 | 42 | #### Step 4: Feedback integration 43 | 44 | Once the feedback is acquired, the function `_feed_regdump_to_instrs(fuzzerstate, regdumps)` is called to integrate the feedback into the program, effectively constructing the ultimate program. 45 | 46 | ### Step 5: DUT run 47 | 48 | The function `runtest_simulator` from `cascade.fuzzsim` runs the ultimate program on the DUT. 49 | 50 | ### Steps 6+: Analysis 51 | 52 | The function `reduce_program` from `cascade.reduce` performs the analysis steps, which are the steps 6+ of the paper's Figure 3. 53 | This function reuses functions used in previous steps, and mostly uses the following functions that reduce the program on both sides: `_find_failing_bb`, `_find_pillar_bb`, `_find_failing_instr_in_bb`, `_find_pillar_instr` . 54 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Artifacts Evaluation - README - Usenix Security 2024 2 | 3 | ## For Paper: Cascade: CPU Fuzzing via Intricate Program Generation 4 | 5 | ### Overview 6 | 7 | Welcome to the artifacts for Cascade! 8 | This repository will help you reproduce the results presented in our paper, and will get you started with Cascade without worrying too much about setting up the context. 9 | For more information about Cascade, visit https://comsec.ethz.ch/cascade. 10 | Most of the fuzzing code is located here https://github.com/cascade-artifacts-designs/cascade-meta. 11 | 12 | The repository is structured as follows. 13 | First, we indicate a few requirements. 14 | Second, we provide a step-by-step guide to reproduce the results in our paper. 15 | 16 | We recommend using the provided Docker image to reproduce the results. 17 | All experiments, except the Questasim experiment, run inside a Docker container. 18 | The Questasim experiment is optional as its only purpose is to compare the simulator coverage of Cascade and TheHuzz. 19 | 20 | ### Requirements 21 | 22 | Some experiments require 64 cores, however, it can be run with less cores, we do not expect a big difference in the results. 23 | 24 | One optional experiment, which will be explicitly marked, requires access to Questasim (a commercial RTL simulator). 25 | No other experiment depends on these results, hence non-Questasim users can safely ignore this experiment and run the rest of the artifacts. 26 | 27 | ### Step-by-step guide 28 | 29 | #### Obtain the Docker image. (Human time: 1 minute. Computer time: up to some hours.) 30 | 31 | If you are willing to use the Docker image, here is how to proceed. 32 | Else, we recommend to mimic the structure of the repositories as described in the Dockerfile. 33 | 34 | ``` 35 | docker pull docker.io/ethcomsec/cascade-artifacts 36 | ``` 37 | 38 | #### Start a container using the Docker image. (Human time: some minutes, on and off. Computer time: some minutes.) 39 | 40 | All relevant experiments have already been reproduced inside this image. 41 | We made the steps explicit in the Dockerfile. 42 | The Dockerfile is hence also a convenient reference on how to run each experiment. 43 | 44 | First, start a new container with the image: 45 | 46 | ``` 47 | docker run -it docker.io/ethcomsec/cascade-artifacts 48 | ``` 49 | 50 | This procedure assumes you don't want to rebuild everything from scratch, although you can re-run commmands that are presented in the Dockerfile. 51 | 52 | 53 | Instead, if you would like to rebuild the Docker image, simply run `make build` in the current repository, which will re-build the whole Docker image from scratch. 54 | This will take many hours to execute. 55 | 56 | In this Docker container, we limited the computation for Figure 16 to 30 seconds per point to finish in reasonable time. 57 | The value used in the paper is 1200 seconds, which may require multiple days to run, on a 64-core machine. 58 | The duration of 30 seconds is sufficient to support the claim made in the paper that longer programs tend to be more efficient at finding bugs. 59 | This timeout can be modified by adapting the line `ENV TIMEOUT_SECONS_PER_BUG=30` in the Dockerfile with a value of your choice. 60 | 61 | The following error messages are expected, and can be safely ignored: 62 | ``` 63 | SIMLEN environment variable not set. 64 | make: *** [Makefile:129: run_vanilla_notrace] Error 1 65 | ``` 66 | 67 | #### Re-running individual experiments 68 | 69 | You can re-run individual experiments by re-executing lines of the Dockerfile in the docker container. 70 | 71 | Make sure that your Verilator version in the Docker container is correct. 72 | If you get the following error: 73 | 74 | ``` 75 | ERROR: %Error: Unknown warning specified: -Wno-EOFNEWLINE 76 | ``` 77 | 78 | Then please reinstall the newer version of Verilator: 79 | ``` 80 | rm -rf verilator && git clone https://github.com/verilator/verilator && cd verilator && git checkout v5.006 && autoconf && ./configure && make -j 200 && make install 81 | ``` 82 | 83 | #### Plots 84 | 85 | All plots, except for the Questasim experiment, are stored in the `/cascade-meta/figures` directory inside the Docker container, and have been generated as indicated in the Dockerfile. 86 | 87 | ##### Extracting plots from the Docker container 88 | 89 | You must first run a container, for example using the command `make run`. 90 | You can then see the container id, for example, from the command prompt that you get after running `make run`, for example, `root@ac674f329a7b:/#` signifies that the container id is `ac674f329a7b`. 91 | 92 | You can now copy out the figures from the container to your host machine, for example, using the following commands: 93 | ``` 94 | mkdir -p figures 95 | docker cp :/cascade-meta/figures/bug_categories.png figures 96 | docker cp :/cascade-meta/figures/cascade_dependencies.png figures 97 | docker cp :/cascade-meta/figures/cascade_prevalences.png figures 98 | docker cp :/cascade-meta/figures/difuzzrtl_completions.png figures 99 | docker cp :/cascade-meta/figures/difuzzrtl_coverage.png figures 100 | docker cp :/cascade-meta/figures/difuzzrtl_dependencies.png figures 101 | docker cp :/cascade-meta/figures/difuzzrtl_prevalences.png figures 102 | docker cp :/cascade-meta/figures/reduction_perf.png figures 103 | docker cp :/cascade-meta/figures/rfuzz.png figures 104 | docker cp :/cascade-meta/figures/security_implications.png figures 105 | docker cp :/cascade-meta/figures/bug_timings_curves.png figures 106 | docker cp :/cascade-meta/figures/execperf_programlength.png figures 107 | docker cp :/cascade-meta/figures/fuzzperf_programlength.png figures 108 | docker cp :/cascade-meta/figures/genduration_programlength.png figures 109 | docker cp :/cascade-meta/figures/fuzzperf.png figures 110 | ``` 111 | 112 | ##### Mapping to the paper's figures 113 | 114 | Mapping to the paper's figures: 115 | 116 | | Figure in paper | Figure in artifacts | 117 | | --------------- | ------------------------- | 118 | | 1 | difuzzrtl_completions | 119 | | 2 | difuzzrtl_prevalences | 120 | | 3 | - | 121 | | 4 | - | 122 | | 5 | - | 123 | | 6 | fuzzperf | 124 | | 7 | execperf_programlength | 125 | | 8 | genduration_programlength | 126 | | 9 | fuzzperf_programlength | 127 | | 10 | cascade_prevalences | 128 | | 11 | difuzzrtl_dependencies | 129 | | 12 | cascade_dependencies | 130 | | 13 | difuzzrtl_coverage | 131 | | 14 | rfuzz | 132 | | 15 | [optional -- modelsim] | 133 | | 16 | bug_timings_curves | 134 | | 17 | bug_categories | 135 | | 18 | bug_detection_timings | 136 | | 19 | security_implications | 137 | | 20 | reduction_perf | 138 | 139 | #### Re-producing the register coverage of Cascade and DifuzzRTL 140 | 141 | For convenience, we provide the logs of the execution of Cascade and DifuzzRTL as `.log.tgz` files. 142 | To reproduce the results, we kindly redirect you to [the dedicated repository](https://github.com/cascade-artifacts-designs/cascade-difuzzrtl-verilator/#cascade-artifacts-regarding-the-collection-of-the-difuzzrtl-coverage-metric). 143 | 144 | #### Questasim experiment (Optional) 145 | 146 | The Questasim experiment, optional, is the only experiment that must be partially run outside of the Docker container. 147 | The experiment requires the presence of the executables `vsim`, `vlog` and `vcover` in the PATH. 148 | 149 | You will also require fusesoc, as also installed in the Dockerfile. 150 | ``` 151 | pip3 install fusesoc 152 | ``` 153 | 154 | You will need to clone `cascade-meta` and `cascade-chipyard` (containing the Rocket core) locally. 155 | If potential requirements are missing, ensure to reproduce the first line of the Dockerfile, directly on your machine. 156 | 157 | To initialize cascade-chipyard, please run, like done in the Dockerfile: 158 | ``` 159 | source /path/to/cascade-meta && cd /path/to/cascade-chipyard && git branch stable && CASCADE_JOBS=250 scripts/init-submodules-no-riscv-tools.sh -f 160 | ``` 161 | Then, build the Rocket core for the Questasim simulation: 162 | ``` 163 | source /path/to/cascade-meta && cd /path/to/cascade-chipyard/cascade && make build_vanilla_notrace_modelsim && make rerun_vanilla_notrace_modelsim 164 | ``` 165 | 166 | You may have to adapt the `rocket` entry in the local `cascade_meta/design_processing/design_repos.json` for running the experiment. 167 | 168 | To run the Questasim experiment, first start a new container with the image and generate the ELF files for DifuzzRTL and Cascade (this may take some hours). 169 | Note that we could have done this in the Dockerfile but the resulting Docker image would be very large. 170 | You must also choose a local directory where the ELFs directory will be mounted (make sure to have the proper permissions); alternatively, instead of mounting using the `-v` flag, you could copy out the ELFs by using `docker ps` and then `docker cp`. 171 | All this can be done, for example, as follows: 172 | ``` 173 | DIFUZZRTL_FUZZER_DIR_PATH_CANDIDATE= docker run -v /path/to/some/mount/directory:/cascade-mountdir -it cascade-artifacts bash -c "source /cascade-meta/env.sh && python3 /cascade-meta/fuzzer/do_genelfs_for_questa.py" 174 | ``` 175 | 176 | Ensure that you have the Python requirements installed by the Dockerfile on your host machine. 177 | Please install any additional Python requirement that would be requested during the course of the experiment, for instance: 178 | ``` 179 | pip3 install matplotlib numpy tqdm filelock 180 | ``` 181 | 182 | Finally, run the experiment, first indicating where the ELFs are now located (the directory you mounted): 183 | ``` 184 | export CASCADE_PATH_TO_DIFUZZRTL_ELFS_FOR_MODELSIM=/path/to/some/mount/directory 185 | cd /fuzzer && python3 do_compare_cascade_difuzzrtl_modelsim.py 186 | ``` 187 | 188 | The experiment may take many hours and can be divided in two parts: 189 | 1. Running the fuzzer. This can be done in parallel. 190 | 2. Merging the coverage results. This must be done sequentially to get the coverage achieved at each step. 191 | The result is stored in the file `modelsim.png` in the local `cascade-meta/figures` directory. 192 | 193 | ![cascade logo](https://github.com/comsec-group/cascade-artifacts/assets/28906668/0fbbf474-4479-4bf9-96df-43c520f3ae8e) 194 | 195 | ### Additional information 196 | 197 | #### Description of detailed steps 198 | 199 | In `step_descriptions.md`, we provide a mapping of the overview figure from the paper (Figure 3). 200 | 201 | #### A minimal running example 202 | 203 | To run a minimal example, you can follow the following steps: 204 | 205 | First, adapt `descriptor` in `cascade-meta/fuzzer/do_fuzzsingle.py` to the parameters of your choice in terms of memory size, target design, random seed, maximal number of basic blocks and inclusion of privileged instructions. 206 | Second, run this script through `python3 cascade-meta/fuzzer/do_fuzzsingle.py`. 207 | This will execute all steps until and including the DUT run. 208 | If you would like, instead, to fuzz with many programs, use `python3 cascade-meta/fuzzer/do_fuzzdesign.py` instead. Please check the file header comments on which are the command-line parameters. 209 | 210 | Assuming that this run raises a non-termination or mismatch, you can then run the reduction step through `python3 cascade-meta/fuzzer/do_reducesingle.py`, after setting its `descriptor` variable to the same value as in the fuzzing step. 211 | This will execute all steps from the reduction step onwards and produce two executable files, whose difference reveals the head and tail instructions. 212 | 213 | #### Incorporating a new design 214 | 215 | To incorporate a new design and fuzz it with Cascade, please take the two following steps: 216 | - Create a design repository, based on the existing design examples. In particular, create a `/cascade/meta` directory that a few essential configuration information for Cascade. You will have to create the `make run_vanilla_notrace`. You may, but do not have to, adapt `cascade-meta/fuzzer/cascade/fuzzsim.py` according to your needs. 217 | - Add an entry with the name of your choice in `cascade-meta/design-processing/design_repos.json`. 218 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Flavien Solt, ETH Zurich. 2 | # Licensed under the General Public License, Version 3.0, see LICENSE for details. 3 | # SPDX-License-Identifier: GPL-3.0-only 4 | 5 | FROM ubuntu:latest 6 | ENV DEBIAN_FRONTEND=noninteractive 7 | RUN apt-get update && apt-get install -y curl gnupg apt-utils && \ 8 | apt-get install -y apt-transport-https curl gnupg git perl python3 make autoconf g++ flex bison ccache libgoogle-perftools-dev numactl perl-doc libfl2 libfl-dev zlib1g zlib1g-dev \ 9 | autoconf automake autotools-dev libmpc-dev libmpfr-dev libgmp-dev gawk build-essential \ 10 | bison flex texinfo gperf libtool patchutils bc zlib1g-dev git perl python3 python3.10-venv make g++ libfl2 \ 11 | libfl-dev zlib1g zlib1g-dev git autoconf flex bison gtkwave clang \ 12 | tcl-dev libreadline-dev jq libexpat-dev device-tree-compiler vim \ 13 | software-properties-common default-jdk default-jre gengetopt patch diffstat texi2html subversion chrpath wget libgtk-3-dev gettext python3-pip python3.8-dev rsync libguestfs-tools expat \ 14 | libexpat1-dev libusb-dev libncurses5-dev cmake help2man && \ 15 | apt-get install apt-transport-https curl gnupg -yqq 16 | 17 | RUN add-apt-repository -y ppa:openjdk-r/ppa && \ 18 | apt-get install -y openjdk-8-jre && update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 111111 && \ 19 | apt-get install -y openjdk-8-jdk && update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-8-openjdk-amd64/bin/javac 111111 && \ 20 | echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee /etc/apt/sources.list.d/sbt.list && \ 21 | echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee /etc/apt/sources.list.d/sbt_old.list && \ 22 | curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import && \ 23 | chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg && \ 24 | apt-get update && apt-get install sbt 25 | 26 | # Install oh my zsh and some convenience plugins 27 | RUN apt-get install -y zsh && sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 28 | RUN git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions 29 | RUN git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting 30 | RUN sed -i 's/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting)/' /root/.zshrc 31 | 32 | # Install RISC-V toolchain 33 | RUN apt-get install -y autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build 34 | ENV RISCV="/opt/riscv" 35 | RUN git clone https://github.com/riscv/riscv-gnu-toolchain 36 | RUN cd riscv-gnu-toolchain && git checkout 2023.06.09 && ./configure --prefix=/opt/riscv --enable-multilib && make -j 200 37 | ENV PATH="$PATH:/opt/riscv/bin" 38 | 39 | # Install spike 40 | RUN git clone https://github.com/riscv-software-src/riscv-isa-sim.git 41 | RUN cd riscv-isa-sim && mkdir build && cd build && ../configure --prefix=$RISCV && make -j 200 && make install 42 | 43 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-yosys /cascade-yosys 44 | RUN cd cascade-yosys && make -j 200 && make install 45 | 46 | # Some environment variables 47 | ENV PREFIX_CASCADE="$HOME/prefix-cascade" 48 | ENV CARGO_HOME=$PREFIX_CASCADE/.cargo 49 | ENV RUSTUP_HOME=$PREFIX_CASCADE/.rustup 50 | 51 | ENV RUSTEXEC="$CARGO_HOME/bin/rustc" 52 | ENV RUSTUPEXEC="$CARGO_HOME/bin/rustup" 53 | ENV CARGOEXEC="$CARGO_HOME/bin/cargo" 54 | 55 | # Install Rust 56 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 57 | 58 | # Install Morty 59 | RUN $CARGOEXEC install --force morty --root $PREFIX_CASCADE 60 | 61 | # Install Bender 62 | RUN $CARGOEXEC install --force bender --root $PREFIX_CASCADE 63 | 64 | # Install fusesoc 65 | RUN pip3 install fusesoc 66 | 67 | # Install stack 68 | RUN curl -sSL https://get.haskellstack.org/ | sh 69 | 70 | # Install sv2v 71 | RUN git clone https://github.com/zachjs/sv2v.git && cd sv2v && git checkout v0.0.11 && make -j 200 && mkdir -p $PREFIX_CASCADE/bin/ && cp bin/sv2v $PREFIX_CASCADE/bin 72 | 73 | # Install some Python dependencies 74 | RUN pip3 install tqdm 75 | 76 | # Install makeelf 77 | RUN git clone https://github.com/flaviens/makeelf && cd makeelf && git checkout finercontrol && python3 setup.py install 78 | 79 | # Install miniconda 80 | RUN mkdir -p miniconda && wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda/miniconda.sh \ 81 | && cd miniconda/ && bash miniconda.sh -u -b -p $PREFIX_CASCADE/miniconda \ 82 | && $PREFIX_CASCADE/miniconda/bin/conda update -y -n base -c defaults conda \ 83 | && $PREFIX_CASCADE/miniconda/bin/conda config --add channels conda-forge \ 84 | && $PREFIX_CASCADE/miniconda/bin/conda config --set channel_priority strict 85 | 86 | # Install Verilator 87 | RUN git clone https://github.com/verilator/verilator && cd verilator && git checkout v5.006 && autoconf && ./configure && make -j 200 && make install 88 | 89 | ## 90 | # Design repositories 91 | ## 92 | 93 | RUN echo "Cloning the repositories!" 94 | 95 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-picorv32 96 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-kronos 97 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv --recursive 98 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-cva6 --recursive 99 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-chipyard 100 | 101 | 102 | # Initialize the chipyard repository 103 | RUN bash -c "cd cascade-chipyard && git branch stable && CASCADE_JOBS=250 scripts/init-submodules-no-riscv-tools.sh -f" 104 | 105 | # Design repositories with embedded bugs 106 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-cva6-c1 --recursive 107 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-cva6-y1 --recursive 108 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-chipyard-b1 109 | 110 | # Make sure to fix the BOOM bug 111 | RUN sed -i 's/r_buffer_fin.rm := io.fcsr_rm/r_buffer_fin.rm := Mux(ImmGenRm(io.req.bits.uop.imm_packed) === 7.U, io.fcsr_rm, ImmGenRm(io.req.bits.uop.imm_packed))/' /cascade-chipyard/generators/boom/src/main/scala/exu/execution-units/fdiv.scala 112 | 113 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-picorv32-p5 114 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-kronos-k1 115 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-kronos-k2 116 | 117 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv-v1-7 --recursive 118 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv-v8-9-v15 --recursive 119 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv-v10-11 --recursive 120 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv-v12 --recursive 121 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-vexriscv-v13 --recursive 122 | 123 | # Initialize the chipyard-b1 repository 124 | RUN bash -c "cd cascade-chipyard-b1 && git branch stable && CASCADE_JOBS=250 scripts/init-submodules-no-riscv-tools.sh -f" 125 | 126 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-meta --recursive 127 | 128 | # Set the design repo locations correctly for the Docker environment 129 | COPY design_repos.json /cascade-meta/design-processing/design_repos.json 130 | 131 | ENV PATH="$PATH:$PREFIX_CASCADE/bin" 132 | 133 | # Make sure that the Chipyard will support supervisor mode 134 | RUN sed -i 's/useSupervisor: Boolean = false,/useSupervisor: Boolean = true,/' /cascade-chipyard/generators/boom/src/main/scala/common/parameters.scala 135 | RUN sed -i 's/r_buffer_fin.rm := io.fcsr_rm,/r_buffer_fin.rm := Mux(ImmGenRm(io.req.bits.uop.imm_packed) === 7.U, io.fcsr_rm, ImmGenRm(io.req.bits.uop.imm_packed))/' /cascade-chipyard/generators/boom/src/main/scala/exu/execution-units/fdiv.scala 136 | COPY config-mixins.scala /cascade-chipyard/generators/boom/src/main/scala/common 137 | RUN sed -i 's/useSupervisor: Boolean = false,/useSupervisor: Boolean = true,/' /cascade-chipyard-b1/generators/boom/src/main/scala/common/parameters.scala 138 | COPY config-mixins.scala /cascade-chipyard-b1/generators/boom/src/main/scala/common 139 | 140 | # Make all non-instrumented designs for Verilator (and the transparently instrumented for bug Y1) 141 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/design-processing && python3 -u make_all_designs.py" 142 | # A second time to be sure 143 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/design-processing && python3 -u make_all_designs.py" 144 | 145 | RUN pip3 install numpy matplotlib filelock 146 | 147 | ## 148 | # Program metrics for Cascade 149 | ## 150 | 151 | # This generates the plots `cascade_prevalences.png` and `cascade_dependencies.png`. 152 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 -u do_analyze_cascade_elfs.py" 153 | 154 | ## 155 | # Bug bar plots for Cascade 156 | ## 157 | 158 | # This generates the plots `bug_categories.png` and `security_implications.png`. 159 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_plot_bug_bars.py" 160 | 161 | ## 162 | # Program reduction performance for Cascade 163 | ## 164 | 165 | # Make sure vanilla boom was made correctly. 166 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-chipyard/cascade-boom && make run_vanilla_notrace" || true 167 | 168 | # Program reduction performance for Cascade. This generates `reduction_perf.png`. 169 | # In particular, many occurrences of `Failed test_run_rtl_single for params` are expected: they precisely correspond to occurrences of bugs found, during the test case generation and during their reduction. 170 | # The final number in the bash command can be changed to add more repetitions. 171 | # For unknown reasons, this command may not dump the final `reduction_perf.png` file, so we run do_plotevalreduction.py next. 172 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 -u do_evalreduction.py 10" 173 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_plotevalreduction.py 10" 174 | 175 | ## 176 | # Performance microbenchmarks for Cascade 177 | ## 178 | 179 | # This generates `fuzzperf.png`, the microbenchmark for program construction performance. 180 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_fuzzperf.py" 181 | 182 | ## 183 | # Microbenchmarks for program lengths 184 | ## 185 | 186 | # Create perf_ubenchmark_fewinstructions.json 187 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_performance_ubenchmark_fewinstructions.py 0 60 64" 188 | # From perf_ubenchmark_fewinstructions.json, make the 3 plots 189 | 190 | RUN bash -c "apt-get update && apt-get install locales && dpkg-reconfigure locales && pip3 install utf8-locale" 191 | 192 | # Locales may pose some difficulties in some machines, and are just here for text pretty-printing 193 | RUN sed -i "s/ locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/# locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/" /cascade-meta/fuzzer/do_plot_fewinstr_genduration_programlength.py 194 | RUN sed -i "s/ locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/# locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/" /cascade-meta/fuzzer/do_plot_fewinstr_fuzzperf_programlength.py 195 | RUN sed -i "s/ locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/# locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')/" /cascade-meta/fuzzer/do_plot_fewinstr_execperf_programlength.py 196 | 197 | # Generate genduration_programlength.png 198 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_plot_fewinstr_genduration_programlength.py" 199 | # Generate fuzzperf_programlength.png 200 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_plot_fewinstr_fuzzperf_programlength.py" 201 | # Generate execperf_programlength.png 202 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_plot_fewinstr_execperf_programlength.py" 203 | 204 | 205 | ## 206 | # Bug detection performance for Cascade 207 | ## 208 | 209 | # To reproduce the complete figure, this must be set to 1200 (on 64 cores). But this may take multiple days to complete. This smaller timeout value of 30 seconds is already confirming the trend shown in the paper. Feel free to increase it if you have compute time available. 210 | ENV TIMEOUT_SECONS_PER_BUG=30 211 | # This generates `bug_detection_timings.png`, which corresponds to the time required to find each bug. 212 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_timetobug.py 64 10 $TIMEOUT_SECONS_PER_BUG" 213 | 214 | ## 215 | # Bug detection performance for various program lengths 216 | ## 217 | 218 | RUN sed -i 's/json.load(open("perf_ubenchmark_fewinstructions.json/json.load(open("bug_timings_curves.json/' /cascade-meta/fuzzer/do_timetobugplot_curves.py 219 | 220 | # This generates `bug_timings_curves.png`, which corresponds to the time required to find each bug. 221 | # The parameters must match the parameters given to do_timetobug.py 222 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_timetobugplot_curves.py 64 10 $TIMEOUT_SECONS_PER_BUG 15" 223 | 224 | # Generates bug_detection_timings.png 225 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_timetobug_boxes.py 64 10" 226 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_timetobug_boxes_plot.py 64 10" 227 | 228 | 229 | ## 230 | # RFUZZ performance 231 | ## 232 | 233 | # Prepare the designs to run with the RFUZZ instrumentation and fuzzer. 234 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/design-processing && python3 make_all_designs.py rfuzz && python3 make_all_designs.py drfuzz" || true 235 | 236 | # Run the RFUZZ experiment, generates `rfuzz.png`. 237 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_rfuzz.py" 238 | 239 | ## 240 | # DifuzzRTL 241 | ## 242 | 243 | # For the control register coverage comparison, we provide the execution trace, since the experiment is very long and generates a large amount of ELFs (in the order of 60000). 244 | # To produce the logs: 245 | # - For DifuzzRTL, run `cd /cascade-difuzzrtl/docker/shareddir/savedockerdifuzzrtl/Fuzzer && make SIM_BUILD=builddir VFILE=RocketTile_state TOPLEVEL=RocketTile NUM_ITER=50000 OUT=outdir_difuzz IS_CASCADE=0 IS_RECORD=0 SPIKE=/opt/riscv/bin/spike` 246 | # - For Cascade, first generate 5000 ELFs using `python3 genmanyelfs.py 5000` in cascade-meta, then apply `python3 cascade_elf_to_hex.py` in cascade-difuzzrtl (by adapting the paths), and finally run `cd /cascade-difuzzrtl/docker/shareddir/savedockerdifuzzrtl/Fuzzer && make SIM_BUILD=builddir VFILE=RocketTile_state TOPLEVEL=RocketTile NUM_ITER=50000 OUT=outdir_cascade IS_CASCADE=1 IS_RECORD=0 SPIKE=/opt/riscv/bin/spike` 247 | # In these "make" recipes, make sure to execute the correct (legacy) versions of cocotb and Verilator 248 | COPY out_rocket_state.log.tgz / 249 | COPY out_rocket_state_cascade.log.tgz / 250 | 251 | # Compare the control register coverage. This generates `difuzzrtl_coverage.png`. 252 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_collect_difuzz_coverage.py" 253 | 254 | # Install elf2hex 255 | RUN git clone https://github.com/sifive/elf2hex.git 256 | RUN cd elf2hex && autoreconf -i && ./configure --target=riscv64-unknown-elf && make -j 200 && make install 257 | # Fix some cpp files 258 | RUN sed -i 's/objcopy=""/objcopy="riscv64-unknown-elf-objcopy"/' /usr/local/bin/riscv64-unknown-elf-elf2hex 259 | 260 | # Install cocotb 261 | RUN echo "host" | apt install -y make gcc g++ python3 python3-dev python3-pip 262 | RUN ln -s /usr/bin/python3 /usr/bin/python 263 | RUN pip3 install cocotb==1.5.2 264 | 265 | # Install verilator-v4.106 266 | RUN rm -rf verilator && git clone https://github.com/verilator/verilator.git && cd verilator && git checkout v4.106 && autoconf && ./configure && make -j200 267 | RUN cd verilator && make install 268 | RUN sed -i 's|#include |&\n#include |' /usr/local/share/verilator/include/verilated.cpp 269 | 270 | RUN pip3 install psutil sysv_ipc 271 | 272 | RUN git clone https://github.com/cascade-artifacts-designs/cascade-difuzzrtl.git 273 | 274 | # DifuzzRTL program metrics (Figures 1, 2 and 3) 275 | # Create 500 random ELF files 276 | RUN cd /cascade-difuzzrtl/docker/shareddir/savedockerdifuzzrtl/Fuzzer && make SIM_BUILD=builddir VFILE=RocketTile_state TOPLEVEL=RocketTile NUM_ITER=500 OUT=outdir IS_CASCADE=0 IS_RECORD=1 SPIKE=/opt/riscv/bin/spike 277 | 278 | # Analyze the DifuzzRTL program metrics. This generates `difuzzrtl_dependencies.png`, `difuzzrtl_prevalences.png` and `difuzzrtl_completions.png` 279 | RUN bash -c "source /cascade-meta/env.sh && cd /cascade-meta/fuzzer && python3 do_analyze_difuzzrtl_elfs.py 500" 280 | 281 | RUN cp /cascade-meta/fuzzer/bug_timings_curves.png /cascade-meta/figures 282 | RUN cp /cascade-meta/fuzzer/execperf_programlength.png /cascade-meta/figures 283 | RUN cp /cascade-meta/fuzzer/fuzzperf_programlength.png /cascade-meta/figures 284 | RUN cp /cascade-meta/fuzzer/genduration_programlength.png /cascade-meta/figures 285 | RUN cp /cascade-data/fuzzperf.png /cascade-meta/figures 286 | 287 | # The Questasim results must be generated outside of this container (but using it to generate ELFs), on a machine that has Questasim installed. 288 | -------------------------------------------------------------------------------- /config-mixins.scala: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // Copyright (c) 2015 - 2018, The Regents of the University of California (Regents). 3 | // All Rights Reserved. See LICENSE and LICENSE.SiFive for license details. 4 | //------------------------------------------------------------------------------ 5 | 6 | package boom.common 7 | 8 | import chisel3._ 9 | import chisel3.util.{log2Up} 10 | 11 | import freechips.rocketchip.config.{Parameters, Config, Field} 12 | import freechips.rocketchip.subsystem._ 13 | import freechips.rocketchip.devices.tilelink.{BootROMParams} 14 | import freechips.rocketchip.diplomacy.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing} 15 | import freechips.rocketchip.rocket._ 16 | import freechips.rocketchip.tile._ 17 | 18 | import boom.ifu._ 19 | import boom.exu._ 20 | import boom.lsu._ 21 | 22 | // --------------------- 23 | // BOOM Config Fragments 24 | // --------------------- 25 | 26 | class WithBoomCommitLogPrintf extends Config((site, here, up) => { 27 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 28 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 29 | enableCommitLogPrintf = true 30 | ))) 31 | case other => other 32 | } 33 | }) 34 | 35 | 36 | class WithBoomBranchPrintf extends Config((site, here, up) => { 37 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 38 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 39 | enableBranchPrintf = true 40 | ))) 41 | case other => other 42 | } 43 | }) 44 | 45 | class WithNBoomPerfCounters(n: Int) extends Config((site, here, up) => { 46 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 47 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 48 | nPerfCounters = n 49 | ))) 50 | case other => other 51 | } 52 | }) 53 | 54 | 55 | class WithSynchronousBoomTiles extends Config((site, here, up) => { 56 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 57 | case tp: BoomTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( 58 | crossingType = SynchronousCrossing() 59 | )) 60 | case other => other 61 | } 62 | }) 63 | 64 | class WithAsynchronousBoomTiles extends Config((site, here, up) => { 65 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 66 | case tp: BoomTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( 67 | crossingType = AsynchronousCrossing() 68 | )) 69 | case other => other 70 | } 71 | }) 72 | 73 | class WithRationalBoomTiles extends Config((site, here, up) => { 74 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 75 | case tp: BoomTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( 76 | crossingType = RationalCrossing() 77 | )) 78 | case other => other 79 | } 80 | }) 81 | 82 | /** 83 | * 1-wide BOOM. 84 | */ 85 | class WithNSmallBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 86 | new WithTAGELBPD ++ // Default to TAGE-L BPD 87 | new Config((site, here, up) => { 88 | case TilesLocated(InSubsystem) => { 89 | val prev = up(TilesLocated(InSubsystem), site) 90 | val idOffset = overrideIdOffset.getOrElse(prev.size) 91 | (0 until n).map { i => 92 | BoomTileAttachParams( 93 | tileParams = BoomTileParams( 94 | core = BoomCoreParams( 95 | fetchWidth = 4, 96 | decodeWidth = 1, 97 | numRobEntries = 32, 98 | issueParams = Seq( 99 | IssueParams(issueWidth=1, numEntries=8, iqType=IQT_MEM.litValue, dispatchWidth=1), 100 | IssueParams(issueWidth=1, numEntries=8, iqType=IQT_INT.litValue, dispatchWidth=1), 101 | IssueParams(issueWidth=1, numEntries=8, iqType=IQT_FP.litValue , dispatchWidth=1)), 102 | numIntPhysRegisters = 52, 103 | numFpPhysRegisters = 48, 104 | numLdqEntries = 8, 105 | numStqEntries = 8, 106 | maxBrCount = 8, 107 | numFetchBufferEntries = 8, 108 | ftq = FtqParameters(nEntries=16), 109 | nPerfCounters = 2, 110 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 111 | ), 112 | dcache = Some( 113 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, nMSHRs=2, nTLBWays=8) 114 | ), 115 | icache = Some( 116 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, fetchBytes=2*4) 117 | ), 118 | hartId = i + idOffset 119 | ), 120 | crossingParams = RocketCrossingParams() 121 | ) 122 | } ++ prev 123 | } 124 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8) 125 | case XLen => 64 126 | }) 127 | ) 128 | 129 | /** 130 | * 2-wide BOOM. 131 | */ 132 | class WithNMediumBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 133 | new WithTAGELBPD ++ // Default to TAGE-L BPD 134 | new Config((site, here, up) => { 135 | case TilesLocated(InSubsystem) => { 136 | val prev = up(TilesLocated(InSubsystem), site) 137 | val idOffset = overrideIdOffset.getOrElse(prev.size) 138 | (0 until n).map { i => 139 | BoomTileAttachParams( 140 | tileParams = BoomTileParams( 141 | core = BoomCoreParams( 142 | fetchWidth = 4, 143 | decodeWidth = 2, 144 | numRobEntries = 64, 145 | issueParams = Seq( 146 | IssueParams(issueWidth=1, numEntries=12, iqType=IQT_MEM.litValue, dispatchWidth=2), 147 | IssueParams(issueWidth=2, numEntries=20, iqType=IQT_INT.litValue, dispatchWidth=2), 148 | IssueParams(issueWidth=1, numEntries=16, iqType=IQT_FP.litValue , dispatchWidth=2)), 149 | numIntPhysRegisters = 80, 150 | numFpPhysRegisters = 64, 151 | numLdqEntries = 16, 152 | numStqEntries = 16, 153 | maxBrCount = 12, 154 | numFetchBufferEntries = 16, 155 | ftq = FtqParameters(nEntries=32), 156 | nPerfCounters = 6, 157 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 158 | ), 159 | dcache = Some( 160 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, nMSHRs=2, nTLBWays=8) 161 | ), 162 | icache = Some( 163 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, fetchBytes=2*4) 164 | ), 165 | hartId = i + idOffset 166 | ), 167 | crossingParams = RocketCrossingParams() 168 | ) 169 | } ++ prev 170 | } 171 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8) 172 | case XLen => 64 173 | }) 174 | ) 175 | 176 | class WithNMediumBoomsTracing(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 177 | new WithTAGELBPD ++ // Default to TAGE-L BPD 178 | new WithBoomCommitLogPrintf ++ 179 | new Config((site, here, up) => { 180 | case TilesLocated(InSubsystem) => { 181 | val prev = up(TilesLocated(InSubsystem), site) 182 | val idOffset = overrideIdOffset.getOrElse(prev.size) 183 | (0 until n).map { i => 184 | BoomTileAttachParams( 185 | tileParams = BoomTileParams( 186 | core = BoomCoreParams( 187 | fetchWidth = 4, 188 | decodeWidth = 2, 189 | numRobEntries = 64, 190 | issueParams = Seq( 191 | IssueParams(issueWidth=1, numEntries=12, iqType=IQT_MEM.litValue, dispatchWidth=2), 192 | IssueParams(issueWidth=2, numEntries=20, iqType=IQT_INT.litValue, dispatchWidth=2), 193 | IssueParams(issueWidth=1, numEntries=16, iqType=IQT_FP.litValue , dispatchWidth=2)), 194 | numIntPhysRegisters = 80, 195 | numFpPhysRegisters = 64, 196 | numLdqEntries = 16, 197 | numStqEntries = 16, 198 | maxBrCount = 12, 199 | numFetchBufferEntries = 16, 200 | ftq = FtqParameters(nEntries=32), 201 | nPerfCounters = 6, 202 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 203 | ), 204 | dcache = Some( 205 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, nMSHRs=2, nTLBWays=8) 206 | ), 207 | icache = Some( 208 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=4, fetchBytes=2*4) 209 | ), 210 | hartId = i + idOffset 211 | ), 212 | crossingParams = RocketCrossingParams() 213 | ) 214 | } ++ prev 215 | } 216 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8) 217 | case XLen => 64 218 | }) 219 | ) 220 | 221 | 222 | // DOC include start: LargeBoomConfig 223 | /** 224 | * 3-wide BOOM. Try to match the Cortex-A15. 225 | */ 226 | class WithNLargeBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 227 | new WithTAGELBPD ++ // Default to TAGE-L BPD 228 | new Config((site, here, up) => { 229 | case TilesLocated(InSubsystem) => { 230 | val prev = up(TilesLocated(InSubsystem), site) 231 | val idOffset = overrideIdOffset.getOrElse(prev.size) 232 | (0 until n).map { i => 233 | BoomTileAttachParams( 234 | tileParams = BoomTileParams( 235 | core = BoomCoreParams( 236 | fetchWidth = 8, 237 | decodeWidth = 3, 238 | numRobEntries = 96, 239 | issueParams = Seq( 240 | IssueParams(issueWidth=1, numEntries=16, iqType=IQT_MEM.litValue, dispatchWidth=3), 241 | IssueParams(issueWidth=3, numEntries=32, iqType=IQT_INT.litValue, dispatchWidth=3), 242 | IssueParams(issueWidth=1, numEntries=24, iqType=IQT_FP.litValue , dispatchWidth=3)), 243 | numIntPhysRegisters = 100, 244 | numFpPhysRegisters = 96, 245 | numLdqEntries = 24, 246 | numStqEntries = 24, 247 | maxBrCount = 16, 248 | numFetchBufferEntries = 24, 249 | ftq = FtqParameters(nEntries=32), 250 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 251 | ), 252 | dcache = Some( 253 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, nMSHRs=4, nTLBWays=16) 254 | ), 255 | icache = Some( 256 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, fetchBytes=4*4) 257 | ), 258 | hartId = i + idOffset 259 | ), 260 | crossingParams = RocketCrossingParams() 261 | ) 262 | } ++ prev 263 | } 264 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 16) 265 | case XLen => 64 266 | }) 267 | ) 268 | // DOC include end: LargeBoomConfig 269 | 270 | /** 271 | * 4-wide BOOM. 272 | */ 273 | class WithNMegaBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 274 | new WithTAGELBPD ++ // Default to TAGE-L BPD 275 | new Config((site, here, up) => { 276 | case TilesLocated(InSubsystem) => { 277 | val prev = up(TilesLocated(InSubsystem), site) 278 | val idOffset = overrideIdOffset.getOrElse(prev.size) 279 | (0 until n).map { i => 280 | BoomTileAttachParams( 281 | tileParams = BoomTileParams( 282 | core = BoomCoreParams( 283 | fetchWidth = 8, 284 | decodeWidth = 4, 285 | numRobEntries = 128, 286 | issueParams = Seq( 287 | IssueParams(issueWidth=2, numEntries=24, iqType=IQT_MEM.litValue, dispatchWidth=4), 288 | IssueParams(issueWidth=4, numEntries=40, iqType=IQT_INT.litValue, dispatchWidth=4), 289 | IssueParams(issueWidth=2, numEntries=32, iqType=IQT_FP.litValue , dispatchWidth=4)), 290 | numIntPhysRegisters = 128, 291 | numFpPhysRegisters = 128, 292 | numLdqEntries = 32, 293 | numStqEntries = 32, 294 | maxBrCount = 20, 295 | numFetchBufferEntries = 32, 296 | enablePrefetching = true, 297 | ftq = FtqParameters(nEntries=40), 298 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 299 | ), 300 | dcache = Some( 301 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, nMSHRs=8, nTLBWays=32) 302 | ), 303 | icache = Some( 304 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, fetchBytes=4*4) 305 | ), 306 | hartId = i + idOffset 307 | ), 308 | crossingParams = RocketCrossingParams() 309 | ) 310 | } ++ prev 311 | } 312 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 16) 313 | case XLen => 64 314 | }) 315 | ) 316 | 317 | /** 318 | * 5-wide BOOM. 319 | */ 320 | class WithNGigaBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 321 | new WithTAGELBPD ++ // Default to TAGE-L BPD 322 | new Config((site, here, up) => { 323 | case TilesLocated(InSubsystem) => { 324 | val prev = up(TilesLocated(InSubsystem), site) 325 | val idOffset = overrideIdOffset.getOrElse(prev.size) 326 | (0 until n).map { i => 327 | BoomTileAttachParams( 328 | tileParams = BoomTileParams( 329 | core = BoomCoreParams( 330 | fetchWidth = 8, 331 | decodeWidth = 5, 332 | numRobEntries = 130, 333 | issueParams = Seq( 334 | IssueParams(issueWidth=2, numEntries=24, iqType=IQT_MEM.litValue, dispatchWidth=5), 335 | IssueParams(issueWidth=5, numEntries=40, iqType=IQT_INT.litValue, dispatchWidth=5), 336 | IssueParams(issueWidth=2, numEntries=32, iqType=IQT_FP.litValue , dispatchWidth=5)), 337 | numIntPhysRegisters = 128, 338 | numFpPhysRegisters = 128, 339 | numLdqEntries = 32, 340 | numStqEntries = 32, 341 | maxBrCount = 20, 342 | numFetchBufferEntries = 32, 343 | enablePrefetching = true, 344 | numDCacheBanks = 1, 345 | ftq = FtqParameters(nEntries=40), 346 | fpu = Some(freechips.rocketchip.tile.FPUParams(sfmaLatency=4, dfmaLatency=4, divSqrt=true)) 347 | ), 348 | dcache = Some( 349 | DCacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, nMSHRs=8, nTLBWays=32) 350 | ), 351 | icache = Some( 352 | ICacheParams(rowBits = site(SystemBusKey).beatBits, nSets=64, nWays=8, fetchBytes=4*4) 353 | ), 354 | hartId = i + idOffset 355 | ), 356 | crossingParams = RocketCrossingParams() 357 | ) 358 | } ++ prev 359 | } 360 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 16) 361 | case XLen => 64 362 | }) 363 | ) 364 | 365 | /** 366 | * BOOM Configs for CS152 lab 367 | */ 368 | class WithNCS152BaselineBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 369 | new WithTAGELBPD ++ // Default to TAGE-L BPD 370 | new Config((site, here, up) => { 371 | case TilesLocated(InSubsystem) => { 372 | val prev = up(TilesLocated(InSubsystem), site) 373 | val idOffset = overrideIdOffset.getOrElse(prev.size) 374 | (0 until n).map { i => 375 | val coreWidth = 1 // CS152: Change me (1 to 4) 376 | val memWidth = 1 // CS152: Change me (1 or 2) 377 | BoomTileAttachParams( 378 | tileParams = BoomTileParams( 379 | core = BoomCoreParams( 380 | fetchWidth = 4, // CS152: Change me (4 or 8) 381 | numRobEntries = 4, // CS152: Change me (2+) 382 | numIntPhysRegisters = 33, // CS152: Change me (33+) 383 | numLdqEntries = 8, // CS152: Change me (2+) 384 | numStqEntries = 8, // CS152: Change me (2+) 385 | maxBrCount = 8, // CS152: Change me (2+) 386 | enableBranchPrediction = false, // CS152: Change me 387 | numRasEntries = 0, // CS152: Change me 388 | 389 | // DO NOT CHANGE BELOW 390 | enableBranchPrintf = true, 391 | decodeWidth = coreWidth, 392 | numFetchBufferEntries = coreWidth * 8, 393 | numDCacheBanks = memWidth, 394 | issueParams = Seq( 395 | IssueParams(issueWidth=memWidth, numEntries=8, iqType=IQT_MEM.litValue, dispatchWidth=coreWidth), 396 | IssueParams(issueWidth=coreWidth, numEntries=32, iqType=IQT_INT.litValue, dispatchWidth=coreWidth), 397 | IssueParams(issueWidth=1, numEntries=4, iqType=IQT_FP.litValue , dispatchWidth=coreWidth)) 398 | // DO NOT CHANGE ABOVE 399 | ), 400 | dcache = Some(DCacheParams( 401 | rowBits=site(SystemBusKey).beatBytes*8, 402 | nSets=64, // CS152: Change me (must be pow2, 2-64) 403 | nWays=4, // CS152: Change me (1-8) 404 | nMSHRs=2 // CS152: Change me (1+) 405 | )), 406 | hartId = i + idOffset 407 | ), 408 | crossingParams = RocketCrossingParams() 409 | ) 410 | } ++ prev 411 | } 412 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8) 413 | case XLen => 64 414 | }) 415 | ) 416 | 417 | class WithNCS152DefaultBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config( 418 | new WithTAGELBPD ++ // Default to TAGE-L BPD 419 | new Config((site, here, up) => { 420 | case TilesLocated(InSubsystem) => { 421 | val prev = up(TilesLocated(InSubsystem), site) 422 | val idOffset = overrideIdOffset.getOrElse(prev.size) 423 | (0 until n).map { i => 424 | val coreWidth = 3 // CS152: Change me (1 to 4) 425 | val memWidth = 1 // CS152: Change me (1 or 2) 426 | val nIssueSlots = 32 // CS152: Change me (2+) 427 | BoomTileAttachParams( 428 | tileParams = BoomTileParams( 429 | core = BoomCoreParams( 430 | fetchWidth = 4, // CS152: Change me (4 or 8) 431 | numRobEntries = 96, // CS152: Change me (2+) 432 | numIntPhysRegisters = 96, // CS152: Change me (33+) 433 | numLdqEntries = 16, // CS152: Change me (2+) 434 | numStqEntries = 16, // CS152: Change me (2+) 435 | maxBrCount = 12, // CS152: Change me (2+) 436 | enableBranchPrediction = true, // CS152: Change me 437 | numRasEntries = 16, // CS152: Change me 438 | 439 | // DO NOT CHANGE BELOW 440 | enableBranchPrintf = true, 441 | decodeWidth = coreWidth, 442 | numFetchBufferEntries = coreWidth * 8, 443 | numDCacheBanks = memWidth, 444 | issueParams = Seq( 445 | IssueParams(issueWidth=memWidth, numEntries=nIssueSlots, iqType=IQT_MEM.litValue, dispatchWidth=coreWidth), 446 | IssueParams(issueWidth=coreWidth, numEntries=nIssueSlots, iqType=IQT_INT.litValue, dispatchWidth=coreWidth), 447 | IssueParams(issueWidth=1, numEntries=nIssueSlots, iqType=IQT_FP.litValue , dispatchWidth=coreWidth)) 448 | // DO NOT CHANGE ABOVE 449 | ), 450 | dcache = Some(DCacheParams( 451 | rowBits=site(SystemBusKey).beatBytes*8, 452 | nSets=64, // CS152: Change me (must be pow2, 2-64) 453 | nWays=4, // CS152: Change me (1-8) 454 | nMSHRs=2 // CS152: Change me (1+) 455 | )), 456 | hartId = i + idOffset 457 | ), 458 | crossingParams = RocketCrossingParams() 459 | ) 460 | } ++ prev 461 | } 462 | case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8) 463 | case XLen => 64 464 | }) 465 | ) 466 | 467 | /** 468 | * Branch prediction configs below 469 | */ 470 | 471 | class WithTAGELBPD extends Config((site, here, up) => { 472 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 473 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 474 | bpdMaxMetaLength = 120, 475 | globalHistoryLength = 64, 476 | localHistoryLength = 1, 477 | localHistoryNSets = 0, 478 | branchPredictor = ((resp_in: BranchPredictionBankResponse, p: Parameters) => { 479 | val loop = Module(new LoopBranchPredictorBank()(p)) 480 | val tage = Module(new TageBranchPredictorBank()(p)) 481 | val btb = Module(new BTBBranchPredictorBank()(p)) 482 | val bim = Module(new BIMBranchPredictorBank()(p)) 483 | val ubtb = Module(new FAMicroBTBBranchPredictorBank()(p)) 484 | val preds = Seq(loop, tage, btb, ubtb, bim) 485 | preds.map(_.io := DontCare) 486 | 487 | ubtb.io.resp_in(0) := resp_in 488 | bim.io.resp_in(0) := ubtb.io.resp 489 | btb.io.resp_in(0) := bim.io.resp 490 | tage.io.resp_in(0) := btb.io.resp 491 | loop.io.resp_in(0) := tage.io.resp 492 | 493 | (preds, loop.io.resp) 494 | }) 495 | ))) 496 | case other => other 497 | } 498 | }) 499 | 500 | class WithBoom2BPD extends Config((site, here, up) => { 501 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 502 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 503 | bpdMaxMetaLength = 45, 504 | globalHistoryLength = 16, 505 | localHistoryLength = 1, 506 | localHistoryNSets = 0, 507 | branchPredictor = ((resp_in: BranchPredictionBankResponse, p: Parameters) => { 508 | // gshare is just variant of TAGE with 1 table 509 | val gshare = Module(new TageBranchPredictorBank( 510 | BoomTageParams(tableInfo = Seq((256, 16, 7))) 511 | )(p)) 512 | val btb = Module(new BTBBranchPredictorBank()(p)) 513 | val bim = Module(new BIMBranchPredictorBank()(p)) 514 | val preds = Seq(bim, btb, gshare) 515 | preds.map(_.io := DontCare) 516 | 517 | bim.io.resp_in(0) := resp_in 518 | btb.io.resp_in(0) := bim.io.resp 519 | gshare.io.resp_in(0) := btb.io.resp 520 | (preds, gshare.io.resp) 521 | }) 522 | ))) 523 | case other => other 524 | } 525 | }) 526 | 527 | class WithAlpha21264BPD extends Config((site, here, up) => { 528 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 529 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 530 | bpdMaxMetaLength = 64, 531 | globalHistoryLength = 32, 532 | localHistoryLength = 32, 533 | localHistoryNSets = 128, 534 | branchPredictor = ((resp_in: BranchPredictionBankResponse, p: Parameters) => { 535 | val btb = Module(new BTBBranchPredictorBank()(p)) 536 | val gbim = Module(new HBIMBranchPredictorBank()(p)) 537 | val lbim = Module(new HBIMBranchPredictorBank(BoomHBIMParams(useLocal=true))(p)) 538 | val tourney = Module(new TourneyBranchPredictorBank()(p)) 539 | val preds = Seq(lbim, btb, gbim, tourney) 540 | preds.map(_.io := DontCare) 541 | 542 | gbim.io.resp_in(0) := resp_in 543 | lbim.io.resp_in(0) := resp_in 544 | tourney.io.resp_in(0) := gbim.io.resp 545 | tourney.io.resp_in(1) := lbim.io.resp 546 | btb.io.resp_in(0) := tourney.io.resp 547 | 548 | (preds, btb.io.resp) 549 | }) 550 | ))) 551 | case other => other 552 | } 553 | }) 554 | 555 | 556 | class WithSWBPD extends Config((site, here, up) => { 557 | case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { 558 | case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = tp.tileParams.core.copy( 559 | bpdMaxMetaLength = 1, 560 | globalHistoryLength = 32, 561 | localHistoryLength = 1, 562 | localHistoryNSets = 0, 563 | branchPredictor = ((resp_in: BranchPredictionBankResponse, p: Parameters) => { 564 | val sw = Module(new SwBranchPredictorBank()(p)) 565 | 566 | sw.io.resp_in(0) := resp_in 567 | 568 | (Seq(sw), sw.io.resp) 569 | }) 570 | ))) 571 | case other => other 572 | } 573 | }) 574 | --------------------------------------------------------------------------------