diff --git a/.github/cli-space-cleanup.sh b/.github/cli-space-cleanup.sh new file mode 100755 index 000000000..0f8de1619 --- /dev/null +++ b/.github/cli-space-cleanup.sh @@ -0,0 +1,65 @@ +#!/bin/bash +########################################### +## GitHub runner space cleanup +## +## Written: Jordan Carlin, jcarlin@hmc.edu +## Created: 30 June 2024 +## Modified: +## +## Purpose: Remove unnecessary packages/directories from GitHub Actions runner + +## A component of the CORE-V-WALLY configurable RISC-V project. +## https://github.com/openhwgroup/cvw +## +## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ + +# Remove unnecessary packages +removePacks=( '^llvm-.*' 'php.*' '^mongodb-.*' '^mysql-.*' '^dotnet-sdk-.*' 'azure-cli' 'google-cloud-cli' 'google-chrome-stable' 'firefox' '^powershell*' 'microsoft-edge-stable' 'mono-devel' 'hhvm' ) +for pack in "${removePacks[@]}"; do + sudo apt-get purge -y "$pack" || true +done +sudo apt-get autoremove -y || true +sudo apt-get clean || true + +# Remove unnecessary directories +sudo rm -rf /usr/local/lib/android +sudo rm -rf /usr/share/dotnet +sudo rm -rf /usr/share/swift +sudo rm -rf /usr/share/miniconda +sudo rm -rf /usr/share/az* +sudo rm -rf /usr/share/gradle-* +sudo rm -rf /usr/share/sbt +sudo rm -rf /opt/ghc +sudo rm -rf /usr/local/.ghcup +sudo rm -rf /usr/local/share/powershell +sudo rm -rf /usr/local/lib/node_modules +sudo rm -rf /usr/local/julia* +sudo rm -rf /usr/local/share/chromium +sudo rm -rf /usr/local/share/vcpkg +sudo rm -rf /usr/local/games +sudo rm -rf /usr/local/sqlpackage +sudo rm -rf /usr/lib/google-cloud-sdk +sudo rm -rf /usr/lib/jvm +sudo rm -rf /usr/lib/mono +sudo rm -rf /usr/lib/R +sudo rm -rf /usr/lib/postgresql +sudo rm -rf /usr/lib/heroku +sudo rm -rf /usr/lib/firefox +sudo rm -rf /opt/hostedtoolcache + +# Clean up docker images +sudo docker image prune --all --force diff --git a/.github/workflows/dockerBuild.yml b/.github/workflows/dockerBuild.yml new file mode 100644 index 000000000..02a1b66e8 --- /dev/null +++ b/.github/workflows/dockerBuild.yml @@ -0,0 +1,32 @@ +name: Build Docker Image +on: [workflow_dispatch, push, pull_request] +defaults: + run: + shell: bash + +jobs: + docker_build: + name: Build Docker Image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Free up storage + run: | + df -h + ./.github/cli-space-cleanup.sh + df -h + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push docker image + uses: docker/build-push-action@v5 + with: + tags: ghcr.io/jordancarlin/cvw/ubuntu24cvw:latest + push: true diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml new file mode 100644 index 000000000..771255ff7 --- /dev/null +++ b/.github/workflows/install.yml @@ -0,0 +1,183 @@ +name: Installation +on: [workflow_dispatch, push] +defaults: + run: + shell: bash + +jobs: + ubuntu_install: + name: Test installation on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"] + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Free up storage + run: | + df -h + ./.github/cli-space-cleanup.sh + df -h + - name: install + run: sudo ./bin/wally-tool-chain-install.sh --clean + - name: Upload installation logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: installation-logs-${{ matrix.os }} + path: /opt/riscv/logs/ + - name: make tests + run: | + source setup.sh + make riscof + - name: regression + run: | + source setup.sh + regression-wally + - name: Upload regression logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: regression-logs-${{ matrix.os }} + path: ${{ github.workspace }}/sim/verilator/logs/ + + rhel_family_install: + name: Test installation on ${{ matrix.os }} + runs-on: ubuntu-latest + container: + image: ${{ matrix.os }} + options: --privileged --mount type=bind,source=/,target=/host --pid=host --entrypoint /bin/bash + strategy: + fail-fast: false + matrix: + os: ["rockylinux:8", "rockylinux:9", "almalinux:8", "almalinux:9"] + steps: + - name: Unique name for Artifacts + id: prep_artifact_name + run: | + name=$(echo -n "${{ matrix.os }}" | sed -e 's/[ \t:\/\\"<>|*?]/-/g' -e 's/--*/-/g') + echo "ARTIFACT_NAME=$name" >> $GITHUB_ENV + - name: Install dependencies + run: | + dnf install -y sudo git + dnf install curl -y --allowerasing || true + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Fix git ownership + run: git config --global --add safe.directory '*' + - name: Free up storage + run: | + df -h + nsenter -t 1 -m -u -n -i bash -c "$(cat .github/cli-space-cleanup.sh)" + df -h + - name: install + run: sudo ./bin/wally-tool-chain-install.sh --clean + - name: Upload installation logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: installation-logs-${{ env.ARTIFACT_NAME }} + path: /opt/riscv/logs/ + - name: make tests + run: | + source setup.sh + make riscof + - name: regression + run: | + source setup.sh + regression-wally + - name: Upload regression logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: regression-logs-${{ env.ARTIFACT_NAME }} + path: ${{ github.workspace }}/sim/verilator/logs/ + + + user_install: + name: Test installation with user permissions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Free up storage + run: | + df -h + ./.github/cli-space-cleanup.sh + df -h + - name: install packages with sudo + run: sudo ./bin/wally-package-install.sh + - name: install + run: ./bin/wally-tool-chain-install.sh --clean + - name: Upload installation logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: installation-logs-user-install + path: ~/riscv/logs/ + - name: make tests + run: | + source setup.sh + make riscof + - name: regression + run: | + source setup.sh + regression-wally + - name: Upload regression logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: regression-logs-user-install + path: ${{ github.workspace }}/sim/verilator/logs/ + + + custom_location_install: + name: Test installation with custom location ${{ matrix.path }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + path: ["/home/riscv"] + steps: + - name: Unique name for Artifacts + id: prep_artifact_name + run: | + name=$(echo -n "${{ matrix.os }}" | sed -e 's/[ \t:\/\\"<>|*?]/-/g' -e 's/--*/-/g') + echo "ARTIFACT_NAME=$name" >> $GITHUB_ENV + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Free up storage + run: | + df -h + ./.github/cli-space-cleanup.sh + df -h + - name: install + run: sudo ./bin/wally-tool-chain-install.sh --clean ${{ matrix.path }} + - name: Upload instalation logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: installation-logs-custom-location-install-${{ env.ARTIFACT_NAME }} + path: ${{ matrix.path }}/logs/ + - name: Update setup.sh with new $RISCV location + run: sed -i 's,exit 1,export RISCV=${{ matrix.path }},g' setup.sh + - name: make tests + run: | + source setup.sh + make riscof + - name: regression + run: | + source setup.sh + regression-wally + - name: Upload regression logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: regression-logs-custom-location-install-${{ env.ARTIFACT_NAME }} + path: ${{ github.workspace }}/sim/verilator/logs/ diff --git a/.gitignore b/.gitignore index 19dbba458..abb501e74 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,4 @@ config/deriv sim/slack-notifier/slack-webhook-url.txt docs/docker/buildroot-config-src docs/docker/testvector-generation +!.github/* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..0cb88016f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +# CVW Dockerfile +# Jordan Carlin jcarlin@hmc.edu July 2024 +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +FROM ubuntu:24.04 + +SHELL ["/bin/bash", "-c"] + +# Create a user with sudo privileges +ARG USERNAME=wally +ARG USER_UID=1000 +ARG USER_GID=$USER_UID +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Change to the new user +USER $USERNAME + +COPY . /home/$USERNAME/cvw + +WORKDIR /home/$USERNAME/cvw + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update -y \ + && apt-get install -y sudo git \ + && ./bin/wally-package-install.sh \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN sudo ./bin/wally-tool-chain-install.sh --clean + +RUN source setup.sh \ + && git config --global --add safe.directory '*' \ + && make -j$(nproc) + +CMD ["bash", "-c", "source setup.sh && exec /bin/bash"] diff --git a/bin/wally-package-install.sh b/bin/wally-package-install.sh index 8fea2d27b..725d3b201 100755 --- a/bin/wally-package-install.sh +++ b/bin/wally-package-install.sh @@ -55,10 +55,9 @@ if [ "$FAMILY" == rhel ]; then SPIKE_PACKAGES+=(dtc boost-regex boost-system) VERILATOR_PACKAGES+=(help2man perl clang ccache gperftools numactl mold) BUILDROOT_PACKAGES+=(ncurses-base ncurses ncurses-libs ncurses-devel gcc-gfortran cpio) # gcc-gfortran is only needed for compiling spec benchmarks on buildroot linux - # Extra packages not availale in rhel8, nice for Verilator and needed for sail respectively + # Extra packages not availale in rhel8, nice for Verilator if (( RHEL_VERSION >= 9 )); then VERILATOR_PACKAGES+=(perl-doc) - SAIL_PACKAGES=(z3) fi # A newer version of gcc is required for qemu OTHER_PACKAGES=(gcc-toolset-13) @@ -80,7 +79,6 @@ elif [ "$FAMILY" == ubuntu ]; then QEMU_PACKAGES+=(libfdt-dev libpixman-1-dev) SPIKE_PACKAGES+=(device-tree-compiler libboost-regex-dev libboost-system-dev) VERILATOR_PACKAGES+=(help2man perl g++ clang ccache libunwind-dev libgoogle-perftools-dev numactl perl-doc libfl2 libfl-dev zlib1g) - SAIL_PACKAGES+=(opam z3) BUILDROOT_PACKAGES+=(ncurses-base ncurses-bin libncurses-dev gfortran cpio) # gfortran is only needed for compiling spec benchmarks on buildroot linux VIVADO_PACKAGES+=(libncurses*) # Vivado hangs on the third stage of installation without this fi @@ -90,11 +88,11 @@ fi if [ "${1}" == "--check" ]; then section_header "Checking Dependencies from Package Manager" if [ "$FAMILY" == rhel ]; then - for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do + for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do rpm -q "$pack" > /dev/null || (echo -e "${FAIL_COLOR}Missing packages detected (${WARNING_COLOR}$pack${FAIL_COLOR}). Run as root to auto-install or run wally-package-install.sh first.${ENDC}" && exit 1) done elif [ "$FAMILY" == ubuntu ]; then - for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do + for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do dpkg -l "$pack" | grep "ii" > /dev/null || (echo -e "${FAIL_COLOR}Missing packages detected (${WARNING_COLOR}$pack${FAIL_COLOR}). Run as root to auto-install or run wally-package-install.sh first." && exit 1) done fi @@ -124,6 +122,6 @@ else # Update and Upgrade tools eval "$UPDATE_COMMAND" # Install packages listed above using appropriate package manager - sudo $PACKAGE_MANAGER install -y "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}" "${VIVADO_PACKAGES[@]}" + sudo $PACKAGE_MANAGER install -y "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}" "${VIVADO_PACKAGES[@]}" echo -e "${SUCCESS_COLOR}Packages successfully installed.${ENDC}" fi diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 88600ba26..3fb70193d 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -7,6 +7,7 @@ ## Modified: 22 January 2023 ## Modified: 23 March 2023 ## Modified: 30 June 2024, Jordan Carlin jcarlin@hmc.edu +## Modified: 1 September 2024 ## ## Purpose: Open source tool chain installation script ## @@ -148,11 +149,6 @@ source "$RISCV"/riscv-python/bin/activate # activate python virtual environment STATUS="python packages" pip install --upgrade pip && pip install -r "$dir"/requirements.txt -# z3 is needed for sail and not availabe from dnf for rhel 8 -if (( RHEL_VERSION == 8 )); then - pip install -U z3-solver -fi - source "$RISCV"/riscv-python/bin/activate # reload python virtual environment echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}" @@ -166,9 +162,7 @@ if (( RHEL_VERSION == 8 )) || (( UBUNTU_VERSION == 20 )); then section_header "Installing glib" pip install -U meson # Meson is needed to build glib cd "$RISCV" - wget https://download.gnome.org/sources/glib/2.70/glib-2.70.5.tar.xz - tar -xJf glib-2.70.5.tar.xz - rm glib-2.70.5.tar.xz + curl --location https://download.gnome.org/sources/glib/2.70/glib-2.70.5.tar.xz | tar xJ cd glib-2.70.5 meson setup _build --prefix="$RISCV" meson compile -C _build @@ -185,9 +179,7 @@ if (( RHEL_VERSION == 8 )); then if [ ! -e "$RISCV"/include/gmp.h ]; then section_header "Installing gmp" cd "$RISCV" - wget https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz - tar -xJf gmp-6.3.0.tar.xz - rm gmp-6.3.0.tar.xz + curl --location https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz | tar xJ cd gmp-6.3.0 ./configure --prefix="$RISCV" make -j "${NUM_THREADS}" @@ -321,40 +313,20 @@ else fi -# Install opam from binary disribution on rhel as it is not available from dnf -# Opam is needed to install the sail compiler -if [ "$FAMILY" == rhel ]; then - section_header "Installing/Updating Opam" - STATUS="Opam" - export OPAMROOTISOK=1 # Silence warnings about running opam as root - cd "$RISCV" - mkdir -p opam - cd opam - wget https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh - printf '%s\n' "$RISCV"/bin Y | sh install.sh # the print command provides $RISCV/bin as the installation path when prompted - cd "$RISCV" - rm -rf opam - echo -e "${SUCCESS_COLOR}Opam successfully installed/updated!${ENDC}" -fi - # Sail Compiler (https://github.com/rems-project/sail) # Sail is a formal specification language designed for describing the semantics of an ISA. # It is used to generate the RISC-V Sail Model, which is the golden reference model for RISC-V. # The Sail Compiler is written in OCaml, which is an object-oriented extension of ML, which in turn -# is a functional programming language suited to formal verification. The Sail compiler is installed -# with the opam OCaml package manager. It has so many dependencies that it can be difficult to install, -# but a binary release of it should be available soon, removing the need to use opam. +# is a functional programming language suited to formal verification. section_header "Installing/Updating Sail Compiler" STATUS="Sail Compiler" -export OPAMROOTISOK=1 # Silence warnings about running opam as root -export OPAMROOT="$RISCV"/opam -cd "$RISCV" -opam init -y --disable-sandboxing --no-setup --compiler=5.1.0 -eval "$(opam config env)" -opam update -y -opam upgrade -y -opam install sail -y -echo -e "${SUCCESS_COLOR}Sail Compiler successfully installed/updated!${ENDC}" +if [ ! -e "$RISCV"/bin/sail ]; then + cd "$RISCV" + curl --location https://github.com/rems-project/sail/releases/latest/download/sail.tar.gz | tar xvz --directory="$RISCV" --strip-components=1 + echo -e "${SUCCESS_COLOR}Sail Compiler successfully installed/updated!${ENDC}" +else + echo -e "${SUCCESS_COLOR}Sail Compiler already installed.${ENDC}" +fi # RISC-V Sail Model (https://github.com/riscv/sail-riscv) # The RISC-V Sail Model is the golden reference model for RISC-V. It is written in Sail (described above) @@ -363,7 +335,8 @@ STATUS="RISC-V Sail Model" if git_check "sail-riscv" "https://github.com/riscv/sail-riscv.git" "$RISCV/bin/riscv_sim_RV32"; then cd sail-riscv git reset --hard && git clean -f && git checkout master && git pull - export OPAMCLI=2.0 # Sail is not compatible with opam 2.1 as of 4/16/24 + git fetch origin pull/532/head:binary + git switch binary ARCH=RV64 make -j "${NUM_THREADS}" c_emulator/riscv_sim_RV64 2>&1 | logger sailModel; [ "${PIPESTATUS[0]}" == 0 ] ARCH=RV32 make -j "${NUM_THREADS}" c_emulator/riscv_sim_RV32 2>&1 | logger sailModel; [ "${PIPESTATUS[0]}" == 0 ] cp -f c_emulator/riscv_sim_RV64 "$RISCV"/bin/riscv_sim_RV64 @@ -371,7 +344,6 @@ if git_check "sail-riscv" "https://github.com/riscv/sail-riscv.git" "$RISCV/bin/ if [ "$clean" ]; then cd "$RISCV" rm -rf sail-riscv - rm -rf opam fi echo -e "${SUCCESS_COLOR}RISC-V Sail Model successfully installed/updated!${ENDC}" else