diff --git a/.github/workflows/checkfmt.yml b/.github/workflows/checkfmt.yml new file mode 100644 index 0000000..077ec5d --- /dev/null +++ b/.github/workflows/checkfmt.yml @@ -0,0 +1,46 @@ +name: Check the format of a PR +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + - labeled +env: + USER: runner + +# Cancel the current workflow when new commit pushed +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + + check-format: + name: "Check format" + runs-on: [self-hosted, linux, nixos] + strategy: + fail-fast: false + defaults: + run: + working-directory: ./templates/chisel + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: "Check Scala format" + continue-on-error: true + run: | + nix develop -c bash -c 'mill -i gcd.checkFormat && mill -i elaborator.checkFormat' + - name: "Check Rust format" + continue-on-error: true + run: | + cd gcdemu + nix develop -c cargo fmt --check + cd .. + - name: "Check nix format" + continue-on-error: true + run: | + nix fmt -- --check nix flake.nix + diff --git a/.github/workflows/daily-bump.yml b/.github/workflows/daily-bump.yml new file mode 100644 index 0000000..2424efb --- /dev/null +++ b/.github/workflows/daily-bump.yml @@ -0,0 +1,66 @@ +name: Dependencies Bump +on: + schedule: + # Run this job everyday at 5:30 AM UTC+8 + - cron: '30 21 * * *' + +jobs: + bump-deps: + name: "Bump Chisel and CIRCT" + if: ${{ !cancelled() }} + runs-on: [self-hosted, linux, nixos] + permissions: + contents: write + defaults: + run: + working-directory: ./templates/chisel + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: master + - name: Bump nixpkgs + run: | + nix flake update + - name: Bump Chisel + run: | + cd nix/pkgs/dependencies + nix run '.#nvfetcher' -- -f '^chisel$' + - name: Bump all mill deps + run: | + oldHash=$(nix derivation show .#gcd.gcd-compiled.millDeps | jq -r 'to_entries[0].value.env.outputHash') + nix build '.#gcd.gcd-compiled.millDeps' --rebuild > milldeps-log.txt 2>&1 || true + newHash=$(cat milldeps-log.txt \ + | grep -P '^\s+got:\s+sha256-.*$' \ + | cut -d':' -f2 \ + | xargs) + if [ -z "$newHash" ] || [ "$newHash" = "$oldHash" ]; then + echo "Original build logs for debug: " + cat milldeps-log.txt + echo "Hash unchanged, exit" + exit 0 + fi + echo "Updating hash $oldHash to $newHash" + sed -i "s|$oldHash|$newHash|" nix/gcd/gcd.nix + - name: Commit changes + env: + GITHUB_TOKEN: ${{ secrets.BIYUN_GITHUB_ACTION }} + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + currentDate=$(date +%F) + branch="dependencies-bumping-$currentDate" + git checkout -b "$branch" + + git add 'nix/pkgs/dependencies' + git add 'flake.lock' + + if ! git diff --quiet --cached --exit-code; then + updatedFiles=$(git diff --cached --name-only) + echo "File changed" + git commit -m "[deps] Bump dependencies" + git push origin "$branch" --force-with-lease + nix run '.#gh' -- \ + pr create --title "Bump dependencies" --body "Updated: $updatedFiles" + fi diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..134810b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,75 @@ +name: Build and Run Simulation +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + - labeled +env: + USER: runner + +# Cancel the current workflow when new commit pushed +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + + build-simulators: + name: "Build Simulators" + runs-on: [self-hosted, linux, nixos, BIGRAM] + strategy: + fail-fast: false + defaults: + run: + working-directory: ./templates/chisel + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: "Build vcs simulator" + run: | + nix build '.#gcd.vcs' --impure + - name: "Build vcs simulator with trace" + run: | + nix build '.#gcd.vcs-trace' --impure + - name: "Build verilator simulator" + run: | + nix build '.#gcd.verilated' + - name: "Build verilator simulator with trace" + run: | + nix build '.#gcd.verilated-trace' + + run-vcs: + name: "Run VCS" + strategy: + fail-fast: false + runs-on: [self-hosted, linux, nixos] + defaults: + run: + working-directory: ./templates/chisel + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: "Run VCS" + run: | + nix build '.#gcd.vcs.tests.simple-sim' --impure -L + + run-verilator: + name: "Run Verilator" + strategy: + fail-fast: false + runs-on: [self-hosted, linux, nixos] + defaults: + run: + working-directory: ./templates/chisel + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: "Run verilator" + run: | + nix run '.#gcd.verilated' diff --git a/templates/chisel/.gitignore b/templates/chisel/.gitignore index f373a7b..338f9fc 100644 --- a/templates/chisel/.gitignore +++ b/templates/chisel/.gitignore @@ -1,7 +1,17 @@ .bloop +.bsp +.jvm-opts +.mill-jvm-opts .metals/ .vscode/ + out/ result* +gcd-sim-result/ /dependencies/ target/ + +*.vcd +*.fst +*.fsdb +*.log diff --git a/templates/chisel/.scalafmt.conf b/templates/chisel/.scalafmt.conf index c839f64..0310aaa 100644 --- a/templates/chisel/.scalafmt.conf +++ b/templates/chisel/.scalafmt.conf @@ -10,7 +10,7 @@ lineEndings = preserve includeCurlyBraceInSelectChains = false danglingParentheses.preset = true -align.tokens.add = [ +align.tokens."+" = [ { code = ":" } diff --git a/templates/chisel/build.sc b/templates/chisel/build.sc index 4da6ed7..3b79023 100644 --- a/templates/chisel/build.sc +++ b/templates/chisel/build.sc @@ -37,7 +37,7 @@ trait GCD extends millbuild.common.HasChisel with ScalafmtModule { } object elaborator extends Elaborator -trait Elaborator extends millbuild.common.ElaboratorModule { +trait Elaborator extends millbuild.common.ElaboratorModule with ScalafmtModule { def scalaVersion = T(deps.scalaVer) def panamaconverterModule = panamaconverter diff --git a/templates/chisel/configs/GCDTestBenchMain.json b/templates/chisel/configs/GCDTestBenchMain.json index c6ee49f..2daa26b 100644 --- a/templates/chisel/configs/GCDTestBenchMain.json +++ b/templates/chisel/configs/GCDTestBenchMain.json @@ -10,6 +10,6 @@ "width": 16, "useAsyncReset": false }, - "timeout": 5000, + "timeout": 70000, "testSize": 100 } diff --git a/templates/chisel/elaborator/src/GCD.scala b/templates/chisel/elaborator/src/GCD.scala index c0959f9..fb92fdc 100644 --- a/templates/chisel/elaborator/src/GCD.scala +++ b/templates/chisel/elaborator/src/GCD.scala @@ -11,6 +11,8 @@ object GCDMain extends Elaborator { case class GCDParameterMain( @arg(name = "xLen") xLen: Int, @arg(name = "useAsyncReset") useAsyncReset: Boolean) { + require(xLen > 0, "xLen must be a non-negative integer") + require(chisel3.util.isPow2(xLen), "xLen must be a power of 2") def convert: GCDParameter = GCDParameter(xLen, useAsyncReset) } diff --git a/templates/chisel/flake.nix b/templates/chisel/flake.nix index c796c60..db27558 100644 --- a/templates/chisel/flake.nix +++ b/templates/chisel/flake.nix @@ -20,7 +20,8 @@ overlays = [ overlay ]; inherit system; }; - in { + in + { formatter = pkgs.nixpkgs-fmt; legacyPackages = pkgs; devShells.default = pkgs.mkShell ({ diff --git a/templates/chisel/gcdemu/src/drive.rs b/templates/chisel/gcdemu/src/drive.rs index 700d6ed..98fe414 100644 --- a/templates/chisel/gcdemu/src/drive.rs +++ b/templates/chisel/gcdemu/src/drive.rs @@ -107,8 +107,8 @@ impl Driver { WATCHDOG_FINISH } else if tick - self.last_input_cycle > self.timeout { error!( - "[{}] watchdog timeout, last input tick = {}", - tick, self.last_input_cycle + "[{}] watchdog timeout, last input tick = {}, {} tests completed", + tick, self.last_input_cycle, self.test_num ); WATCHDOG_TIMEOUT } else { diff --git a/templates/chisel/nix/gcd/default.nix b/templates/chisel/nix/gcd/default.nix index 947afc4..c4bc76f 100644 --- a/templates/chisel/nix/gcd/default.nix +++ b/templates/chisel/nix/gcd/default.nix @@ -3,56 +3,55 @@ { lib, newScope, }: lib.makeScope newScope (scope: - let - designTarget = "GCD"; - tbTarget = "GCDTestBench"; - dpiLibName = "gcdemu"; - in { - # RTL - gcd-compiled = scope.callPackage ./gcd.nix { target = designTarget; }; - elaborate = scope.callPackage ./elaborate.nix { - elaborator = scope.gcd-compiled.elaborator; - }; - mlirbc = scope.callPackage ./mlirbc.nix { }; - rtl = scope.callPackage ./rtl.nix { }; +let + designTarget = "GCD"; + tbTarget = "GCDTestBench"; + dpiLibName = "gcdemu"; +in +{ + # RTL + gcd-compiled = scope.callPackage ./gcd.nix { target = designTarget; }; + elaborate = scope.callPackage ./elaborate.nix { + elaborator = scope.gcd-compiled.elaborator; + }; + mlirbc = scope.callPackage ./mlirbc.nix { }; + rtl = scope.callPackage ./rtl.nix { }; - # Testbench - tb-compiled = scope.callPackage ./gcd.nix { target = tbTarget; }; - tb-elaborate = scope.callPackage ./elaborate.nix { - elaborator = scope.tb-compiled.elaborator; - }; - tb-mlirbc = - scope.callPackage ./mlirbc.nix { elaborate = scope.tb-elaborate; }; - tb-rtl = scope.callPackage ./rtl.nix { mlirbc = scope.tb-mlirbc; }; - tb-dpi-lib = scope.callPackage ./dpi-lib.nix { inherit dpiLibName; }; + # Testbench + tb-compiled = scope.callPackage ./gcd.nix { target = tbTarget; }; + tb-elaborate = scope.callPackage ./elaborate.nix { + elaborator = scope.tb-compiled.elaborator; + }; + tb-mlirbc = + scope.callPackage ./mlirbc.nix { elaborate = scope.tb-elaborate; }; + tb-rtl = scope.callPackage ./rtl.nix { mlirbc = scope.tb-mlirbc; }; + tb-dpi-lib = scope.callPackage ./dpi-lib.nix { inherit dpiLibName; }; - verilated = scope.callPackage ./verilated.nix { - rtl = scope.tb-rtl.override { enable-layers = [ "Verification" ]; }; - dpi-lib = scope.tb-dpi-lib; - }; - verilated-trace = scope.verilated.override { - dpi-lib = scope.verilated.dpi-lib.override { enable-trace = true; }; - }; - vcs = scope.callPackage ./vcs.nix { - dpi-lib = scope.tb-dpi-lib.override { - sv2023 = false; - vpi = true; - }; - rtl = scope.tb-rtl.override { - enable-layers = - [ "Verification" "Verification.Assert" "Verification.Cover" ]; - }; + verilated = scope.callPackage ./verilated.nix { + rtl = scope.tb-rtl.override { enable-layers = [ "Verification" ]; }; + dpi-lib = scope.tb-dpi-lib; + }; + verilated-trace = scope.verilated.override { + dpi-lib = scope.verilated.dpi-lib.override { enable-trace = true; }; + }; + vcs = scope.callPackage ./vcs.nix { + dpi-lib = scope.tb-dpi-lib.override { + sv2023 = false; + vpi = true; + timescale = 1000; }; - vcs-trace = scope.vcs.override { - dpi-lib = scope.vcs.dpi-lib.override { - enable-trace = true; - timescale = 1000; - }; + rtl = scope.tb-rtl.override { + enable-layers = + [ "Verification" "Verification.Assert" "Verification.Cover" ]; }; + }; + vcs-trace = scope.vcs.override { + dpi-lib = scope.vcs.dpi-lib.override { enable-trace = true; }; + }; - # TODO: designConfig should be read from OM - tbConfig = with builtins; - fromJSON (readFile ./../../configs/${tbTarget}Main.json); + # TODO: designConfig should be read from OM + tbConfig = with builtins; + fromJSON (readFile ./../../configs/${tbTarget}Main.json); - }) +}) diff --git a/templates/chisel/nix/gcd/dpi-lib.nix b/templates/chisel/nix/gcd/dpi-lib.nix index c388c82..b4dcb56 100644 --- a/templates/chisel/nix/gcd/dpi-lib.nix +++ b/templates/chisel/nix/gcd/dpi-lib.nix @@ -1,8 +1,15 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2024 Jiuyang Liu -{ lib, rustPlatform, tbConfig, dpiLibName, sv2023 ? true, vpi ? false -, enable-trace ? false, timescale ? 1 }: +{ lib +, rustPlatform +, tbConfig +, dpiLibName +, sv2023 ? true +, vpi ? false +, enable-trace ? false +, timescale ? 1 +}: rustPlatform.buildRustPackage rec { name = "dpi-lib"; diff --git a/templates/chisel/nix/gcd/gcd.nix b/templates/chisel/nix/gcd/gcd.nix index 0198a8c..42dd4bb 100644 --- a/templates/chisel/nix/gcd/gcd.nix +++ b/templates/chisel/nix/gcd/gcd.nix @@ -1,14 +1,23 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2024 Jiuyang Liu -{ lib, stdenv, fetchMillDeps, makeWrapper, jdk21 - -# chisel deps -, mill, espresso, circt-full, jextract-21, add-determinism +{ lib +, stdenv +, fetchMillDeps +, makeWrapper +, jdk21 + + # chisel deps +, mill +, espresso +, circt-full +, jextract-21 +, add-determinism , projectDependencies -, target }: +, target +}: let self = stdenv.mkDerivation rec { @@ -70,6 +79,8 @@ let outputs = [ "out" "elaborator" ]; + meta.mainProgram = "elaborator"; + buildPhase = '' mill -i '__.assembly' ''; @@ -86,4 +97,5 @@ let --add-flags "--enable-preview -Djava.library.path=${circt-full}/lib -cp $out/share/java/elaborator.jar ${mainClass}" ''; }; -in self +in +self diff --git a/templates/chisel/nix/gcd/rtl.nix b/templates/chisel/nix/gcd/rtl.nix index 3ac8630..8cd8a77 100644 --- a/templates/chisel/nix/gcd/rtl.nix +++ b/templates/chisel/nix/gcd/rtl.nix @@ -1,17 +1,24 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2024 Jiuyang Liu -{ lib, stdenvNoCC, circt, mlirbc, mfcArgs ? [ - "-O=release" - "--split-verilog" - "--preserve-values=all" - "--lowering-options=verifLabels,omitVersionComment" - "--strip-debug-info" -], enable-layers ? [ ] }: +{ lib +, stdenvNoCC +, circt +, mlirbc +, mfcArgs ? [ + "-O=release" + "--split-verilog" + "--preserve-values=all" + "--lowering-options=verifLabels,omitVersionComment" + "--strip-debug-info" + ] +, enable-layers ? [ ] +}: let processLayer = lib.map (str: "./" + lib.replaceStrings [ "." ] [ "/" ] str); enableLayersDirs = processLayer enable-layers; -in stdenvNoCC.mkDerivation { +in +stdenvNoCC.mkDerivation { name = "${mlirbc.name}-rtl"; nativeBuildInputs = [ circt ]; diff --git a/templates/chisel/nix/gcd/vcs-wrapper.sh b/templates/chisel/nix/gcd/vcs-wrapper.sh new file mode 100755 index 0000000..52efad2 --- /dev/null +++ b/templates/chisel/nix/gcd/vcs-wrapper.sh @@ -0,0 +1,42 @@ +#!@shell@ + +_EXTRA_ARGS="$@" + +if ((${VERBOSE:-0})); then + set -x +fi + +_DATE_BIN=@dateBin@ +_VCS_SIM_BIN=@vcsSimBin@ +_VCS_SIM_DAIDIR=@vcsSimDaidir@ +_VCS_FHS_ENV=@vcsFhsEnv@ + +_NOW=$("$_DATE_BIN" "+%Y-%m-%d-%H-%M-%S") +_GCD_SIM_RESULT_DIR=${GCD_SIM_RESULT_DIR:-"gcd-sim-result"} +_CURRENT="$_GCD_SIM_RESULT_DIR"/all/"$_NOW" +mkdir -p "$_CURRENT" +ln -sfn "all/$_NOW" "$_GCD_SIM_RESULT_DIR/result" + +cp "$_VCS_SIM_BIN" "$_CURRENT/" +cp -r "$_VCS_SIM_DAIDIR" "$_CURRENT/" + +chmod -R +w "$_CURRENT" + +pushd "$_CURRENT" >/dev/null + +_emu_name=$(basename "$_VCS_SIM_BIN") +_daidir=$(basename "$_VCS_SIM_DAIDIR") + +export LD_LIBRARY_PATH="$PWD/$_daidir:$LD_LIBRARY_PATH" + +"$_VCS_FHS_ENV" -c "./$_emu_name $_EXTRA_ARGS" &> >(tee vcs-emu-journal.log) + +if ((${DATA_ONLY:-0})); then + rm -f "./$_emu_name" +fi + +set -e _emu_name _daidir + +popd >/dev/null + +echo "VCS emulator finished, result saved in $_GCD_SIM_RESULT_DIR/result" diff --git a/templates/chisel/nix/gcd/vcs.nix b/templates/chisel/nix/gcd/vcs.nix index 68ec6f0..40bb5c2 100644 --- a/templates/chisel/nix/gcd/vcs.nix +++ b/templates/chisel/nix/gcd/vcs.nix @@ -1,9 +1,19 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2024 Jiuyang Liu -{ lib, bash, stdenv, rtl, dpi-lib, vcs-fhs-env }: -let binName = "gcd-vcs-simulator"; -in stdenv.mkDerivation { +{ lib +, bash +, stdenv +, rtl +, dpi-lib +, vcs-fhs-env +, runCommand +}: + +let + binName = "gcd-vcs-simulator"; +in +stdenv.mkDerivation (finalAttr: { name = "vcs"; # Add "sandbox = relaxed" into /etc/nix/nix.conf, and run `systemctl restart nix-daemon` @@ -15,6 +25,8 @@ in stdenv.mkDerivation { src = rtl; + meta.mainProgram = binName; + buildPhase = '' runHook preBuild @@ -44,6 +56,15 @@ in stdenv.mkDerivation { inherit vcs-fhs-env; inherit dpi-lib; inherit rtl; + + tests.simple-sim = runCommand "${binName}-test" { __noChroot = true; } '' + export GCD_SIM_RESULT_DIR="$(mktemp -d)" + export DATA_ONLY=1 + ${finalAttr.finalPackage}/bin/${binName} + + mkdir -p "$out" + cp -vr "$GCD_SIM_RESULT_DIR"/result/* "$out/" + ''; }; shellHook = '' @@ -58,15 +79,14 @@ in stdenv.mkDerivation { cp ${binName} $out/lib cp -r ${binName}.daidir $out/lib - # We need to carefully handle string escape here, so don't use makeWrapper - tee $out/bin/${binName} <