diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100755 index 0000000..3c33b0d --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,133 @@ +FROM ghcr.io/utoss/verilator:latest AS verilator + +FROM ghcr.io/utoss/risc-v-toolchain:latest AS risc-v-toolchain + +FROM ghcr.io/utoss/quartus:latest AS quartus + +FROM public.ecr.aws/lts/ubuntu:22.04_stable + +ARG DEBIAN_FRONTEND=noninteractive +ARG KEYRING_PATH=/usr/share/keyrings +ARG APT_SOURCES_PATH=/etc/apt/sources.list.d + +# update and upgrade +RUN apt update && apt upgrade -y + +# install essentialls +RUN apt update && \ + apt install -y \ + man make build-essential git zsh vim curl wget procps gnupg gnupg2 ca-certificates zip \ + software-properties-common + +# unminimize the system +RUN bash -c "yes | unminimize" + +# create dev sudo user +RUN useradd --create-home dev && \ + usermod --append --groups sudo dev && \ + apt update && apt install -y sudo && \ + echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +# install dumb init system +USER root +RUN apt update && apt install -y dumb-init + +# setup oh-my-zsh +USER dev +ARG DOCKER_OHMYZSH_SCRIPT_NAME=zsh-in-docker.sh +ARG DOCKER_OHMYZSH_SCRIPT_URL=https://github.com/deluan/zsh-in-docker/releases/download/v1.1.3/${DOCKER_OHMYZSH_SCRIPT_NAME} +ARG DOCKER_OHMYZSH_SCRIPT_HASH="ffa8175332ef01b500ace59d03ce7e2f3a7453651e9a37060974bb6536f0706b ${DOCKER_OHMYZSH_SCRIPT_NAME}" +RUN cd /tmp && \ + wget ${DOCKER_OHMYZSH_SCRIPT_URL} && \ + echo ${DOCKER_OHMYZSH_SCRIPT_HASH} | sha256sum -c && \ + chmod +x ./${DOCKER_OHMYZSH_SCRIPT_NAME} && \ + ./${DOCKER_OHMYZSH_SCRIPT_NAME} -t robbyrussell -p git -p ssh-agent && \ + rm ./${DOCKER_OHMYZSH_SCRIPT_NAME} + +# build and install icarus verilog +USER dev +ARG ICARUS_SRC_TAR=s20251012.tar.gz +ARG ICARUS_SRC_URL=https://github.com/steveicarus/iverilog/archive/refs/tags/${ICARUS_SRC_TAR} +ARG ICARUS_SRC_HASH="97776c5dd1ee09157f7cb9f48978c7687b9157b09fa7029c0f9378aac9a6f58c ${ICARUS_SRC_TAR}" +RUN sudo apt update && sudo apt install -y autoconf gperf make gcc g++ bison flex && \ + cd /tmp && \ + wget ${ICARUS_SRC_URL} && \ + echo ${ICARUS_SRC_HASH} | sha256sum -c && \ + tar -xzf ${ICARUS_SRC_TAR} && \ + cd iverilog-* && sh autoconf.sh && ./configure && make && make check && sudo make install && \ + cd .. && rm ${ICARUS_SRC_TAR} && rm -rf ./iverilog-* + +# copy Verilator installation +USER dev +COPY --from=verilator /usr/local/bin/ /usr/local/bin/ +COPY --from=verilator /usr/local/share/verilator/ /usr/local/share/verilator/ + +# install verilator runtime deps +USER dev +RUN sudo apt update && sudo apt install -y ccache + +# copy quartus prime lite installation +USER dev +COPY --from=quartus /opt/quartus /opt/quartus +ENV PATH="/opt/quartus/quartus/bin:${PATH}" + +# install cocotb +USER dev +RUN sudo apt update && sudo apt install -y python3 python3-pip libpython3-dev && \ + pip3 install cocotb~=1.9 + +# install svlint +USER dev +ARG SVLINT_VERSION=0.9.3 +ARG SVLINT_ZIP_NAME=svlint-v${SVLINT_VERSION}-x86_64-lnx.zip +ARG SVLINT_ZIP_URL=https://github.com/dalance/svlint/releases/download/v${SVLINT_VERSION}/${SVLINT_ZIP_NAME} +ARG SVLINT_ZIP_HASH="df44caa38e0cddd09bafa93365d489e47f4823bdda26aa923028c2f06df90456 ${SVLINT_ZIP_NAME}" +RUN mkdir -p /tmp/svlint && \ + cd /tmp/svlint && \ + wget ${SVLINT_ZIP_URL} && \ + echo ${SVLINT_ZIP_HASH} | sha256sum -c && \ + unzip ${SVLINT_ZIP_NAME} && \ + sudo mv bin/* /usr/local/bin/ && \ + cd .. && rm -r /tmp/svlint + +# install svls +USER dev +ARG SVLS_VERSION=0.2.12 +ARG SVLS_ZIP_NAME=svls-v${SVLS_VERSION}-x86_64-lnx.zip +ARG SVLS_ZIP_URL=https://github.com/dalance/svls/releases/download/v${SVLS_VERSION}/${SVLS_ZIP_NAME} +ARG SVLS_ZIP_HASH="bebdb42731d3d186c7de4263651f0cf06f346f492b30398a128465f50136f33f ${SVLS_ZIP_NAME}" +RUN mkdir -p /tmp/svls && \ + cd /tmp/svls && \ + wget ${SVLS_ZIP_URL} && \ + echo ${SVLS_ZIP_HASH} | sha256sum -c && \ + unzip ${SVLS_ZIP_NAME} && \ + sudo mv svls /usr/local/bin/ && \ + cd .. && rm -r /tmp/svls + +# install riscv toolchain +USER dev +COPY --from=risc-v-toolchain /opt/riscv /opt/riscv +ENV PATH="/opt/riscv/bin:${PATH}" + +# install SAIL simulator +USER dev +ARG SAIL_RISCV_VERSION=0.7 +ARG SAIL_RISCV_ZIP_NAME=sail_riscv-Linux-x86_64.tar.gz +ARG SAIL_RISCV_ZIP_URL=https://github.com/riscv/sail-riscv/releases/download/${SAIL_RISCV_VERSION}/${SAIL_RISCV_ZIP_NAME} +ARG SAIL_RISCV_ZIP_HASH="6b8c3abc3126ce14911a3dec46ff540a60841ef090898f72c4c6f9b0b825efab ${SAIL_RISCV_ZIP_NAME}" +RUN mkdir -p /tmp/sail-riscv && \ + cd /tmp/sail-riscv && \ + wget ${SAIL_RISCV_ZIP_URL} && \ + echo ${SAIL_RISCV_ZIP_HASH} | sha256sum -c && \ + tar -xzf ${SAIL_RISCV_ZIP_NAME} && \ + sudo mv sail_riscv-Linux-x86_64/bin/* /usr/local/bin/ && \ + cd .. && sudo rm -r /tmp/sail-riscv && \ + cd /usr/local/bin && \ + sudo mv riscv_sim_rv32d riscv_sim_RV32 && \ + sudo mv riscv_sim_rv64d riscv_sim_RV64 + +# install riscof +USER dev +RUN pip3 install riscof + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100755 index 0000000..fd3e812 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "utoss-risc-v-devcontainer", + "image": "ghcr.io/utoss/risc-v-devcontainer", + "remoteUser": "dev", + "postStartCommand": "bash -c '.devcontainer/scripts/post-start.sh ${containerWorkspaceFolder}'", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "zsh", + "args": [ + "-l" + ] + } + }, + "terminal.integrated.defaultProfile.linux": "zsh" + }, + "extensions": [ + "mshr-h.VerilogHDL", + "ms-vscode.live-server", + "dalance.svls-vscode", + "tamasfe.even-better-toml" + ] + } + } +} diff --git a/.devcontainer/scripts/post-start.sh b/.devcontainer/scripts/post-start.sh new file mode 100755 index 0000000..2c7f315 --- /dev/null +++ b/.devcontainer/scripts/post-start.sh @@ -0,0 +1,24 @@ +#!/usr/bin/bash + +set -euo pipefail + +WORKSPACE="$1" + +git config --global --add safe.directory "$WORKSPACE" +echo "✅ Added $WORKSPACE to git safe directories" + +echo 'hi' + +if [[ -z "${CODESPACES:-}" ]]; then + SOCK_PATH=$(ls /tmp/vscode-ssh-auth-*.sock 2>/dev/null | head -n1) + if [[ -n "$SOCK_PATH" ]]; then + echo "export SSH_AUTH_SOCK=$SOCK_PATH" >> ~/.zshrc + echo "export SSH_AUTH_SOCK=$SOCK_PATH" >> ~/.bashrc + export SSH_AUTH_SOCK=$SOCK_PATH + echo "✅ Mapped SSH_AUTH_SOCK" + else + echo "⚠️ VS Code agent socket not found; leaving SSH_AUTH_SOCK unchanged" + fi +else + echo "⏩ Skipping SSH_AUTH_SOCK setup for Codespaces" +fi diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7879204..0406e4a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,64 +12,20 @@ permissions: jobs: build_ci_image: - timeout-minutes: 30 - runs-on: ubuntu-latest - outputs: - image-tag: ${{ steps.meta.outputs.tags }} - image-primary-tag: ${{ fromJSON(steps.meta.outputs.json).tags[0] }} - image-digest: ${{ steps.build.outputs.digest }} - - steps: - - name: Free up disk space for Quartus installation - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - sudo apt-get clean - docker system prune -af --volumes - echo "Available space after cleanup:" - df -h - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/utoss/risc-v - tags: | - type=ref,event=branch,prefix=ci-branch- - type=ref,event=pr,prefix=ci-pr- - type=raw,value=latest,prefix=ci-,enable={{is_default_branch}} - - - name: Build and push Docker image - id: build - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile.ci - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64 - cache-from: | - type=gha - type=registry,ref=ghcr.io/utoss/risc-v:buildcache - cache-to: | - type=gha,mode=max - type=registry,ref=ghcr.io/utoss/risc-v:buildcache,mode=max + uses: ./.github/workflows/docker-image.yml + with: + image-name: ghcr.io/utoss/risc-v + dockerfile: ./Dockerfile.ci + tag-prefix: ci- + secrets: inherit + + build_devcontainer_image: + uses: ./.github/workflows/docker-image.yml + with: + image-name: ghcr.io/utoss/risc-v-devcontainer + dockerfile: .devcontainer/Dockerfile + tag-prefix: "" + secrets: inherit svlint: needs: build_ci_image diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..cce70b1 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,83 @@ +name: Docker imge build template workflow + +on: + workflow_call: + inputs: + image-name: + required: true + type: string + dockerfile: + required: true + type: string + tag-prefix: + required: false + type: string + default: "" + outputs: + image-tag: + description: Built image tags + value: ${{ jobs.build.outputs.image-tag }} + image-primary-tag: + description: Primary image tag + value: ${{ jobs.build.outputs.image-primary-tag }} + +jobs: + build: + timeout-minutes: 30 + runs-on: ubuntu-latest + outputs: + image-tag: ${{ steps.meta.outputs.tags }} + image-primary-tag: ${{ fromJSON(steps.meta.outputs.json).tags[0] }} + image-digest: ${{ steps.build.outputs.digest }} + + steps: + - name: Free up disk space + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo apt-get clean + docker system prune -af --volumes + echo "Available space after cleanup:" + df -h + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ inputs.image-name }} + tags: | + type=ref,event=branch,prefix=${{ inputs.tag-prefix }}branch- + type=ref,event=pr,prefix=${{ inputs.tag-prefix }}pr- + type=raw,value=latest,prefix=#{{ inputs.tag-prefix }},enable={{is_default_branch}} + + - name: Build and push Docker image + id: build + uses: docker/build-push-action@v5 + with: + context: . + file: ${{ inputs.dockerfile }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64 + cache-from: | + type=gha + type=registry,ref=${{ inputs.image-name }}:buildcache + cache-to: | + type=gha,mode=max + type=registry,ref=${{ inputs.image-name }}:buildcache,mode=max diff --git a/.gitignore b/.gitignore index 54549ba..8738c93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ *.vvp *.vcd -.devcontainer/ - riscof/riscof_work/ riscof/riscv-arch-test/ riscof/utoss_riscv/__pycache__/ diff --git a/Dockerfile.ci b/Dockerfile.ci index 7ccf702..2279ea4 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,3 +1,5 @@ +FROM ghcr.io/utoss/verilator:latest AS verilator + FROM ghcr.io/utoss/risc-v-toolchain:latest AS risc-v-toolchain FROM ghcr.io/utoss/quartus:latest AS quartus @@ -36,19 +38,14 @@ RUN sudo apt update && sudo apt install -y autoconf gperf make gcc g++ bison fle cd iverilog-* && sh autoconf.sh && ./configure && make && make check && sudo make install && \ cd .. && rm ${ICARUS_SRC_TAR} && rm -rf ./iverilog-* -# build and install Verilator +# copy Verilator installation USER dev -ARG VERILATOR_VERSION=v5.042 -ARG VERILATOR_GIT_REPO=https://github.com/verilator/verilator -RUN sudo apt-get install -y git help2man perl python3 make autoconf g++ flex bison ccache \ - libgoogle-perftools-dev numactl perl-doc \ - libfl2 \ - libfl-dev \ - zlib1g zlib1g-dev && \ - cd /tmp && \ - git clone --depth=1 --branch ${VERILATOR_VERSION} ${VERILATOR_GIT_REPO} && \ - cd verilator && \ - autoconf && ./configure && make -j `nproc` && sudo make install +COPY --from=verilator /usr/local/bin/ /usr/local/bin/ +COPY --from=verilator /usr/local/share/verilator/ /usr/local/share/verilator/ + +# install verilator runtime deps +USER dev +RUN sudo apt update && sudo apt install -y ccache # copy quartus prime lite installation USER dev diff --git a/Dockerfile.verilator b/Dockerfile.verilator new file mode 100644 index 0000000..2f1f7fc --- /dev/null +++ b/Dockerfile.verilator @@ -0,0 +1,18 @@ +FROM public.ecr.aws/lts/ubuntu:22.04_stable AS builder + +ARG VERILATOR_VERSION=v5.042 +ARG VERILATOR_GIT_REPO=https://github.com/verilator/verilator +RUN apt update && apt install -y git help2man perl python3 make autoconf g++ flex bison ccache \ + libgoogle-perftools-dev numactl perl-doc \ + libfl2 \ + libfl-dev \ + zlib1g zlib1g-dev && \ + cd /tmp && \ + git clone --depth=1 --branch ${VERILATOR_VERSION} ${VERILATOR_GIT_REPO} && \ + cd verilator && \ + autoconf && ./configure && make -j `nproc` && make install + +FROM public.ecr.aws/lts/ubuntu:22.04_stable + +COPY --from=builder /usr/local/bin/ /usr/local/bin/ +COPY --from=builder /usr/local/share/verilator/ /usr/local/share/verilator/ diff --git a/README.md b/README.md index 8a26daf..a8d51b2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,10 @@ UTOSS' starter multicycle RISC-V core. ## Getting Started -Checkout Setting up Developement Environment wiki page. +Checkout Setting up Developement Environment wiki page if you wuld like to develop locally. You cant +also create a +[Codespace](https://docs.github.com/en/codespaces/about-codespaces/what-are-codespaces) which will +use our [devcontainer image](.devcontainer/Dockerfile) with all the necessary tools preinstalled. ## Project structure