| # Azure Pipelines CI build configuration | 
 | # Documentation at https://aka.ms/yaml | 
 |  | 
 | variables: | 
 |   VERILATOR_VERSION: 4.028 | 
 |   VERILATOR_PATH: /opt/buildcache/verilator/$(VERILATOR_VERSION) | 
 |   TOOLCHAIN_PATH: /opt/buildcache/riscv | 
 |   # Release tag from https://github.com/lowRISC/lowrisc-toolchains/releases | 
 |   # if you update this, update the definition in util/container/Dockerfile | 
 |   TOOLCHAIN_VERSION: 20191010-1 | 
 |   # This controls where builds happen, and gets picked up by build_consts.sh. | 
 |   BUILD_ROOT: $(Build.ArtifactStagingDirectory) | 
 |  | 
 | trigger: | 
 |   batch: true | 
 |   branches: | 
 |     include: | 
 |     - '*' | 
 |   tags: | 
 |     include: | 
 |     - "*" | 
 | pr: | 
 |   branches: | 
 |     include: | 
 |     - '*' | 
 |  | 
 | 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 | 
 |       flake8 --version | 
 |       ninja --version | 
 |       meson --version | 
 |       echo "PATH=$PATH" | 
 |     displayName: Display tool versions | 
 |   - bash: | | 
 |       fork_origin="$(git merge-base --fork-point origin/master)" | 
 |       git diff --name-only "$fork_origin" "*.py" \ | 
 |         | xargs -r util/lintpy.py --tools flake8 -f | 
 |     displayName: Run Python lint | 
 |     continueOnError: true | 
 |   - 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)$')" | 
 |       if [[ -n "$changed_files" ]]; then | 
 |         xargs 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 | 
 |       fi | 
 |     # This check is not idempotent, but checks changes to a base branch. | 
 |     # Run it only on pull requests. Note that the git diff filter (ACMRTUXB) omits | 
 |     # files that are deleted in a PR, since those break the checker script below. | 
 |     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 --diff-filter=ACMRTUXB "$fork_origin")" | 
 |       if [[ -n "$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 "$OBJ_DIR" all | 
 |     displayName: Build embedded targets | 
 |   - template: ci/upload-artifacts-template.yml | 
 |   - bash: | | 
 |       . util/build_consts.sh | 
 |       ninja -C "$OBJ_DIR" test | 
 |     displayName: 'Run unit tests' | 
 |   - 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 | 
 |  | 
 | - template: ci/run-riscv-compliance.yml | 
 |   parameters: | 
 |     rvc_test_suites: | 
 |       - rv32i | 
 |  | 
 | - template: ci/run-riscv-compliance.yml | 
 |   parameters: | 
 |     rvc_test_suites: | 
 |       - rv32im | 
 |       - rv32imc | 
 |       - rv32Zicsr | 
 |  | 
 | - 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/boot_rom/boot_rom_fpga_nexysvideo.32.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 \ | 
 |         --BootRomInitFile="$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_release_artifacts | 
 |   displayName: Package and deploy release distribution | 
 |   pool: | 
 |     vmImage: ubuntu-16.04 | 
 |   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/* |