| # 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 |
| 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. |
| 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 [[ -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 \ |
| --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_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/* |