| # Azure Pipelines CI build configuration |
| # Documentation at https://aka.ms/yaml |
| |
| variables: |
| VERILATOR_VERSION: 4.010 |
| VERILATOR_PATH: /opt/buildcache/verilator/$(VERILATOR_VERSION) |
| TOOLCHAIN_PATH: /opt/buildcache/riscv |
| # Release tag from https://github.com/lowRISC/lowrisc-toolchains/releases |
| TOOLCHAIN_VERSION: 20191010-1 |
| # This controls where builds happen, and gets picked up by build_consts.sh. |
| BUILD_ROOT: $(Build.ArtifactStagingDirectory) |
| |
| trigger: |
| tags: |
| include: |
| - '*' |
| # Combine builds on master as long as another build is running |
| batch: true |
| branches: |
| include: |
| - master |
| |
| jobs: |
| - job: "lint" |
| displayName: "Run code quality checks (lint)" |
| pool: |
| vmImage: "ubuntu-16.04" |
| steps: |
| - bash: | |
| sudo apt-get remove -y clang-6.0 libclang-common-6.0-dev libclang1-6.0 libllvm6.0 |
| displayName: 'Remove existing Clang installation' |
| - template: 'ci/install-package-dependencies.yml' |
| - bash: | |
| python3 --version |
| yapf --version |
| isort --version |
| clang-format -version |
| displayName: 'Display tool versions' |
| |
| # XXX: Python lint checks are disabled until Issue #313 is resolved |
| # - bash: find ./util -iname '*.py' -print0 | xargs -0 -n1 $PWD/util/lintpy.py -f |
| # displayName: 'Run Python lint' |
| |
| - bash: | |
| make -C hw regs && git diff --exit-code |
| if [ $? != 0 ]; then |
| echo -n "##vso[task.logissue type=error]" |
| echo "Register headers not up-to-date. Regenerate them with 'make -C hw regs'." |
| exit 1 |
| fi |
| condition: always() |
| displayName: 'Ensure all generated files are clean and up-to-date' |
| |
| - bash: | |
| ./util/build_docs.py |
| condition: always() |
| displayName: 'Render documentation' |
| |
| - bash: | |
| cd site/landing |
| ../../build/docs-hugo/hugo |
| condition: always() |
| displayName: 'Render landing site' |
| |
| - bash: | |
| # XXX: As of today, task.logissue comments with 'sourcepath' set don't |
| # get reported to GitHub Checks annotations. Upstream bug report: |
| # https://developercommunity.visualstudio.com/content/problem/689794/pipelines-logging-command-logissue-does-not-report.html |
| #echo "##vso[task.issue type=error;sourcepath=/azure-pipelines.yml;linenumber=45;columnnumber=1;code=100;]Found something that could be a problem." |
| fork_origin=$(git merge-base --fork-point origin/master) |
| 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 "##vso[task.logissue type=error]" |
| echo "C/C++ lint failed. Use 'git clang-format' with appropriate options to reformat the changed code." |
| exit 1 |
| fi |
| # This check is not idempotent, but checks changes to a base branch. |
| # Run it only on pull requests. |
| condition: eq(variables['Build.Reason'], 'PullRequest') |
| displayName: 'Use clang-format to check C/C++ coding style' |
| |
| - bash: | |
| fork_origin="$(git merge-base --fork-point origin/master)" |
| changed_files="$(git diff --name-only "$fork_origin")" |
| if [[ -z "$changed_files" ]]; then |
| xargs util/fix_include_guard.py --dry-run <<< "$changed_files" | tee fix-include-guard-output |
| if [[ -s fix-include-guard-output ]]; then |
| echo -n "##vso[task.logissue type=error]" |
| echo "Include guard check failed. Please run util/fix_include_guard.py on the above files." |
| exit 1 |
| fi |
| fi |
| condition: eq(variables['Build.Reason'], 'PullRequest') |
| displayName: 'Check formatting on header guards' |
| |
| - bash: | |
| commit_range=$(git merge-base --fork-point origin/master)..HEAD |
| # Notes: |
| # * Merge commits are not checked. We always use rebases instead of |
| # merges to keep a linear history, which makes merge commits disappear |
| # ultimately, making them only a CI artifact which should not be |
| # checked. |
| # * 'type=error' is used even for warnings. Only "errors" are shown in |
| # the GitHub checks API. However, warnings don't return a non-zero |
| # error code and don't fail the build step. |
| ./util/lint_commits.py \ |
| --no-merges \ |
| --error-msg-prefix='##vso[task.logissue type=error]' \ |
| --warning-msg-prefix='##vso[task.logissue type=error]' \ |
| $commit_range |
| # Only run on pull requests to check new commits only |
| condition: eq(variables['Build.Reason'], 'PullRequest') |
| displayName: "Check commit metadata" |
| |
| - bash: | |
| only_doc_changes=0 |
| if [ "$(Build.Reason)" = "PullRequest" ]; then |
| # Conservative way of checking for documentation-only changes. |
| # Only relevant for pipelines triggered from pull requests |
| echo "Checking for doc-only changes in this pull request" |
| fork_origin=$(git merge-base --fork-point origin/master) |
| only_doc_changes=$(git diff --name-only $fork_origin | grep -v '\.md$' -q; echo $?) |
| fi |
| echo "##vso[task.setvariable variable=onlyDocChanges;isOutput=true]${only_doc_changes}" |
| displayName: "Check if the commit only contains documentation changes" |
| name: DetermineBuildType |
| |
| - job: "sw_build" |
| displayName: "Build Software" |
| dependsOn: lint |
| condition: and(succeeded(), eq(dependencies.lint.outputs['DetermineBuildType.onlyDocChanges'], '0')) |
| pool: |
| vmImage: "ubuntu-16.04" |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - bash: | |
| set -x |
| sudo util/get-toolchain.py \ |
| --target-dir="${TOOLCHAIN_PATH}" \ |
| --release-version="${TOOLCHAIN_VERSION}" \ |
| --update |
| displayName: 'Install toolchain' |
| - bash: | |
| . util/build_consts.sh |
| ./meson_init.sh -A |
| ninja -C "$(sw_obj_dir sim-verilator)" all |
| ninja -C "$(sw_obj_dir fpga)" all |
| displayName: 'Build embedded targets' |
| - template: 'ci/upload-artifacts-template.yml' |
| parameters: |
| artifact: sw_build |
| |
| - job: "top_earlgrey_verilator" |
| displayName: "Build Verilator simulation of the Earl Grey toplevel design" |
| dependsOn: lint |
| condition: and(succeeded(), eq(dependencies.lint.outputs['DetermineBuildType.onlyDocChanges'], '0')) |
| pool: Default |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - bash: | |
| set -e |
| if [ ! -d $(VERILATOR_PATH) ]; then |
| echo "Building verilator (no cached build found)" |
| mkdir -p build/verilator |
| cd build/verilator |
| curl -Ls -o verilator.tgz https://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz |
| tar -xf verilator.tgz |
| cd verilator-$(VERILATOR_VERSION) |
| ./configure --prefix=$(VERILATOR_PATH) |
| make -j$(nproc) |
| mkdir -p $VERILATOR_PATH |
| make install |
| else |
| echo "Re-using cached verilator build" |
| fi |
| displayName: 'Build and install Verilator' |
| - bash: | |
| export PATH=$VERILATOR_PATH/bin:$PATH |
| python3 --version |
| fusesoc --version |
| verilator --version |
| displayName: 'Display environment' |
| - bash: | |
| . util/build_consts.sh |
| mkdir -p "$OBJ_DIR/hw" |
| mkdir -p "$BIN_DIR/hw/top_earlgrey" |
| |
| export PATH=$VERILATOR_PATH/bin:$PATH |
| fusesoc --cores-root=. \ |
| run --target=sim --setup --build \ |
| --build-root="$OBJ_DIR/hw" \ |
| lowrisc:systems:top_earlgrey_verilator |
| |
| cp "$OBJ_DIR/hw/sim-verilator/Vtop_earlgrey_verilator" \ |
| "$BIN_DIR/hw/top_earlgrey" |
| displayName: 'Build simulation with Verilator' |
| - template: 'ci/upload-artifacts-template.yml' |
| parameters: |
| artifact: top_earlgrey_verilator |
| |
| - job: "execute_verilated_tests" |
| displayName: "Execute tests on the Verilated system" |
| pool: |
| vmImage: "ubuntu-16.04" |
| dependsOn: |
| - top_earlgrey_verilator |
| - sw_build |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - template: 'ci/download-artifacts-template.yml' |
| - bash: | |
| . util/build_consts.sh |
| export VERILATED_SYSTEM_PATH="$BIN_DIR/hw/top_earlgrey/Vtop_earlgrey_verilator" |
| pytest --version |
| ci/run_verilator_pytest.sh |
| displayName: 'Execute tests' |
| |
| - job: "riscv_compliance_tests" |
| displayName: "Execute RISC-V compliance tests" |
| pool: |
| vmImage: "ubuntu-16.04" |
| dependsOn: |
| - top_earlgrey_verilator |
| - execute_verilated_tests |
| # TODO: re-enable this CI step once RISC-V compliance correctly calls into |
| # Meson. See #1181. |
| condition: False |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - template: 'ci/download-artifacts-template.yml' |
| - bash: | |
| . util/build_consts.sh |
| export TARGET_SIM="$BIN_DIR/hw/top_earlgrey/Vtop_earlgrey_verilator" |
| export RISCV_DEVICE=rv32imc |
| export RISCV_TARGET=opentitan |
| export OT_TARGET=verilator |
| export OT_TOOLS="$TOOLCHAIN_PATH/bin" |
| cd sw/vendor/riscv_compliance |
| # Only running base interger variant for now, others will be added later. |
| make RISCV_ISA=rv32i |
| displayName: 'Execute tests' |
| |
| - job: "top_earlgrey_nexysvideo" |
| displayName: "Build NexysVideo variant of the Earl Grey toplevel design using Vivado" |
| dependsOn: |
| - lint |
| # The bootrom is built into the FPGA image at synthesis time. |
| - sw_build |
| condition: and(succeeded(), eq(dependencies.lint.outputs['DetermineBuildType.onlyDocChanges'], '0')) |
| pool: Default |
| timeoutInMinutes: 120 # 2 hours |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - template: 'ci/download-artifacts-template.yml' |
| - bash: | |
| set -e |
| . util/build_consts.sh |
| mkdir -p "$OBJ_DIR/hw" |
| mkdir -p "$BIN_DIR/hw/top_earlgrey" |
| |
| BOOTROM_VMEM="$BIN_DIR/sw/device/fpga/boot_rom/boot_rom.vmem" |
| test -f "$BOOTROM_VMEM" |
| |
| . /opt/xilinx/Vivado/2018.3/settings64.sh |
| fusesoc --cores-root=. \ |
| run --target=synth --setup --build \ |
| --build-root="$OBJ_DIR/hw" \ |
| lowrisc:systems:top_earlgrey_nexysvideo \ |
| --ROM_INIT_FILE="$BOOTROM_VMEM" |
| |
| cp "$OBJ_DIR/hw/synth-vivado/lowrisc_systems_top_earlgrey_nexysvideo_0.1.bit" \ |
| "$BIN_DIR/hw/top_earlgrey" |
| displayName: 'Build bitstream with Vivado' |
| - template: 'ci/upload-artifacts-template.yml' |
| parameters: |
| artifact: top_earlgrey_nexysvideo |
| |
| - job: "deploy_releaseartifacts" |
| displayName: "Package and deploy release distribution" |
| pool: |
| vmImage: "ubuntu-latest" |
| dependsOn: |
| - lint |
| - sw_build |
| - top_earlgrey_verilator |
| - top_earlgrey_nexysvideo |
| condition: eq(dependencies.lint.outputs['DetermineBuildType.onlyDocChanges'], '0') |
| steps: |
| - template: 'ci/install-package-dependencies.yml' |
| - template: 'ci/download-artifacts-template.yml' |
| - bash: | |
| . util/build_consts.sh |
| |
| util/make_distribution.sh |
| |
| tar --list -f $BIN_DIR/opentitan-*.tar.xz |
| # Put the resulting tar file into a directory the |publish| step below can reference. |
| mkdir "$BUILD_ROOT/dist-final" |
| mv $BIN_DIR/opentitan-*.tar.xz "$BUILD_ROOT/dist-final" |
| displayName: 'Create final dist directory out of partial ones' |
| - publish: $(Build.ArtifactStagingDirectory)/dist-final |
| artifact: opentitan-dist |
| displayName: "Upload release artifacts as Azure artifact" |
| - task: GithubRelease@0 |
| displayName: 'Upload to GitHub releases (only tags)' |
| condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/')) |
| inputs: |
| gitHubConnection: opentitan-release-upload |
| repositoryName: lowrisc/opentitan |
| addChangeLog: false |
| assets: | |
| $(Build.ArtifactStagingDirectory)/dist-final/* |