diff --git a/.github/actions/ibex-rtl-ci-steps/action.yml b/.github/actions/ibex-rtl-ci-steps/action.yml new file mode 100644 index 0000000000..e31d6779d1 --- /dev/null +++ b/.github/actions/ibex-rtl-ci-steps/action.yml @@ -0,0 +1,102 @@ +name: Ibex RTL CI Steps +description: Ibex RTL CI Steps + +inputs: + ibex_config: + required: true + description: Ibex configuration to run CI for + +runs: + using: "composite" + steps: + # ibex_config.py will exit with error code 1 on any error which will cause + # the CI to fail if there's an issue with the configuration file or an + # incorrect configuration name being used + - name: Test and display fusesoc config for ${{ inputs.ibex_config }} + shell: bash + run: | + IBEX_CONFIG_OPTS=`./util/ibex_config.py ${{ inputs.ibex_config }} fusesoc_opts` + echo $IBEX_CONFIG_OPTS + echo "IBEX_CONFIG_OPTS=$IBEX_CONFIG_OPTS" >> $GITHUB_ENV + + - name: Lint Verilog source files with Verilator for ${{ inputs.ibex_config }} + shell: bash + run: | + set +e + fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS + if [ $? != 0 ]; then + echo -n "::error::" + echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors." + exit 1 + fi + + - name: Lint Verilog source files with Verible Verilog Lint for ${{ inputs.ibex_config }} + shell: bash + run: | + set +e + fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS + if [ $? != 0 ]; then + echo -n "::error::" + echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors." + exit 1 + fi + + - name: Run RISC-V Compliance test for Ibex RV32IMC for ${{ inputs.ibex_config }} + shell: bash + run: | + set +e + # Build simulation model of Ibex + fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance $IBEX_CONFIG_OPTS + if [ $? != 0 ]; then + echo -n "::error::" + echo "Unable to build Verilator model of Ibex for compliance testing." + exit 1 + fi + + # Run compliance test suite + export TARGET_SIM=$PWD/build/lowrisc_ibex_ibex_riscv_compliance_0.1/sim-verilator/Vibex_riscv_compliance + export RISCV_PREFIX=riscv32-unknown-elf- + export RISCV_TARGET=ibex + export RISCV_DEVICE=rv32imc + fail=0 + for isa in rv32i rv32im rv32imc rv32Zicsr rv32Zifencei; do + make -C build/riscv-compliance RISCV_ISA=$isa 2>&1 | tee run.log + if [ ${PIPESTATUS[0]} != 0 ]; then + echo -n "::error::" + echo "The RISC-V compliance test suite failed for $isa" + + # There's no easy way to get the test results in machine-readable + # form to properly exclude known-failing tests. Going with an + # approximate solution for now. + if [ $isa == rv32i ] && grep -q 'FAIL: 4/48' run.log; then + echo -n "::error::" + echo "Expected failure for rv32i, see lowrisc/ibex#100 more more information." + else + fail=1 + fi + fi + done + exit $fail + + - name: Run Verilator co-sim tests for for ${{ inputs.ibex_config }} + shell: bash + run: | + source ci/setup-cosim.sh + # Build simple system with co-simulation + fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system_cosim $IBEX_CONFIG_OPTS + + # Run directed tests against simple system co-simulation + ./ci/run-cosim-test.sh --skip-pass-check CoreMark examples/sw/benchmarks/coremark/coremark.elf + + if ./util/ibex_config.py ${{ inputs.ibex_config }} query_fields PMPEnable | grep -q 'PMPEnable=1'; then + ./ci/run-cosim-test.sh --skip-pass-check pmp_smoke examples/sw/simple_system/pmp_smoke_test/pmp_smoke_test.elf + else + echo "PMP not supported on ${{ inputs.ibex_config }}, skipping pmp_smoke_test" + fi + + if ./util/ibex_config.py ${{ inputs.ibex_config }} query_fields SecureIbex | grep -q 'SecureIbex=1'; then + ./ci/run-cosim-test.sh dit_test examples/sw/simple_system/dit_test/dit_test.elf + ./ci/run-cosim-test.sh dummy_instr_test examples/sw/simple_system/dummy_instr_test/dummy_instr_test.elf + else + echo "Security features not supported on ${{ inputs.ibex_config }}, skipping security feature tests" + fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..d0fc5e902c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,150 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# GitHub Actions CI build configuration + +name: Ibex CI + +on: + push: + branches: + - "*" + tags: + - "*" + pull_request: + branches: + - "*" + +# Note: All tests run as part of one job to avoid copying intermediate build +# artifacts around (e.g. Verilator and toolchain builds). Once more builds/tests +# are added, we need to re-evaluate this decision to parallelize jobs and +# improve end-to-end CI times. + +jobs: + lint_dv: + name: Run quality checks (Lint and DV) + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + with: + # Fetch all history so that we can run git diff on the base branch + fetch-depth: 0 + + - name: Setup environment variables + run: | + # Filter out empty lines or comments + grep -v '^\(#\|$\)' ci/vars.env >> $GITHUB_ENV + + - name: Install build dependencies + run: | + ci/install-build-deps.sh + + - name: Display environment + run: | + echo $PATH + python3 --version + echo -n "fusesoc " + fusesoc --version + verilator --version + riscv32-unknown-elf-gcc --version + verible-verilog-lint --version + + # Verible format is experimental so only run on default config for now, + # will eventually become part of the per-config CI + - name: Format all source code with Verible format (experimental) + run: | + set +e + fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing + if [ $? != 0 ]; then + echo -n "::error::" + echo "Verilog format with Verible failed. Run 'fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing' to check and fix all errors." + echo "This flow is currently experimental and failures can be ignored." + fi + # Show diff of what verilog_format would have changed, and then revert. + git diff --no-pager + git reset --hard HEAD + continue-on-error: true + + - name: Use clang-format to check C/C++ coding style + # This check is not idempotent, but checks changes to a base branch. + # Run it only on pull requests. + if: github.event_name == 'pull_request' + run: | + set +e + fork_origin=${{ github.event.pull_request.base.sha }} + changed_files=$(git diff --name-only $fork_origin | grep -v '^vendor' | grep -E '\.(cpp|cc|c|h)$') + test -z "$changed_files" || git diff -U0 $fork_origin $changed_files | clang-format-diff -p1 | tee clang-format-output + if [ -s clang-format-output ]; then + echo -n "::error::" + echo "C/C++ lint failed. Use 'git clang-format' with appropriate options to reformat the changed code." + exit 1 + fi + + - name: Build and run CSR testbench with Verilator + run: | + # Build and run CSR testbench, chosen Ibex configuration does not effect + # this so doesn't need to be part of per-config CI + fusesoc --cores-root=. run --target=sim --tool=verilator lowrisc:ibex:tb_cs_registers + + - name: Get RISC-V Compliance test suite + run: | + cd build + git clone https://github.com/riscv/riscv-compliance.git + cd riscv-compliance + git checkout "$RISCV_COMPLIANCE_GIT_VERSION" + + - name: Build tests for verilator co-simulation + run: | + # Build CoreMark without performance counter dump for co-simulation testing + make -C ./examples/sw/benchmarks/coremark SUPPRESS_PCOUNT_DUMP=1 + make -C ./examples/sw/simple_system/pmp_smoke_test + make -C ./examples/sw/simple_system/dit_test + make -C ./examples/sw/simple_system/dummy_instr_test + + # Run Ibex RTL CI per supported configuration + - name: Run Ibex RTL CI for small configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: small + - name: Run Ibex RTL CI for opentitan configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: opentitan + - name: Run Ibex RTL CI for maxperf configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: maxperf + - name: Run Ibex RTL CI for maxperf-pmp-bmbalanced configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: maxperf-pmp-bmbalanced + - name: Run Ibex RTL CI for maxperf-pmp-bmfull configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: maxperf-pmp-bmfull + - name: Run Ibex RTL CI for experimental-branch-predictor configuration + uses: ./.github/actions/ibex-rtl-ci-steps + with: + ibex_config: experimental-branch-predictor + + # Run lint on simple system + - name: Run Verilator lint on simple system + run: | + set +e + fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system + if [ $? != 0 ]; then + echo -n "::error::" + echo "Verilog lint with Verilator failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system' to check and fix all errors." + exit 1 + fi + + - name: Run Verible lint on simple system + run: | + set +e + fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system + if [ $? != 0 ]; then + echo -n "::error::" + echo "Verilog lint with Verible failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system' to check and fix all errors." + exit 1 + fi diff --git a/ci/install-build-deps.sh b/ci/install-build-deps.sh index 96e197ba4c..1da949aee9 100755 --- a/ci/install-build-deps.sh +++ b/ci/install-build-deps.sh @@ -21,6 +21,10 @@ if [ "$(id -u)" -ne 0 ]; then SUDO_CMD="sudo " fi +if [ -z "$GITHUB_ACTIONS" ]; then + GITHUB_PATH=/dev/null +fi + case "$ID-$VERSION_ID" in ubuntu-16.04|ubuntu-18.04|ubuntu-20.04) # Curl must be available to get the repo key below. @@ -57,12 +61,14 @@ case "$ID-$VERSION_ID" in $SUDO_CMD chmod 777 /tools/riscv-isa-sim $SUDO_CMD tar -C /tools/riscv-isa-sim -xvzf ibex-cosim-"$IBEX_COSIM_VERSION".tar.gz --strip-components=1 echo "##vso[task.prependpath]/tools/riscv-isa-sim/bin" + echo "/tools/riscv-isa-sim/bin" >> $GITHUB_PATH wget https://storage.googleapis.com/verilator-builds/verilator-"$VERILATOR_VERSION".tar.gz $SUDO_CMD mkdir -p /tools/verilator $SUDO_CMD chmod 777 /tools/verilator $SUDO_CMD tar -C /tools/verilator -xvzf verilator-"$VERILATOR_VERSION".tar.gz echo "##vso[task.prependpath]/tools/verilator/$VERILATOR_VERSION/bin" + echo "/tools/verilator/$VERILATOR_VERSION/bin" >> $GITHUB_PATH # Python dependencies # # Updating pip and setuptools is required to have these tools properly @@ -81,6 +87,7 @@ case "$ID-$VERSION_ID" in $SUDO_CMD mkdir -p /tools/verible && $SUDO_CMD chmod 777 /tools/verible tar -C /tools/verible -xf verible.tar.gz --strip-components=1 echo "##vso[task.prependpath]/tools/verible/bin" + echo "/tools/verible/bin" >> $GITHUB_PATH ;; *) @@ -96,3 +103,4 @@ curl -Ls -o build/toolchain/rv32-toolchain.tar.xz "$TOOLCHAIN_URL" $SUDO_CMD mkdir -p /tools/riscv && $SUDO_CMD chmod 777 /tools/riscv tar -C /tools/riscv -xf build/toolchain/rv32-toolchain.tar.xz --strip-components=1 echo "##vso[task.prependpath]/tools/riscv/bin" +echo "/tools/riscv/bin" >> $GITHUB_PATH diff --git a/ci/run-cosim-test.sh b/ci/run-cosim-test.sh index 254ca8bce5..83e8b1d2ec 100755 --- a/ci/run-cosim-test.sh +++ b/ci/run-cosim-test.sh @@ -27,12 +27,14 @@ echo "Running $TEST_NAME with co-simulation" build/lowrisc_ibex_ibex_simple_system_cosim_0/sim-verilator/Vibex_simple_system --meminit=ram,$TEST_ELF if [ $? != 0 ]; then echo "##vso[task.logissue type=error]Running % failed co-simulation testing" + echo "::error::Running % failed co-simulation testing" exit 1 fi grep 'FAILURE' ibex_simple_system.log if [ $? != 1 ]; then echo "##vso[task.logissue type=error]Failure seen in $TEST_NAME log" + echo "::error::Failure seen in $TEST_NAME log" echo "Log contents:" cat ibex_simple_system.log exit 1 @@ -42,6 +44,7 @@ if [ $SKIP_PASS_CHECK != 1 ]; then grep 'PASS' ibex_simple_system.log if [ $? != 0 ]; then echo "##vso[task.logissue type=error]No pass seen in $TEST_NAME log" + echo "::error::No pass seen in $TEST_NAME log" echo "Log contents:" cat ibex_simple_system.log exit 1 diff --git a/ci/vars.env b/ci/vars.env new file mode 100644 index 0000000000..38c8edeb9d --- /dev/null +++ b/ci/vars.env @@ -0,0 +1,15 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# Pipeline variables, used by the public and private CI pipelines +# Quote values to ensure they are parsed as string (version numbers might +# end up as float otherwise). +VERILATOR_VERSION=v4.104 +IBEX_COSIM_VERSION=15fbd568 +RISCV_TOOLCHAIN_TAR_VERSION=20220210-1 +RISCV_TOOLCHAIN_TAR_VARIANT=lowrisc-toolchain-gcc-rv32imcb +RISCV_COMPLIANCE_GIT_VERSION=844c6660ef3f0d9b96957991109dfd80cc4938e2 +VERIBLE_VERSION=v0.0-2135-gb534c1fe +# lowRISC-internal version numbers of Ibex-specific Spike builds. +SPIKE_IBEX_VERSION=20220817-git-eccdcb15c3e51b4f7906c7b42fb824f24a4338a2