diff --git a/.github/workflows/ci-tests.yaml b/.github/workflows/ci-tests.yaml index b9016219ae..b1905c30ec 100644 --- a/.github/workflows/ci-tests.yaml +++ b/.github/workflows/ci-tests.yaml @@ -1,105 +1,106 @@ +--- # This workflow runs after a pull-request has been approved by a reviewer. name: CI Tests on: - pull_request: - types: [opened, edited, synchronize, ready_for_review] + pull_request: + types: [opened, edited, synchronize, ready_for_review] concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true jobs: - pre-commit: + pre-commit: # runs on github hosted runner - runs-on: ubuntu-22.04 - if: github.event.pull_request.draft == false - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - - uses: pre-commit/action@v3.0.0 + runs-on: ubuntu-22.04 + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 # ensures we have a change-id in every commit, needed for gerrit - check-for-change-id: - # runs on github hosted runner - runs-on: ubuntu-22.04 - if: github.event.pull_request.draft == false - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Check for Change-Id - run: | - # loop through all the commits in the pull request - for commit in $(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}); do - git checkout $commit - if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ") - then - # passes as long as at least one change-id exists in the pull request - exit 0 - fi - done - # if we reach this part, none of the commits had a change-id - echo "None of the commits in this pull request contains a Change-ID, which we require for any changes made to gem5. "\ - "To automatically insert one, run the following:\n f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; "\ - "curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f\n Then amend the commit with git commit --amend --no-edit, and update your pull request." - exit 1 + check-for-change-id: + # runs on github hosted runner + runs-on: ubuntu-22.04 + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Check for Change-Id + run: | + # loop through all the commits in the pull request + for commit in $(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}); do + git checkout $commit + if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ") + then + # passes as long as at least one change-id exists in the pull request + exit 0 + fi + done + # if we reach this part, none of the commits had a change-id + echo "None of the commits in this pull request contains a Change-ID, which we require for any changes made to gem5. "\ + "To automatically insert one, run the following:\n f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; "\ + "curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f\n Then amend the commit with git commit --amend --no-edit, and update your pull request." + exit 1 - unittests-all-opt: - runs-on: [self-hosted, linux, x64] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id] # only runs if pre-commit and change-id passes - timeout-minutes: 60 - steps: - - uses: actions/checkout@v3 - - name: CI Unittests - working-directory: ${{ github.workspace }} - run: scons build/ALL/unittests.opt -j $(nproc) - - run: echo "This job's status is ${{ job.status }}." + unittests-all-opt: + runs-on: [self-hosted, linux, x64] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id] # only runs if pre-commit and change-id passes + timeout-minutes: 60 + steps: + - uses: actions/checkout@v3 + - name: CI Unittests + working-directory: ${{ github.workspace }} + run: scons build/ALL/unittests.opt -j $(nproc) + - run: echo "This job's status is ${{ job.status }}." - testlib-quick-matrix: - runs-on: [self-hosted, linux, x64] - if: github.event.pull_request.draft == false + testlib-quick-matrix: + runs-on: [self-hosted, linux, x64] + if: github.event.pull_request.draft == false # In order to make sure the environment is exactly the same, we run in # the same container we use to build gem5 and run the testlib tests. This - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id] - steps: - - uses: actions/checkout@v3 + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id] + steps: + - uses: actions/checkout@v3 # Unfortunately the 'ubunutu-latest' image doesn't have jq installed. # We therefore need to install it as a step here. - - name: Install jq - run: apt install -y jq + - name: Install jq + run: apt install -y jq - - name: Get directories for testlib-quick - working-directory: "${{ github.workspace }}/tests" - id: dir-matrix - run: echo "test-dirs-matrix=$(find gem5/* -type d -maxdepth 0 | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT + - name: Get directories for testlib-quick + working-directory: ${{ github.workspace }}/tests + id: dir-matrix + run: echo "test-dirs-matrix=$(find gem5/* -type d -maxdepth 0 | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT - - name: Get the build targets for testlib-quick-gem5-builds - working-directory: "${{ github.workspace }}/tests" - id: build-matrix - run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT + - name: Get the build targets for testlib-quick-gem5-builds + working-directory: ${{ github.workspace }}/tests + id: build-matrix + run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT - outputs: - build-matrix: ${{ steps.build-matrix.outputs.build-matrix }} - test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }} + outputs: + build-matrix: ${{ steps.build-matrix.outputs.build-matrix }} + test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }} - testlib-quick-gem5-builds: - runs-on: [self-hosted, linux, x64] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id, testlib-quick-matrix] - strategy: - matrix: - build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }} - steps: - - uses: actions/checkout@v3 - - name: Build gem5 - run: scons ${{ matrix.build-target }} -j $(nproc) + testlib-quick-gem5-builds: + runs-on: [self-hosted, linux, x64] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id, testlib-quick-matrix] + strategy: + matrix: + build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }} + steps: + - uses: actions/checkout@v3 + - name: Build gem5 + run: scons ${{ matrix.build-target }} -j $(nproc) # Upload the gem5 binary as an artifact. # Note: the "achor.txt" file is a hack to make sure the paths are @@ -109,72 +110,70 @@ jobs: # Then upload-artifact will upload "ARM/gem5.opt" and "RISCV/gem5.opt", # stripping the "build" directory. By adding the "anchor.txt" file, we # ensure the "build" directory is preserved. - - run: echo "anchor" > anchor.txt - - uses: actions/upload-artifact@v3 - with: - name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds - path: | - build/*/gem5.* - anchor.txt - retention-days: 7 + - run: echo "anchor" > anchor.txt + - uses: actions/upload-artifact@v3 + with: + name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds + path: | + build/*/gem5.* + anchor.txt + retention-days: 7 - testlib-quick-execution: - runs-on: [self-hosted, linux, x64] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds] - timeout-minutes: 360 # 6 hours - strategy: - fail-fast: false - matrix: - test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }} - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true + testlib-quick-execution: + runs-on: [self-hosted, linux, x64] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds] + timeout-minutes: 360 # 6 hours + strategy: + fail-fast: false + matrix: + test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }} + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true # Checkout the repository then download the gem5.opt artifact. - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 - with: - name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds + - uses: actions/checkout@v3 + - uses: actions/download-artifact@v3 + with: + name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds # Check that the gem5.opt artifact exists and is executable. - - name: Chmod gem5.{opt,debug,fast} to be executable - run: | - find . -name "gem5.opt" -exec chmod u+x {} \; - find . -name "gem5.debug" -exec chmod u+x {} \; - find . -name "gem5.fast" -exec chmod u+x {} \; + - name: Chmod gem5.{opt,debug,fast} to be executable + run: | + find . -name "gem5.opt" -exec chmod u+x {} \; + find . -name "gem5.debug" -exec chmod u+x {} \; + find . -name "gem5.fast" -exec chmod u+x {} \; # Run the testlib quick tests in the given directory. - - name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests - id: run-tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run --skip-build -t $(nproc) -vv ${{ matrix.test-dir }} + - name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests + id: run-tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run --skip-build -vv -j$(nproc) ${{ matrix.test-dir }} # Get the basename of the matrix.test-dir path (to name the artifact). - - name: Sanatize test-dir for artifact name - id: sanitize-test-dir - if: success() || failure() - run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT + - name: Sanatize test-dir for artifact name + id: sanitize-test-dir + if: success() || failure() + run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT # Upload the tests/testing-results directory as an artifact. - - name: Upload test results - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: ci-tests-run-${{ github.run_number }}-attempt-${{ github.run_attempt }}-testlib-quick-${{ steps.sanitize-test-dir.outputs.sanatized-test-dir }}-status-${{ steps.run-tests.outcome }}-output - path: tests/testing-results - retention-days: 30 + - name: Upload test results + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: ci-tests-run-${{ github.run_number }}-attempt-${{ github.run_attempt }}-testlib-quick-${{ steps.sanitize-test-dir.outputs.sanatized-test-dir + }}-status-${{ steps.run-tests.outcome }}-output + path: tests/testing-results + retention-days: 30 - testlib-quick: + testlib-quick: # It is 'testlib-quick' which needs to pass for the pull request to be # merged. The 'testlib-quick-execution' is a matrix job which runs all the # the testlib quick tests. This job is therefore a stub which will pass if # all the testlib-quick-execution jobs pass. - runs-on: [self-hosted, linux, x64] - needs: testlib-quick-execution - steps: - - run: echo "This job's status is ${{ job.status }}." + runs-on: [self-hosted, linux, x64] + needs: testlib-quick-execution + steps: + - run: echo "This job's status is ${{ job.status }}." diff --git a/.github/workflows/compiler-tests.yaml b/.github/workflows/compiler-tests.yaml index 5bd6a8d165..6e25720f2e 100644 --- a/.github/workflows/compiler-tests.yaml +++ b/.github/workflows/compiler-tests.yaml @@ -1,52 +1,57 @@ +--- # This workflow runs all of the compiler tests name: Compiler Tests on: # Runs every Friday from 7AM UTC - schedule: - - cron: '00 7 * * 5' + schedule: + - cron: 00 7 * * 5 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: # replication of compiler-tests.sh - all-compilers: - strategy: - fail-fast: false - matrix: - image: [gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-9, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, clang-version-13, clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies] - opts: [.opt, .fast] - runs-on: [self-hosted, linux, x64] - timeout-minutes: 2880 # 48 hours - container: gcr.io/gem5-test/${{ matrix.image }}:latest - steps: - - uses: actions/checkout@v3 - with: + all-compilers: + strategy: + fail-fast: false + matrix: + image: [gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-9, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, + clang-version-13, clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, + ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies] + opts: [.opt, .fast] + runs-on: [self-hosted, linux, x64] + timeout-minutes: 2880 # 48 hours + container: gcr.io/gem5-test/${{ matrix.image }}:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/ALL/gem5${{ matrix.opts }} with ${{ matrix.image }} - run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/ALL/gem5${{ matrix.opts }} -j$(nproc) - timeout-minutes: 600 # 10 hours + ref: develop + - name: Compile build/ALL/gem5${{ matrix.opts }} with ${{ matrix.image }} + run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/ALL/gem5${{ matrix.opts }} -j$(nproc) + timeout-minutes: 600 # 10 hours # Tests the two latest gcc and clang supported compilers against all gem5 compilations. - latest-compilers-all-gem5-builds: - strategy: - fail-fast: false - matrix: - gem5-compilation: [ARM, ARM_MESI_Three_Level, ARM_MESI_Three_Level_HTM, ARM_MOESI_hammer, Garnet_standalone, GCN3_X86, MIPS, 'NULL', NULL_MESI_Two_Level, NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86, GCN3_X86] - image: [gcc-version-12, clang-version-16] - opts: [.opt] - runs-on: [self-hosted, linux, x64] - timeout-minutes: 2880 # 48 hours - container: gcr.io/gem5-test/${{ matrix.image }}:latest - steps: - - uses: actions/checkout@v3 - with: + latest-compilers-all-gem5-builds: + strategy: + fail-fast: false + matrix: + gem5-compilation: [ARM, ARM_MESI_Three_Level, ARM_MESI_Three_Level_HTM, ARM_MOESI_hammer, Garnet_standalone, GCN3_X86, MIPS, 'NULL', NULL_MESI_Two_Level, + NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86, + GCN3_X86] + image: [gcc-version-12, clang-version-16] + opts: [.opt] + runs-on: [self-hosted, linux, x64] + timeout-minutes: 2880 # 48 hours + container: gcr.io/gem5-test/${{ matrix.image }}:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} with ${{ matrix.image }} - run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} -j$(nproc) - timeout-minutes: 600 # 10 hours + ref: develop + - name: Compile build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} with ${{ matrix.image }} + run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} -j$(nproc) + timeout-minutes: 600 # 10 hours diff --git a/.github/workflows/daily-tests.yaml b/.github/workflows/daily-tests.yaml index 86dba0c139..351c0301be 100644 --- a/.github/workflows/daily-tests.yaml +++ b/.github/workflows/daily-tests.yaml @@ -1,286 +1,286 @@ +--- # This workflow runs all of the long tests within main.py, extra tests in nightly.sh, and unittests name: Daily Tests on: # Runs every day from 7AM UTC - schedule: - - cron: '0 7 * * *' + schedule: + - cron: 0 7 * * * jobs: - name-artifacts: - runs-on: ubuntu-latest - outputs: - build-name: ${{ steps.artifact-name.outputs.name }} - steps: - - uses: actions/checkout@v2 - - id: artifact-name - run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT + name-artifacts: + runs-on: ubuntu-latest + outputs: + build-name: ${{ steps.artifact-name.outputs.name }} + steps: + - uses: actions/checkout@v2 + - id: artifact-name + run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT - build-gem5: - strategy: - fail-fast: false - matrix: + build-gem5: + strategy: + fail-fast: false + matrix: # NULL is in quotes since it is considered a keyword in yaml files - image: [ALL, ALL_CHI, ARM, ALL_MSI, ALL_MESI_Two_Level, "NULL", NULL_MI_example, RISCV, VEGA_X86] + image: [ALL, ALL_CHI, ARM, ALL_MSI, ALL_MESI_Two_Level, 'NULL', NULL_MI_example, RISCV, VEGA_X86] # this allows us to pass additional command line parameters # the default is to add -j $(nproc), but some images # require more specifications when built - include: - - command-line: -j $(nproc) - - image: ALL_CHI - command-line: --default=ALL PROTOCOL=CHI -j $(nproc) - - image: ALL_MSI - command-line: --default=ALL PROTOCOL=MSI -j $(nproc) - - image: ALL_MESI_Two_Level - command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc) - - image: NULL_MI_example - command-line: --default=NULL PROTOCOL=MI_example -j $(nproc) - runs-on: [self-hosted, linux, x64] - needs: name-artifacts - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - steps: - - uses: actions/checkout@v3 - with: + include: + - command-line: -j $(nproc) + - image: ALL_CHI + command-line: --default=ALL PROTOCOL=CHI -j $(nproc) + - image: ALL_MSI + command-line: --default=ALL PROTOCOL=MSI -j $(nproc) + - image: ALL_MESI_Two_Level + command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc) + - image: NULL_MI_example + command-line: --default=NULL PROTOCOL=MI_example -j $(nproc) + runs-on: [self-hosted, linux, x64] + needs: name-artifacts + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build gem5 - run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }} - - uses: actions/upload-artifact@v3 - with: - name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }} - path: build/${{ matrix.image }}/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - name: Build gem5 + run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }} + - uses: actions/upload-artifact@v3 + with: + name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }} + path: build/${{ matrix.image }}/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." # this builds both unittests.fast and unittests.debug - unittests-fast-debug: - strategy: - matrix: - type: [fast, debug] - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v3 - with: + unittests-fast-debug: + strategy: + matrix: + type: [fast, debug] + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: ALL/unittests.${{ matrix.type }} UnitTests - run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc) + ref: develop + - name: ALL/unittests.${{ matrix.type }} UnitTests + run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc) # start running all of the long tests - testlib-long-tests: - strategy: - fail-fast: false - matrix: - test-type: [arm_boot_tests, fs, gpu, insttest_se, learning_gem5, m5threads_test_atomic, memory, multi_isa, replacement_policies, riscv_boot_tests, stdlib, x86_boot_tests] - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [name-artifacts, build-gem5] - timeout-minutes: 1440 # 24 hours for entire matrix to run - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-long-tests: + strategy: + fail-fast: false + matrix: + test-type: [arm_boot_tests, fs, gpu, insttest_se, learning_gem5, m5threads_test_atomic, memory, multi_isa, replacement_policies, riscv_boot_tests, + stdlib, x86_boot_tests] + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [name-artifacts, build-gem5] + timeout-minutes: 1440 # 24 hours for entire matrix to run + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop + ref: develop # download all artifacts for each test # since long tests can't start until the build matrix completes, # we download all artifacts from the build for each test # in this matrix - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI - path: build/ALL_CHI - - run: chmod u+x build/ALL_CHI/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ARM - path: build/ARM - - run: chmod u+x build/ARM/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI - path: build/ALL_MSI - - run: chmod u+x build/ALL_MSI/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level - path: build/ALL_MESI_Two_Level - - run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}NULL - path: build/NULL - - run: chmod u+x build/NULL/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example - path: build/NULL_MI_example - - run: chmod u+x build/NULL_MI_example/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}RISCV - path: build/RISCV - - run: chmod u+x build/RISCV/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86 - path: build/VEGA_X86 - - run: chmod u+x build/VEGA_X86/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI + path: build/ALL_CHI + - run: chmod u+x build/ALL_CHI/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ARM + path: build/ARM + - run: chmod u+x build/ARM/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI + path: build/ALL_MSI + - run: chmod u+x build/ALL_MSI/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level + path: build/ALL_MESI_Two_Level + - run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}NULL + path: build/NULL + - run: chmod u+x build/NULL/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example + path: build/NULL_MI_example + - run: chmod u+x build/NULL_MI_example/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}RISCV + path: build/RISCV + - run: chmod u+x build/RISCV/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86 + path: build/VEGA_X86 + - run: chmod u+x build/VEGA_X86/gem5.opt # run test - - name: long ${{ matrix.test-type }} tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc) - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + - name: long ${{ matrix.test-type }} tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc) + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." # split library example tests into runs based on Suite UID # so that they don't hog the runners for too long - testlib-long-gem5_library_example_tests: - runs-on: [self-hosted, linux, x64] - strategy: - fail-fast: false - matrix: - test-type: [gem5-library-example-x86-ubuntu-run-ALL-x86_64-opt, gem5-library-example-riscv-ubuntu-run-ALL-x86_64-opt, lupv-example-ALL-x86_64-opt, gem5-library-example-arm-ubuntu-run-test-ALL-x86_64-opt, gem5-library-example-riscvmatched-hello-ALL-x86_64-opt] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [name-artifacts, build-gem5] - timeout-minutes: 1440 # 24 hours - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-long-gem5_library_example_tests: + runs-on: [self-hosted, linux, x64] + strategy: + fail-fast: false + matrix: + test-type: [gem5-library-example-x86-ubuntu-run-ALL-x86_64-opt, gem5-library-example-riscv-ubuntu-run-ALL-x86_64-opt, lupv-example-ALL-x86_64-opt, + gem5-library-example-arm-ubuntu-run-test-ALL-x86_64-opt, gem5-library-example-riscvmatched-hello-ALL-x86_64-opt] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [name-artifacts, build-gem5] + timeout-minutes: 1440 # 24 hours + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - name: long ${{ matrix.test-type }} gem5_library_example_tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run --uid SuiteUID:tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py:test-${{ matrix.test-type }} --length=long --skip-build -vv - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - name: long ${{ matrix.test-type }} gem5_library_example_tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run --uid SuiteUID:tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py:test-${{ matrix.test-type }} --length=long + --skip-build -vv + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." # This runs the SST-gem5 integration compilation and tests it with # ext/sst/sst/example.py. - sst-test: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/sst-env:latest - timeout-minutes: 180 + sst-test: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/sst-env:latest + timeout-minutes: 180 - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build RISCV/libgem5_opt.so with SST - run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc) - - name: Compile ext/sst - working-directory: ${{ github.workspace }}/ext/sst - run: make -j $(nproc) - - name: Run SST test - working-directory: ${{ github.workspace }}/ext/sst - run: sst --add-lib-path=./ sst/example.py + ref: develop + - name: Build RISCV/libgem5_opt.so with SST + run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc) + - name: Compile ext/sst + working-directory: ${{ github.workspace }}/ext/sst + run: make -j $(nproc) + - name: Run SST test + working-directory: ${{ github.workspace }}/ext/sst + run: sst --add-lib-path=./ sst/example.py # This runs the gem5 within SystemC ingration and runs a simple hello-world # simulation with it. - systemc-test: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/systemc-env:latest - timeout-minutes: 180 + systemc-test: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/systemc-env:latest + timeout-minutes: 180 - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build ARM/gem5.opt - run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc) - - name: Build ARM/libgem5_opt.so - run: scons build/ARM/libgem5_opt.so --with-cxx-config --without-python --without-tcmalloc USE_SYSTEMC=0 -j$(nproc) --duplicate-sources - - name: Compile gem5 withing SystemC - working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc - run: make - - name: Run gem5 within SystemC test - run: ./build/ARM/gem5.opt configs/deprecated/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello - - name: Continue gem5 within SystemC test - run: LD_LIBRARY_PATH=build/ARM/:/opt/systemc/lib-linux64/ ./util/systemc/gem5_within_systemc/gem5.opt.sc m5out/config.ini + ref: develop + - name: Build ARM/gem5.opt + run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc) + - name: Build ARM/libgem5_opt.so + run: scons build/ARM/libgem5_opt.so --with-cxx-config --without-python --without-tcmalloc USE_SYSTEMC=0 -j$(nproc) --duplicate-sources + - name: Compile gem5 withing SystemC + working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc + run: make + - name: Run gem5 within SystemC test + run: ./build/ARM/gem5.opt configs/deprecated/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello + - name: Continue gem5 within SystemC test + run: LD_LIBRARY_PATH=build/ARM/:/opt/systemc/lib-linux64/ ./util/systemc/gem5_within_systemc/gem5.opt.sc m5out/config.ini # Runs the gem5 Nighyly GPU tests. - gpu-tests: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/gcn-gpu:latest - timeout-minutes: 720 # 12 hours + gpu-tests: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/gcn-gpu:latest + timeout-minutes: 720 # 12 hours - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/GCN3_X86/gem5.opt - run: scons build/GCN3_X86/gem5.opt -j $(nproc) - - name: Get Square test-prog from gem5-resources - uses: wei/wget@v1 - with: - args: -q http://dist.gem5.org/dist/develop/test-progs/square/square # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time: https://github.com/coder/sshcode/issues/102 - - name: Run Square test with GCN3_X86/gem5.opt (SE mode) - run: | - mkdir -p tests/testing-results - ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square - - name: Get allSyncPrims-1kernel from gem5-resources - uses: wei/wget@v1 - with: - args: -q http://dist.gem5.org/dist/develop/test-progs/heterosync/gcn3/allSyncPrims-1kernel # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time - - name: Run allSyncPrims-1kernel sleepMutex test with GCN3_X86/gem5.opt (SE mode) - run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="sleepMutex 10 16 4" - - name: Run allSyncPrims-1kernel lfTreeBarrUsing test with GCN3_X86/gem5.opt (SE mode) - run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="lfTreeBarrUniq 10 16 4" + ref: develop + - name: Compile build/GCN3_X86/gem5.opt + run: scons build/GCN3_X86/gem5.opt -j $(nproc) + - name: Get Square test-prog from gem5-resources + uses: wei/wget@v1 + with: + args: -q http://dist.gem5.org/dist/develop/test-progs/square/square # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time: https://github.com/coder/sshcode/issues/102 + - name: Run Square test with GCN3_X86/gem5.opt (SE mode) + run: | + mkdir -p tests/testing-results + ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square + - name: Get allSyncPrims-1kernel from gem5-resources + uses: wei/wget@v1 + with: + args: -q http://dist.gem5.org/dist/develop/test-progs/heterosync/gcn3/allSyncPrims-1kernel # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time + - name: Run allSyncPrims-1kernel sleepMutex test with GCN3_X86/gem5.opt (SE mode) + run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="sleepMutex 10 16 + 4" + - name: Run allSyncPrims-1kernel lfTreeBarrUsing test with GCN3_X86/gem5.opt (SE mode) + run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="lfTreeBarrUniq + 10 16 4" diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index c0dc7bcb36..68b0905e83 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -1,53 +1,54 @@ +--- name: Docker images build and push on: - workflow_dispatch: + workflow_dispatch: jobs: - obtain-dockerfiles: - runs-on: [self-hosted, linux, x64] - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + obtain-dockerfiles: + runs-on: [self-hosted, linux, x64] + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/upload-artifact@v3 - with: - name: dockerfiles - path: util/dockerfiles + ref: develop + - uses: actions/upload-artifact@v3 + with: + name: dockerfiles + path: util/dockerfiles # This builds and pushes the docker image. - build-and-push: - runs-on: [self-hosted, linux, x64] - needs: obtain-dockerfiles - permissions: - packages: write - contents: read + build-and-push: + runs-on: [self-hosted, linux, x64] + needs: obtain-dockerfiles + permissions: + packages: write + contents: read - steps: - - uses: actions/download-artifact@v3 - with: - name: dockerfiles - path: dockerfiles-docker-build + steps: + - uses: actions/download-artifact@v3 + with: + name: dockerfiles + path: dockerfiles-docker-build - - uses: docker/setup-qemu-action@v2 - name: Setup QEMU + - uses: docker/setup-qemu-action@v2 + name: Setup QEMU - - uses: docker/setup-buildx-action@v2 - name: Set up Docker Buildx + - uses: docker/setup-buildx-action@v2 + name: Set up Docker Buildx - - uses: docker/login-action@v2 - name: Login to the GitHub Container Registry - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/login-action@v2 + name: Login to the GitHub Container Registry + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push with bake - uses: docker/bake-action@v4 - with: - workdir: ./dockerfiles-docker-build - files: docker-bake.hcl - push: true + - name: Build and push with bake + uses: docker/bake-action@v4 + with: + workdir: ./dockerfiles-docker-build + files: docker-bake.hcl + push: true diff --git a/.github/workflows/gpu-tests.yaml b/.github/workflows/gpu-tests.yaml index 98f2529b92..43eff95529 100644 --- a/.github/workflows/gpu-tests.yaml +++ b/.github/workflows/gpu-tests.yaml @@ -1,60 +1,61 @@ +--- # This workflow runs all of the very-long tests within main.py name: Weekly Tests on: # Runs every Sunday from 7AM UTC - schedule: - - cron: '00 7 * * 6' + schedule: + - cron: 00 7 * * 6 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: - build-gem5: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/gcn-gpu:latest - steps: - - uses: actions/checkout@v3 - with: + build-gem5: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/gcn-gpu:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build gem5 - run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style - - uses: actions/upload-artifact@v3 - with: - name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 - path: build/GCN3_X86/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - name: Build gem5 + run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style + - uses: actions/upload-artifact@v3 + with: + name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 + path: build/GCN3_X86/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." - HACC-tests: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/gcn-gpu:latest - needs: build-gem5 - timeout-minutes: 120 # 2 hours - steps: - - uses: actions/checkout@v3 - with: + HACC-tests: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/gcn-gpu:latest + needs: build-gem5 + timeout-minutes: 120 # 2 hours + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 - path: build/GCN3_X86 - - run: chmod u+x build/GCN3_X86/gem5.opt - - name: make hip directory - run: mkdir hip - - name: Compile m5ops and x86 - working-directory: ${{ github.workspace }}/util/m5 - run: | - export TERM=xterm-256color - scons build/x86/out/m5 - - name: Download tests - working-directory: ${{ github.workspace }}/hip - run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest - - name: Run HACC tests - working-directory: ${{ github.workspace }} - run: | - build/GCN3_X86/gem5.opt configs/example/apu_se.py -n3 --reg-alloc-policy=dynamic --benchmark-root=hip -c ForceTreeTest --options="0.5 0.1 64 0.1 1 N 12 rcb" + ref: develop + - uses: actions/download-artifact@v3 + with: + name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 + path: build/GCN3_X86 + - run: chmod u+x build/GCN3_X86/gem5.opt + - name: make hip directory + run: mkdir hip + - name: Compile m5ops and x86 + working-directory: ${{ github.workspace }}/util/m5 + run: | + export TERM=xterm-256color + scons build/x86/out/m5 + - name: Download tests + working-directory: ${{ github.workspace }}/hip + run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest + - name: Run HACC tests + working-directory: ${{ github.workspace }} + run: | + build/GCN3_X86/gem5.opt configs/example/apu_se.py -n3 --reg-alloc-policy=dynamic --benchmark-root=hip -c ForceTreeTest --options="0.5 0.1 64 0.1 1 N 12 rcb" diff --git a/.github/workflows/utils.yaml b/.github/workflows/utils.yaml index 91d0bf1722..ccbd87c82f 100644 --- a/.github/workflows/utils.yaml +++ b/.github/workflows/utils.yaml @@ -1,19 +1,21 @@ +--- # This workflow file contains miscellaneous tasks to manage the repository. name: Utils for Repository on: - schedule: - - cron: '30 1 * * *' - workflow_dispatch: + schedule: + - cron: 30 1 * * * + workflow_dispatch: jobs: # This job runs the stale action to close issues that have been inactive for 30 days. # It is scheduled to run every day at 1:30 AM UTC. - close-stale-issues: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v8.0.0 - with: - close-issue-message: 'This issue is being closed because it has been inactive waiting for response for 30 days. If this is still an issue, please open a new issue and reference this one.' - days-before-stale: 21 - days-before-close: 7 - any-of-labels: 'needs details' + close-stale-issues: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v8.0.0 + with: + close-issue-message: This issue is being closed because it has been inactive waiting for response for 30 days. If this is still an issue, + please open a new issue and reference this one. + days-before-stale: 21 + days-before-close: 7 + any-of-labels: needs details diff --git a/.github/workflows/weekly-tests.yaml b/.github/workflows/weekly-tests.yaml index 875bff12f7..d322833153 100644 --- a/.github/workflows/weekly-tests.yaml +++ b/.github/workflows/weekly-tests.yaml @@ -1,110 +1,108 @@ +--- # This workflow runs all of the very-long tests within main.py name: Weekly Tests on: # Runs every Sunday from 7AM UTC - schedule: - - cron: '00 7 * * 6' + schedule: + - cron: 00 7 * * 6 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: - build-gem5: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - outputs: - build-name: ${{ steps.artifact-name.outputs.name }} - steps: - - uses: actions/checkout@v3 - with: + build-gem5: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + outputs: + build-name: ${{ steps.artifact-name.outputs.name }} + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - id: artifact-name - run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT - - name: Build gem5 - run: | - scons build/ALL/gem5.opt -j $(nproc) - - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.artifact-name.outputs.name }} - path: build/ALL/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - id: artifact-name + run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT + - name: Build gem5 + run: | + scons build/ALL/gem5.opt -j $(nproc) + - uses: actions/upload-artifact@v3 + with: + name: ${{ steps.artifact-name.outputs.name }} + path: build/ALL/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." # start running the very-long tests - testlib-very-long-tests: - strategy: - fail-fast: false - matrix: - test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests] - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [build-gem5] - timeout-minutes: 4320 # 3 days - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-very-long-tests: + strategy: + fail-fast: false + matrix: + test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests] + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [build-gem5] + timeout-minutes: 4320 # 3 days + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: ${{needs.build-gem5.outputs.build-name}} - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - name: very-long ${{ matrix.test-type }} - working-directory: ${{ github.workspace }}/tests - run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc) - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - uses: actions/download-artifact@v3 + with: + name: ${{needs.build-gem5.outputs.build-name}} + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - name: very-long ${{ matrix.test-type }} + working-directory: ${{ github.workspace }}/tests + run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc) + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." - dramsys-tests: - runs-on: [self-hosted, linux, x64] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - timeout-minutes: 4320 # 3 days - steps: - - uses: actions/checkout@v3 - with: + dramsys-tests: + runs-on: [self-hosted, linux, x64] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + timeout-minutes: 4320 # 3 days + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop + ref: develop - - name: Checkout DRAMSys - working-directory: ${{ github.workspace }}/ext/dramsys - run: | - git clone https://github.com/tukl-msd/DRAMSys DRAMSys - cd DRAMSys - git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f - git submodule update --init --recursive + - name: Checkout DRAMSys + working-directory: ${{ github.workspace }}/ext/dramsys + run: | + git clone https://github.com/tukl-msd/DRAMSys DRAMSys + cd DRAMSys + git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f + git submodule update --init --recursive # gem5 is built separately because it depends on the DRAMSys library - - name: Build gem5 - working-directory: ${{ github.workspace }} - run: scons build/ALL/gem5.opt -j $(nproc) + - name: Build gem5 + working-directory: ${{ github.workspace }} + run: scons build/ALL/gem5.opt -j $(nproc) - - name: Run DRAMSys Checks - working-directory: ${{ github.workspace }} - run: | - ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/arm-hello-dramsys.py - ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/dramsys-traffic.py - ./build/ALL/gem5.opt configs/example/dramsys.py + - name: Run DRAMSys Checks + working-directory: ${{ github.workspace }} + run: | + ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/arm-hello-dramsys.py + ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/dramsys-traffic.py + ./build/ALL/gem5.opt configs/example/dramsys.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 37b1acbbea..367a7c09d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,4 @@ +--- # Copyright (c) 2022 Arm Limited # All rights reserved. # @@ -33,57 +34,61 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -minimum_pre_commit_version: "2.18" +minimum_pre_commit_version: '2.18' default_language_version: - python: python3 + python: python3 exclude: | - (?x)^( - ext/(?!testlib/).*| - build/.*| - src/systemc/ext/.*| - src/systemc/tests/.*/.*| - src/python/m5/ext/pyfdt/.*| - tests/.*/ref/.* - )$ + (?x)^( + ext/(?!testlib/).*| + build/.*| + src/systemc/ext/.*| + src/systemc/tests/.*/.*| + src/python/m5/ext/pyfdt/.*| + tests/.*/ref/.* + )$ default_stages: [commit] repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-json - - id: check-yaml - - id: check-added-large-files - - id: mixed-line-ending - args: [--fix=lf] - - id: check-case-conflict -- repo: https://github.com/psf/black - rev: 22.6.0 - hooks: - - id: black -- repo: local - hooks: - - id: gem5-style-checker - name: gem5 style checker - entry: util/git-pre-commit.py - always_run: true - exclude: ".*" - language: system - description: 'The gem5 style checker hook.' - - id: gem5-commit-msg-checker - name: gem5 commit msg checker - entry: ext/git-commit-msg - language: system - stages: [commit-msg] - description: 'The gem5 commit message checker hook.' - - id: gerrit-commit-msg-job - name: gerrit commit message job - entry: util/gerrit-commit-msg-hook - language: system - stages: [commit-msg] - description: 'Adds Change-ID to the commit message. Needed by Gerrit.' + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-json + - id: check-yaml + - id: check-added-large-files + - id: mixed-line-ending + args: [--fix=lf] + - id: check-case-conflict + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt + rev: 0.2.3 + hooks: + - id: yamlfmt + - repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black + - repo: local + hooks: + - id: gem5-style-checker + name: gem5 style checker + entry: util/git-pre-commit.py + always_run: true + exclude: .* + language: system + description: The gem5 style checker hook. + - id: gem5-commit-msg-checker + name: gem5 commit msg checker + entry: ext/git-commit-msg + language: system + stages: [commit-msg] + description: The gem5 commit message checker hook. + - id: gerrit-commit-msg-job + name: gerrit commit message job + entry: util/gerrit-commit-msg-hook + language: system + stages: [commit-msg] + description: Adds Change-ID to the commit message. Needed by Gerrit. diff --git a/MAINTAINERS.yaml b/MAINTAINERS.yaml index 02a8b3eb7b..6636f11e26 100644 --- a/MAINTAINERS.yaml +++ b/MAINTAINERS.yaml @@ -1,3 +1,4 @@ +--- # See CONTRIBUTING.md for details of gem5's contribution process. # # This file contains a list of gem5's subsystems and their @@ -40,246 +41,246 @@ # targeting that subsystem. arch: - desc: >- - General architecture-specific components - status: orphaned + desc: >- + General architecture-specific components + status: orphaned arch-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg arch-gcn3: - status: maintained - maintainers: - - Matt Sinclair - - Matt Porema + status: maintained + maintainers: + - Matt Sinclair + - Matt Porema arch-vega: - status: maintained - maintainers: - - Matt Sinclair - - Matt Porema + status: maintained + maintainers: + - Matt Sinclair + - Matt Porema arch-mips: - status: orphaned + status: orphaned arch-power: - status: orphaned + status: orphaned arch-riscv: - status: orphaned + status: orphaned arch-sparc: - status: orphaned + status: orphaned arch-x86: - status: orphaned + status: orphaned base: - status: orphaned + status: orphaned base-stats: - status: orphaned + status: orphaned configs: - status: orphaned - experts: - - Jason Lowe-Power + status: orphaned + experts: + - Jason Lowe-Power cpu: - desc: >- - General changes to all CPU models (e.g., BaseCPU) - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + General changes to all CPU models (e.g., BaseCPU) + status: orphaned + experts: + - Jason Lowe-Power cpu-kvm: - status: maintained - maintainers: - - Andreas Sandberg + status: maintained + maintainers: + - Andreas Sandberg cpu-minor: - status: orphaned + status: orphaned cpu-o3: - status: orphaned + status: orphaned cpu-simple: - status: orphaned - experts: - - Jason Lowe-Power + status: orphaned + experts: + - Jason Lowe-Power dev: - status: orphaned + status: orphaned dev-hsa: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba dev-amdgpu: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba dev-virtio: - status: maintained - maintainers: - - Andreas Sandberg + status: maintained + maintainers: + - Andreas Sandberg dev-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg doc: - status: orphaned + status: orphaned ext: - desc: >- - Components external to gem5 - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + Components external to gem5 + status: orphaned + experts: + - Jason Lowe-Power ext-testlib: - status: orphaned - experts: - - Bobby R. Bruce + status: orphaned + experts: + - Bobby R. Bruce fastmodel: - desc: >- - Changes relating to ARM Fast Models - status: orphaned + desc: >- + Changes relating to ARM Fast Models + status: orphaned gpu-compute: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba learning-gem5: - desc: >- - The code and configs for the Learning gem5 book - status: orphaned - experts: - - Jason Lowe-Power - - Bobby R. Bruce + desc: >- + The code and configs for the Learning gem5 book + status: orphaned + experts: + - Jason Lowe-Power + - Bobby R. Bruce stdlib: - desc: >- - The gem5 standard library found under `src/python/gem5` - status: maintained - maintainers: - - Bobby R. Bruce + desc: >- + The gem5 standard library found under `src/python/gem5` + status: maintained + maintainers: + - Bobby R. Bruce mem: - desc: >- - General memory system (e.g., XBar, Packet) - status: orphaned + desc: >- + General memory system (e.g., XBar, Packet) + status: orphaned mem-cache: - desc: >- - Classic caches and coherence - status: orphaned + desc: >- + Classic caches and coherence + status: orphaned mem-dram: - status: orphaned + status: orphaned mem-garnet: - desc: >- - Garnet subcomponent of Ruby - status: orphaned + desc: >- + Garnet subcomponent of Ruby + status: orphaned mem-ruby: - desc: >- - Ruby structures and protocols - status: maintained - maintainers: - - Matt Sinclair - experts: - - Jason Lowe-Power + desc: >- + Ruby structures and protocols + status: maintained + maintainers: + - Matt Sinclair + experts: + - Jason Lowe-Power misc: - desc: >- - Anything outside of the other categories - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + Anything outside of the other categories + status: orphaned + experts: + - Jason Lowe-Power python: - desc: >- - Python SimObject wrapping and infrastructure - status: orphaned - experts: - - Jason Lowe-Power - - Andreas Sandberg + desc: >- + Python SimObject wrapping and infrastructure + status: orphaned + experts: + - Jason Lowe-Power + - Andreas Sandberg resources: - desc: >- - The gem5-resources repo with auxiliary resources for simulation - status: maintained - maintainers: - - Bobby R. Bruce - experts: - - Jason Lowe-Power + desc: >- + The gem5-resources repo with auxiliary resources for simulation + status: maintained + maintainers: + - Bobby R. Bruce + experts: + - Jason Lowe-Power scons: - desc: >- - Build system - status: orphaned + desc: >- + Build system + status: orphaned sim: - desc: >- - General simulation components - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + General simulation components + status: orphaned + experts: + - Jason Lowe-Power sim-se: - desc: >- - Syscall emulation - status: orphaned + desc: >- + Syscall emulation + status: orphaned system-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg systemc: - desc: >- - Code for the gem5 SystemC implementation and interface - status: orphaned + desc: >- + Code for the gem5 SystemC implementation and interface + status: orphaned tests: - desc: >- - testing changes - status: maintained - maintainers: - - Bobby R. Bruce + desc: >- + testing changes + status: maintained + maintainers: + - Bobby R. Bruce util: - status: orphaned + status: orphaned util-docker: - status: maintained - maintainers: - - Bobby R. Bruce + status: maintained + maintainers: + - Bobby R. Bruce util-m5: - status: orphaned + status: orphaned util-gem5art: - status: orphaned + status: orphaned website: - desc: >- - The gem5-website repo which contains the gem5.org site - status: maintained - maintainers: - - Bobby R. Bruce - experts: - - Jason Lowe-Power + desc: >- + The gem5-website repo which contains the gem5.org site + status: maintained + maintainers: + - Bobby R. Bruce + experts: + - Jason Lowe-Power diff --git a/configs/common/cores/arm/HPI.py b/configs/common/cores/arm/HPI.py index d3d46054f1..cebd91cc72 100644 --- a/configs/common/cores/arm/HPI.py +++ b/configs/common/cores/arm/HPI.py @@ -1679,7 +1679,13 @@ class HPI_MMU(ArmMMU): dtb = ArmTLB(entry_type="data", size=256) +class HPI_BTB(SimpleBTB): + numEntries = 128 + tagBits = 18 + + class HPI_BP(TournamentBP): + btb = HPI_BTB() localPredictorSize = 64 localCtrBits = 2 localHistoryTableSize = 64 @@ -1687,8 +1693,6 @@ class HPI_BP(TournamentBP): globalCtrBits = 2 choicePredictorSize = 1024 choiceCtrBits = 2 - BTBEntries = 128 - BTBTagSize = 18 RASSize = 8 instShiftAmt = 2 diff --git a/configs/common/cores/arm/O3_ARM_Etrace.py b/configs/common/cores/arm/O3_ARM_Etrace.py new file mode 100644 index 0000000000..20870a0b7a --- /dev/null +++ b/configs/common/cores/arm/O3_ARM_Etrace.py @@ -0,0 +1,58 @@ +# Copyright (c) 2012, 2017-2018, 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.objects import * +from .O3_ARM_v7a import O3_ARM_v7a_3 + +# O3_ARM_v7a_3 adapted to generate elastic traces +class O3_ARM_v7a_3_Etrace(O3_ARM_v7a_3): + # Make the number of entries in the ROB, LQ and SQ very + # large so that there are no stalls due to resource + # limitation as such stalls will get captured in the trace + # as compute delay. For replay, ROB, LQ and SQ sizes are + # modelled in the Trace CPU. + numROBEntries = 512 + LQEntries = 128 + SQEntries = 128 + + def attach_probe_listener(self, inst_trace_file, data_trace_file): + # Attach the elastic trace probe listener. Set the protobuf trace + # file names. Set the dependency window size equal to the cpu it + # is attached to. + self.traceListener = m5.objects.ElasticTrace( + instFetchTraceFile=inst_trace_file, + dataDepTraceFile=data_trace_file, + depWindowSize=3 * self.numROBEntries, + ) diff --git a/configs/common/cores/arm/O3_ARM_v7a.py b/configs/common/cores/arm/O3_ARM_v7a.py index 6a1734235a..8c25b82496 100644 --- a/configs/common/cores/arm/O3_ARM_v7a.py +++ b/configs/common/cores/arm/O3_ARM_v7a.py @@ -107,14 +107,18 @@ class O3_ARM_v7a_FUP(FUPool): ] +class O3_ARM_v7a_BTB(SimpleBTB): + numEntries = 2048 + tagBits = 18 + + # Bi-Mode Branch Predictor class O3_ARM_v7a_BP(BiModeBP): + btb = O3_ARM_v7a_BTB() globalPredictorSize = 8192 globalCtrBits = 2 choicePredictorSize = 8192 choiceCtrBits = 2 - BTBEntries = 2048 - BTBTagSize = 18 RASSize = 16 instShiftAmt = 2 diff --git a/configs/common/cores/arm/ex5_big.py b/configs/common/cores/arm/ex5_big.py index 0d4d4903cf..3272ca4676 100644 --- a/configs/common/cores/arm/ex5_big.py +++ b/configs/common/cores/arm/ex5_big.py @@ -104,14 +104,18 @@ class ex5_big_FUP(FUPool): ] +class ex5_big_BTB(SimpleBTB): + numEntries = 4096 + tagBits = 18 + + # Bi-Mode Branch Predictor class ex5_big_BP(BiModeBP): + btb = ex5_big_BTB() globalPredictorSize = 4096 globalCtrBits = 2 choicePredictorSize = 1024 choiceCtrBits = 3 - BTBEntries = 4096 - BTBTagSize = 18 RASSize = 48 instShiftAmt = 2 diff --git a/configs/example/arm/devices.py b/configs/example/arm/devices.py index 6c6474ca2b..7ceb3cd3bf 100644 --- a/configs/example/arm/devices.py +++ b/configs/example/arm/devices.py @@ -338,56 +338,15 @@ class FastmodelCluster(CpuCluster): pass -class BaseSimpleSystem(ArmSystem): - cache_line_size = 64 - - def __init__(self, mem_size, platform, **kwargs): - super(BaseSimpleSystem, self).__init__(**kwargs) - - self.voltage_domain = VoltageDomain(voltage="1.0V") - self.clk_domain = SrcClockDomain( - clock="1GHz", voltage_domain=Parent.voltage_domain - ) - - if platform is None: - self.realview = VExpress_GEM5_V1() - else: - self.realview = platform - - if hasattr(self.realview.gic, "cpu_addr"): - self.gic_cpu_addr = self.realview.gic.cpu_addr - - self.terminal = Terminal() - self.vncserver = VncServer() - - self.iobus = IOXBar() - # Device DMA -> MEM - self.mem_ranges = self.getMemRanges(int(Addr(mem_size))) +class ClusterSystem: + """ + Base class providing cpu clusters generation/handling methods to + SE/FS systems + """ + def __init__(self, **kwargs): self._clusters = [] - def getMemRanges(self, mem_size): - """ - Define system memory ranges. This depends on the physical - memory map provided by the realview platform and by the memory - size provided by the user (mem_size argument). - The method is iterating over all platform ranges until they cover - the entire user's memory requirements. - """ - mem_ranges = [] - for mem_range in self.realview._mem_regions: - size_in_range = min(mem_size, mem_range.size()) - - mem_ranges.append( - AddrRange(start=mem_range.start, size=size_in_range) - ) - - mem_size -= size_in_range - if mem_size == 0: - return mem_ranges - - raise ValueError("memory size too big for platform capabilities") - def numCpuClusters(self): return len(self._clusters) @@ -423,6 +382,80 @@ class BaseSimpleSystem(ArmSystem): cluster.connectMemSide(cluster_mem_bus) +class SimpleSeSystem(System, ClusterSystem): + """ + Example system class for syscall emulation mode + """ + + # Use a fixed cache line size of 64 bytes + cache_line_size = 64 + + def __init__(self, **kwargs): + System.__init__(self, **kwargs) + ClusterSystem.__init__(self, **kwargs) + # Create a voltage and clock domain for system components + self.voltage_domain = VoltageDomain(voltage="3.3V") + self.clk_domain = SrcClockDomain( + clock="1GHz", voltage_domain=self.voltage_domain + ) + + # Create the off-chip memory bus. + self.membus = SystemXBar() + + def connect(self): + self.system_port = self.membus.cpu_side_ports + + +class BaseSimpleSystem(ArmSystem, ClusterSystem): + cache_line_size = 64 + + def __init__(self, mem_size, platform, **kwargs): + ArmSystem.__init__(self, **kwargs) + ClusterSystem.__init__(self, **kwargs) + + self.voltage_domain = VoltageDomain(voltage="1.0V") + self.clk_domain = SrcClockDomain( + clock="1GHz", voltage_domain=Parent.voltage_domain + ) + + if platform is None: + self.realview = VExpress_GEM5_V1() + else: + self.realview = platform + + if hasattr(self.realview.gic, "cpu_addr"): + self.gic_cpu_addr = self.realview.gic.cpu_addr + + self.terminal = Terminal() + self.vncserver = VncServer() + + self.iobus = IOXBar() + # Device DMA -> MEM + self.mem_ranges = self.getMemRanges(int(Addr(mem_size))) + + def getMemRanges(self, mem_size): + """ + Define system memory ranges. This depends on the physical + memory map provided by the realview platform and by the memory + size provided by the user (mem_size argument). + The method is iterating over all platform ranges until they cover + the entire user's memory requirements. + """ + mem_ranges = [] + for mem_range in self.realview._mem_regions: + size_in_range = min(mem_size, mem_range.size()) + + mem_ranges.append( + AddrRange(start=mem_range.start, size=size_in_range) + ) + + mem_size -= size_in_range + if mem_size == 0: + return mem_ranges + + raise ValueError("memory size too big for platform capabilities") + + class SimpleSystem(BaseSimpleSystem): """ Meant to be used with the classic memory model diff --git a/configs/example/arm/etrace_se.py b/configs/example/arm/etrace_se.py new file mode 100644 index 0000000000..8fa971ff84 --- /dev/null +++ b/configs/example/arm/etrace_se.py @@ -0,0 +1,191 @@ +# Copyright (c) 2016-2017, 2022-2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +import os +import m5 +from m5.util import addToPath +from m5.objects import * +import argparse +import shlex + +m5.util.addToPath("../..") + +from common import ObjectList + +import devices + + +def get_processes(cmd): + """Interprets commands to run and returns a list of processes""" + + cwd = os.getcwd() + multiprocesses = [] + for idx, c in enumerate(cmd): + argv = shlex.split(c) + + process = Process(pid=100 + idx, cwd=cwd, cmd=argv, executable=argv[0]) + process.gid = os.getgid() + + print("info: %d. command and arguments: %s" % (idx + 1, process.cmd)) + multiprocesses.append(process) + + return multiprocesses + + +def create(args): + """Create and configure the system object.""" + + system = devices.SimpleSeSystem( + mem_mode="timing", + ) + + # Add CPUs to the system. A cluster of CPUs typically have + # private L1 caches and a shared L2 cache. + system.cpu_cluster = devices.ArmCpuCluster( + system, + args.num_cores, + args.cpu_freq, + "1.2V", + ObjectList.cpu_list.get("O3_ARM_v7a_3_Etrace"), + devices.L1I, + devices.L1D, + devices.L2, + ) + + # Attach the elastic trace probe listener to every CPU in the cluster + for cpu in system.cpu_cluster: + cpu.attach_probe_listener(args.inst_trace_file, args.data_trace_file) + + # As elastic trace generation is enabled, make sure the memory system is + # minimal so that compute delays do not include memory access latencies. + # Configure the compulsory L1 caches for the O3CPU, do not configure + # any more caches. + system.addCaches(True, last_cache_level=1) + + # For elastic trace, over-riding Simple Memory latency to 1ns." + system.memory = SimpleMemory( + range=AddrRange(start=0, size=args.mem_size), + latency="1ns", + port=system.membus.mem_side_ports, + ) + + # Parse the command line and get a list of Processes instances + # that we can pass to gem5. + processes = get_processes(args.commands_to_run) + if len(processes) != args.num_cores: + print( + "Error: Cannot map %d command(s) onto %d CPU(s)" + % (len(processes), args.num_cores) + ) + sys.exit(1) + + system.workload = SEWorkload.init_compatible(processes[0].executable) + + # Assign one workload to each CPU + for cpu, workload in zip(system.cpu_cluster.cpus, processes): + cpu.workload = workload + + return system + + +def main(): + parser = argparse.ArgumentParser(epilog=__doc__) + + parser.add_argument( + "commands_to_run", + metavar="command(s)", + nargs="+", + help="Command(s) to run", + ) + parser.add_argument( + "--inst-trace-file", + action="store", + type=str, + help="""Instruction fetch trace file input to + Elastic Trace probe in a capture simulation and + Trace CPU in a replay simulation""", + default="fetchtrace.proto.gz", + ) + parser.add_argument( + "--data-trace-file", + action="store", + type=str, + help="""Data dependency trace file input to + Elastic Trace probe in a capture simulation and + Trace CPU in a replay simulation""", + default="deptrace.proto.gz", + ) + parser.add_argument("--cpu-freq", type=str, default="4GHz") + parser.add_argument( + "--num-cores", type=int, default=1, help="Number of CPU cores" + ) + parser.add_argument( + "--mem-size", + action="store", + type=str, + default="2GB", + help="Specify the physical memory size", + ) + + args = parser.parse_args() + + # Create a single root node for gem5's object hierarchy. There can + # only exist one root node in the simulator at any given + # time. Tell gem5 that we want to use syscall emulation mode + # instead of full system mode. + root = Root(full_system=False) + + # Populate the root node with a system. A system corresponds to a + # single node with shared memory. + root.system = create(args) + + # Instantiate the C++ object hierarchy. After this point, + # SimObjects can't be instantiated anymore. + m5.instantiate() + + # Start the simulator. This gives control to the C++ world and + # starts the simulator. The returned event tells the simulation + # script why the simulator exited. + event = m5.simulate() + + # Print the reason for the simulation exit. Some exit codes are + # requests for service (e.g., checkpoints) from the simulation + # script. We'll just ignore them here and exit. + print(f"{event.getCause()} ({event.getCode()}) @ {m5.curTick()}") + + +if __name__ == "__m5_main__": + main() diff --git a/configs/example/arm/starter_se.py b/configs/example/arm/starter_se.py index f21f399675..9834487155 100644 --- a/configs/example/arm/starter_se.py +++ b/configs/example/arm/starter_se.py @@ -64,72 +64,6 @@ cpu_types = { } -class SimpleSeSystem(System): - """ - Example system class for syscall emulation mode - """ - - # Use a fixed cache line size of 64 bytes - cache_line_size = 64 - - def __init__(self, args, **kwargs): - super(SimpleSeSystem, self).__init__(**kwargs) - - # Setup book keeping to be able to use CpuClusters from the - # devices module. - self._clusters = [] - self._num_cpus = 0 - - # Create a voltage and clock domain for system components - self.voltage_domain = VoltageDomain(voltage="3.3V") - self.clk_domain = SrcClockDomain( - clock="1GHz", voltage_domain=self.voltage_domain - ) - - # Create the off-chip memory bus. - self.membus = SystemXBar() - - # Wire up the system port that gem5 uses to load the kernel - # and to perform debug accesses. - self.system_port = self.membus.cpu_side_ports - - # Add CPUs to the system. A cluster of CPUs typically have - # private L1 caches and a shared L2 cache. - self.cpu_cluster = devices.ArmCpuCluster( - self, - args.num_cores, - args.cpu_freq, - "1.2V", - *cpu_types[args.cpu], - tarmac_gen=args.tarmac_gen, - tarmac_dest=args.tarmac_dest, - ) - - # Create a cache hierarchy (unless we are simulating a - # functional CPU in atomic memory mode) for the CPU cluster - # and connect it to the shared memory bus. - if self.cpu_cluster.memory_mode() == "timing": - self.cpu_cluster.addL1() - self.cpu_cluster.addL2(self.cpu_cluster.clk_domain) - self.cpu_cluster.connectMemSide(self.membus) - - # Tell gem5 about the memory mode used by the CPUs we are - # simulating. - self.mem_mode = self.cpu_cluster.memory_mode() - - def numCpuClusters(self): - return len(self._clusters) - - def addCpuCluster(self, cpu_cluster): - assert cpu_cluster not in self._clusters - assert len(cpu_cluster) > 0 - self._clusters.append(cpu_cluster) - self._num_cpus += len(cpu_cluster) - - def numCpus(self): - return self._num_cpus - - def get_processes(cmd): """Interprets commands to run and returns a list of processes""" @@ -150,7 +84,31 @@ def get_processes(cmd): def create(args): """Create and configure the system object.""" - system = SimpleSeSystem(args) + cpu_class = cpu_types[args.cpu][0] + mem_mode = cpu_class.memory_mode() + # Only simulate caches when using a timing CPU (e.g., the HPI model) + want_caches = True if mem_mode == "timing" else False + + system = devices.SimpleSeSystem( + mem_mode=mem_mode, + ) + + # Add CPUs to the system. A cluster of CPUs typically have + # private L1 caches and a shared L2 cache. + system.cpu_cluster = devices.ArmCpuCluster( + system, + args.num_cores, + args.cpu_freq, + "1.2V", + *cpu_types[args.cpu], + tarmac_gen=args.tarmac_gen, + tarmac_dest=args.tarmac_dest, + ) + + # Create a cache hierarchy for the cluster. We are assuming that + # clusters have core-private L1 caches and an L2 that's shared + # within the cluster. + system.addCaches(want_caches, last_cache_level=2) # Tell components about the expected physical memory ranges. This # is, for example, used by the MemConfig helper to determine where @@ -160,6 +118,9 @@ def create(args): # Configure the off-chip memory system. MemConfig.config_mem(args, system) + # Wire up the system's memory system + system.connect() + # Parse the command line and get a list of Processes instances # that we can pass to gem5. processes = get_processes(args.commands_to_run) diff --git a/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py b/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py index b5eb7e9912..5787bf4bfc 100644 --- a/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py +++ b/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py @@ -128,7 +128,6 @@ board.set_se_simpoint_workload( ) dir = Path(args.checkpoint_path) -dir.mkdir(exist_ok=True) simulator = Simulator( board=board, diff --git a/ext/drampower/src/CmdScheduler.h b/ext/drampower/src/CmdScheduler.h index 58efd279b1..1497304f54 100644 --- a/ext/drampower/src/CmdScheduler.h +++ b/ext/drampower/src/CmdScheduler.h @@ -84,8 +84,7 @@ class cmdScheduler { std::string name; physicalAddr PhysicalAddr; // sorting the commands according to their scheduling time. - struct commandItemSorter : public std::binary_function{ + struct commandItemSorter { bool operator()(const commandItem& lhs, const commandItem& rhs) const { diff --git a/src/arch/arm/pcstate.hh b/src/arch/arm/pcstate.hh index 7b75ed8184..a2f0463fab 100644 --- a/src/arch/arm/pcstate.hh +++ b/src/arch/arm/pcstate.hh @@ -92,7 +92,7 @@ class PCState : public GenericISA::UPCState<4> public: void - set(Addr val) + set(Addr val) override { Base::set(val); npc(val + (thumb() ? 2 : 4)); diff --git a/src/arch/generic/pcstate.hh b/src/arch/generic/pcstate.hh index 5c278a4233..25b3af69ea 100644 --- a/src/arch/generic/pcstate.hh +++ b/src/arch/generic/pcstate.hh @@ -489,7 +489,7 @@ class DelaySlotPCState : public SimplePCState void nnpc(Addr val) { _nnpc = val; } void - set(Addr val) + set(Addr val) override { Base::set(val); nnpc(val + 2 * InstWidth); @@ -563,7 +563,7 @@ class DelaySlotUPCState : public DelaySlotPCState } void - set(Addr val) + set(Addr val) override { Base::set(val); this->upc(0); diff --git a/src/arch/x86/pcstate.hh b/src/arch/x86/pcstate.hh index a0ed6ffe9f..95984d7a96 100644 --- a/src/arch/x86/pcstate.hh +++ b/src/arch/x86/pcstate.hh @@ -66,7 +66,7 @@ class PCState : public GenericISA::UPCState<8> } void - set(Addr val) + set(Addr val) override { Base::set(val); _size = 0; diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py index d18ca3f821..3bf5e52ae0 100644 --- a/src/cpu/pred/BranchPredictor.py +++ b/src/cpu/pred/BranchPredictor.py @@ -1,3 +1,15 @@ +# Copyright (c) 2022-2023 The University of Edinburgh +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2012 Mark D. Hill and David A. Wood # Copyright (c) 2015 The University of Wisconsin # All rights reserved. @@ -25,10 +37,46 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * from m5.proxy import * +from m5.objects.ClockedObject import ClockedObject + + +class BranchType(Enum): + vals = [ + "NoBranch", + "Return", + "CallDirect", + "CallIndirect", # 'Call', + "DirectCond", + "DirectUncond", # 'Direct', + "IndirectCond", + "IndirectUncond", #'Indirect', + ] + + +class BranchTargetBuffer(ClockedObject): + type = "BranchTargetBuffer" + cxx_class = "gem5::branch_prediction::BranchTargetBuffer" + cxx_header = "cpu/pred/btb.hh" + abstract = True + + numThreads = Param.Unsigned(Parent.numThreads, "Number of threads") + + +class SimpleBTB(BranchTargetBuffer): + type = "SimpleBTB" + cxx_class = "gem5::branch_prediction::SimpleBTB" + cxx_header = "cpu/pred/simple_btb.hh" + + numEntries = Param.Unsigned(4096, "Number of BTB entries") + tagBits = Param.Unsigned(16, "Size of the BTB tags, in bits") + instShiftAmt = Param.Unsigned( + Parent.instShiftAmt, "Number of bits to shift instructions by" + ) + class IndirectPredictor(SimObject): type = "IndirectPredictor" @@ -63,11 +111,12 @@ class BranchPredictor(SimObject): abstract = True numThreads = Param.Unsigned(Parent.numThreads, "Number of threads") - BTBEntries = Param.Unsigned(4096, "Number of BTB entries") - BTBTagSize = Param.Unsigned(16, "Size of the BTB tags, in bits") - RASSize = Param.Unsigned(16, "RAS size") instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by") + RASSize = Param.Unsigned(16, "RAS size") + + btb = Param.BranchTargetBuffer(SimpleBTB(), "Branch target buffer (BTB)") + indirectBranchPred = Param.IndirectPredictor( SimpleIndirectPredictor(), "Indirect branch predictor, set to NULL to disable indirect predictions", diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript index f4b6870ec5..89054ba8e8 100644 --- a/src/cpu/pred/SConscript +++ b/src/cpu/pred/SConscript @@ -1,5 +1,17 @@ # -*- mode:python -*- +# Copyright (c) 2022-2023 The University of Edinburgh +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2006 The Regents of The University of Michigan # All rights reserved. # @@ -28,8 +40,12 @@ Import('*') -SimObject('BranchPredictor.py', sim_objects=[ - 'IndirectPredictor', 'SimpleIndirectPredictor', 'BranchPredictor', + +SimObject('BranchPredictor.py', + sim_objects=[ + 'BranchPredictor', + 'IndirectPredictor', 'SimpleIndirectPredictor', + 'BranchTargetBuffer', 'SimpleBTB', 'LocalBP', 'TournamentBP', 'BiModeBP', 'TAGEBase', 'TAGE', 'LoopPredictor', 'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB', 'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L', @@ -41,17 +57,16 @@ SimObject('BranchPredictor.py', sim_objects=[ 'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB', 'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB', 'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB', - 'MultiperspectivePerceptronTAGE8KB']) + 'MultiperspectivePerceptronTAGE8KB'], + enums=['BranchType']) -DebugFlag('Indirect') Source('bpred_unit.cc') Source('2bit_local.cc') -Source('btb.cc') Source('simple_indirect.cc') Source('indirect.cc') Source('ras.cc') Source('tournament.cc') -Source ('bi_mode.cc') +Source('bi_mode.cc') Source('tage_base.cc') Source('tage.cc') Source('loop_predictor.cc') @@ -66,6 +81,10 @@ Source('statistical_corrector.cc') Source('tage_sc_l.cc') Source('tage_sc_l_8KB.cc') Source('tage_sc_l_64KB.cc') +Source('btb.cc') +Source('simple_btb.cc') +DebugFlag('Indirect') +DebugFlag('BTB') DebugFlag('FreeList') DebugFlag('Branch') DebugFlag('Tage') diff --git a/src/cpu/pred/bpred_unit.cc b/src/cpu/pred/bpred_unit.cc index ed8d6c8b08..85cb7c9e2f 100644 --- a/src/cpu/pred/bpred_unit.cc +++ b/src/cpu/pred/bpred_unit.cc @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2012, 2014 ARM Limited - * Copyright (c) 2010 The University of Edinburgh + * Copyright (c) 2010,2022-2023 The University of Edinburgh * Copyright (c) 2012 Mark D. Hill and David A. Wood * All rights reserved * @@ -59,10 +59,7 @@ BPredUnit::BPredUnit(const Params ¶ms) : SimObject(params), numThreads(params.numThreads), predHist(numThreads), - BTB(params.BTBEntries, - params.BTBTagSize, - params.instShiftAmt, - params.numThreads), + btb(params.btb), RAS(numThreads), iPred(params.indirectBranchPred), stats(this), @@ -218,10 +215,13 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, if (inst->isDirectCtrl() || !iPred) { ++stats.BTBLookups; // Check BTB on direct branches - if (BTB.valid(pc.instAddr(), tid)) { + const PCStateBase * btb_target = btb->lookup(tid, + pc.instAddr(), + getBranchType(inst)); + if (btb_target) { ++stats.BTBHits; // If it's not a return, use the BTB to get target addr. - set(target, BTB.lookup(pc.instAddr(), tid)); + set(target, btb_target); DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s predicted " "target is %s\n", @@ -482,7 +482,8 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, hist_it->seqNum, hist_it->pc); ++stats.BTBUpdates; - BTB.update(hist_it->pc, corr_target, tid); + btb->update(tid, hist_it->pc, corr_target, + getBranchType(hist_it->inst)); } } else { //Actually not Taken diff --git a/src/cpu/pred/bpred_unit.hh b/src/cpu/pred/bpred_unit.hh index 4af1d876a8..1b10d44a7c 100644 --- a/src/cpu/pred/bpred_unit.hh +++ b/src/cpu/pred/bpred_unit.hh @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2012, 2014 ARM Limited - * Copyright (c) 2010 The University of Edinburgh + * Copyright (c) 2010,2022-2023 The University of Edinburgh * All rights reserved * * The license below extends only to copyright in the software and shall @@ -46,6 +46,7 @@ #include "base/statistics.hh" #include "base/types.hh" +#include "cpu/pred/branch_type.hh" #include "cpu/pred/btb.hh" #include "cpu/pred/indirect.hh" #include "cpu/pred/ras.hh" @@ -152,7 +153,14 @@ class BPredUnit : public SimObject * @param inst_PC The PC to look up. * @return Whether the BTB contains the given PC. */ - bool BTBValid(Addr instPC) { return BTB.valid(instPC, 0); } + bool BTBValid(ThreadID tid, Addr instPC) + { + return btb->valid(tid, instPC); + } + bool BTBValid(ThreadID tid, PCStateBase &instPC) + { + return BTBValid(tid, instPC.instAddr()); + } /** * Looks up a given PC in the BTB to get the predicted target. The PC may @@ -162,9 +170,9 @@ class BPredUnit : public SimObject * @return The address of the target of the branch. */ const PCStateBase * - BTBLookup(Addr inst_pc) + BTBLookup(ThreadID tid, PCStateBase &instPC) { - return BTB.lookup(inst_pc, 0); + return btb->lookup(tid, instPC.instAddr()); } /** @@ -189,10 +197,10 @@ class BPredUnit : public SimObject * @param target_PC The branch's target that will be added to the BTB. */ void - BTBUpdate(Addr instPC, const PCStateBase &target) + BTBUpdate(ThreadID tid, Addr instPC, const PCStateBase &target) { ++stats.BTBUpdates; - BTB.update(instPC, target, 0); + return btb->update(tid, instPC, target); } @@ -295,7 +303,7 @@ class BPredUnit : public SimObject std::vector predHist; /** The BTB. */ - DefaultBTB BTB; + BranchTargetBuffer* btb; /** The per-thread return address stack. */ std::vector RAS; diff --git a/src/cpu/pred/branch_type.hh b/src/cpu/pred/branch_type.hh new file mode 100644 index 0000000000..dcc6149a9b --- /dev/null +++ b/src/cpu/pred/branch_type.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* @file + * A helper for branch type information + */ + +#ifndef __CPU_PRED_BRANCH_TYPE_HH__ +#define __CPU_PRED_BRANCH_TYPE_HH__ + +#include "cpu/static_inst.hh" +#include "enums/BranchType.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +typedef enums::BranchType BranchType; + +inline BranchType getBranchType(StaticInstPtr inst) +{ + if (inst->isReturn()) { + return BranchType::Return; + } + + if (inst->isCall()) { + return inst->isDirectCtrl() + ? BranchType::CallDirect + : BranchType::CallIndirect; + } + + if (inst->isDirectCtrl()) { + return inst->isCondCtrl() + ? BranchType::DirectCond + : BranchType::DirectUncond; + } + + if (inst->isIndirectCtrl()) { + return inst->isCondCtrl() + ? BranchType::IndirectCond + : BranchType::IndirectUncond; + } + return BranchType::NoBranch; +} + +inline std::string toString(BranchType type) +{ + return std::string(enums::BranchTypeStrings[type]); +} + + +} // namespace branch_prediction +} // namespace gem5 + +#endif // __CPU_PRED_BRANCH_TYPE_HH__ diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc index 71afd45b9f..85d3e2c9bb 100644 --- a/src/cpu/pred/btb.cc +++ b/src/cpu/pred/btb.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -28,119 +40,59 @@ #include "cpu/pred/btb.hh" -#include "base/intmath.hh" -#include "base/trace.hh" -#include "debug/Fetch.hh" - namespace gem5 { namespace branch_prediction { -DefaultBTB::DefaultBTB(unsigned _numEntries, - unsigned _tagBits, - unsigned _instShiftAmt, - unsigned _num_threads) - : numEntries(_numEntries), - tagBits(_tagBits), - instShiftAmt(_instShiftAmt), - log2NumThreads(floorLog2(_num_threads)) +BranchTargetBuffer::BranchTargetBuffer(const Params ¶ms) + : ClockedObject(params), + numThreads(params.numThreads), + stats(this) { - DPRINTF(Fetch, "BTB: Creating BTB object.\n"); +} - if (!isPowerOf2(numEntries)) { - fatal("BTB entries is not a power of 2!"); +BranchTargetBuffer::BranchTargetBufferStats::BranchTargetBufferStats( + statistics::Group *parent) + : statistics::Group(parent), + ADD_STAT(lookups, statistics::units::Count::get(), + "Number of BTB lookups"), + ADD_STAT(misses, statistics::units::Count::get(), + "Number of BTB misses"), + ADD_STAT(updates, statistics::units::Count::get(), + "Number of BTB updates"), + ADD_STAT(mispredict, statistics::units::Count::get(), + "Number of BTB mispredictions. " + "No target found or target wrong."), + ADD_STAT(evictions, statistics::units::Count::get(), + "Number of BTB evictions") +{ + using namespace statistics; + lookups + .init(enums::Num_BranchType) + .flags(total | pdf); + + misses + .init(enums::Num_BranchType) + .flags(total | pdf); + + updates + .init(enums::Num_BranchType) + .flags(total | pdf); + + mispredict + .init(enums::Num_BranchType) + .flags(total | pdf); + + evictions.flags(nozero); + + for (int i = 0; i < enums::Num_BranchType; i++) { + lookups.subname(i, enums::BranchTypeStrings[i]); + misses.subname(i, enums::BranchTypeStrings[i]); + updates.subname(i, enums::BranchTypeStrings[i]); + mispredict.subname(i, enums::BranchTypeStrings[i]); } - - btb.resize(numEntries); - - for (unsigned i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } - - idxMask = numEntries - 1; - - tagMask = (1 << tagBits) - 1; - - tagShiftAmt = instShiftAmt + floorLog2(numEntries); -} - -void -DefaultBTB::reset() -{ - for (unsigned i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } -} - -inline -unsigned -DefaultBTB::getIndex(Addr instPC, ThreadID tid) -{ - // Need to shift PC over by the word offset. - return ((instPC >> instShiftAmt) - ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) - & idxMask; -} - -inline -Addr -DefaultBTB::getTag(Addr instPC) -{ - return (instPC >> tagShiftAmt) & tagMask; -} - -bool -DefaultBTB::valid(Addr instPC, ThreadID tid) -{ - unsigned btb_idx = getIndex(instPC, tid); - - Addr inst_tag = getTag(instPC); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return true; - } else { - return false; - } -} - -// @todo Create some sort of return struct that has both whether or not the -// address is valid, and also the address. For now will just use addr = 0 to -// represent invalid entry. -const PCStateBase * -DefaultBTB::lookup(Addr inst_pc, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_pc, tid); - - Addr inst_tag = getTag(inst_pc); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return btb[btb_idx].target.get(); - } else { - return nullptr; - } -} - -void -DefaultBTB::update(Addr inst_pc, const PCStateBase &target, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_pc, tid); - - assert(btb_idx < numEntries); - - btb[btb_idx].tid = tid; - btb[btb_idx].valid = true; - set(btb[btb_idx].target, target); - btb[btb_idx].tag = getTag(inst_pc); } } // namespace branch_prediction diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh index 9213053d77..dd3e56a20f 100644 --- a/src/cpu/pred/btb.hh +++ b/src/cpu/pred/btb.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -29,9 +41,13 @@ #ifndef __CPU_PRED_BTB_HH__ #define __CPU_PRED_BTB_HH__ + #include "arch/generic/pcstate.hh" -#include "base/logging.hh" -#include "base/types.hh" +#include "base/statistics.hh" +#include "cpu/pred/branch_type.hh" +#include "cpu/static_inst.hh" +#include "params/BranchTargetBuffer.hh" +#include "sim/clocked_object.hh" namespace gem5 { @@ -39,93 +55,73 @@ namespace gem5 namespace branch_prediction { -class DefaultBTB +class BranchTargetBuffer : public ClockedObject { - private: - struct BTBEntry - { - /** The entry's tag. */ - Addr tag = 0; - - /** The entry's target. */ - std::unique_ptr target; - - /** The entry's thread id. */ - ThreadID tid; - - /** Whether or not the entry is valid. */ - bool valid = false; - }; - public: - /** Creates a BTB with the given number of entries, number of bits per - * tag, and instruction offset amount. - * @param numEntries Number of entries for the BTB. - * @param tagBits Number of bits for each tag in the BTB. - * @param instShiftAmt Offset amount for instructions to ignore alignment. - */ - DefaultBTB(unsigned numEntries, unsigned tagBits, - unsigned instShiftAmt, unsigned numThreads); + typedef BranchTargetBufferParams Params; + typedef enums::BranchType BranchType; - void reset(); + BranchTargetBuffer(const Params ¶ms); - /** Looks up an address in the BTB. Must call valid() first on the address. + virtual void memInvalidate() override = 0; + + /** Checks if a branch address is in the BTB. Intended as a quick check + * before calling lookup. Does not update statistics. * @param inst_PC The address of the branch to look up. - * @param tid The thread id. - * @return Returns the target of the branch. - */ - const PCStateBase *lookup(Addr instPC, ThreadID tid); - - /** Checks if a branch is in the BTB. - * @param inst_PC The address of the branch to look up. - * @param tid The thread id. * @return Whether or not the branch exists in the BTB. */ - bool valid(Addr instPC, ThreadID tid); + virtual bool valid(ThreadID tid, Addr instPC) = 0; + + /** Looks up an address in the BTB to get the target of the branch. + * @param inst_PC The address of the branch to look up. + * @param type Optional type of the branch to look up. + * @return The target of the branch or nullptr if the branch is not + * in the BTB. + */ + virtual const PCStateBase *lookup(ThreadID tid, Addr instPC, + BranchType type = BranchType::NoBranch) = 0; + + /** Looks up an address in the BTB and return the instruction + * information if existant. Does not update statistics. + * @param inst_PC The address of the branch to look up. + * @return Returns the target of the branch. + */ + virtual const StaticInstPtr getInst(ThreadID tid, Addr instPC) = 0; + /** Updates the BTB with the target of a branch. * @param inst_pc The address of the branch being updated. * @param target_pc The target address of the branch. - * @param tid The thread id. */ - void update(Addr inst_pc, const PCStateBase &target_pc, ThreadID tid); + virtual void update(ThreadID tid, Addr inst_pc, + const PCStateBase &target_pc, + BranchType type = BranchType::NoBranch, + StaticInstPtr inst = nullptr) = 0; - private: - /** Returns the index into the BTB, based on the branch's PC. - * @param inst_PC The branch to look up. - * @return Returns the index into the BTB. + /** Update BTB statistics */ - inline unsigned getIndex(Addr instPC, ThreadID tid); + virtual void incorrectTarget(Addr inst_pc, + BranchType type = BranchType::NoBranch) + { + stats.mispredict[type]++; + } - /** Returns the tag bits of a given address. - * @param inst_PC The branch's address. - * @return Returns the tag bits. - */ - inline Addr getTag(Addr instPC); + protected: + /** Number of the threads for which the branch history is maintained. */ + const unsigned numThreads; - /** The actual BTB. */ - std::vector btb; + struct BranchTargetBufferStats : public statistics::Group + { + BranchTargetBufferStats(statistics::Group *parent); - /** The number of entries in the BTB. */ - unsigned numEntries; + statistics::Vector lookups; + statistics::Vector misses; + statistics::Vector updates; + statistics::Vector mispredict; + statistics::Scalar evictions; - /** The index mask. */ - unsigned idxMask; + } stats; - /** The number of tag bits per entry. */ - unsigned tagBits; - - /** The tag mask. */ - unsigned tagMask; - - /** Number of bits to shift PC when calculating index. */ - unsigned instShiftAmt; - - /** Number of bits to shift PC when calculating tag. */ - unsigned tagShiftAmt; - - /** Log2 NumThreads used for hashing threadid */ - unsigned log2NumThreads; }; } // namespace branch_prediction diff --git a/src/cpu/pred/simple_btb.cc b/src/cpu/pred/simple_btb.cc new file mode 100644 index 0000000000..c78caac7a8 --- /dev/null +++ b/src/cpu/pred/simple_btb.cc @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu/pred/simple_btb.hh" + +#include "base/intmath.hh" +#include "base/trace.hh" +#include "debug/BTB.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +SimpleBTB::SimpleBTB(const SimpleBTBParams &p) + : BranchTargetBuffer(p), + numEntries(p.numEntries), + tagBits(p.tagBits), + instShiftAmt(p.instShiftAmt), + log2NumThreads(floorLog2(p.numThreads)) +{ + DPRINTF(BTB, "BTB: Creating BTB object.\n"); + + if (!isPowerOf2(numEntries)) { + fatal("BTB entries is not a power of 2!"); + } + + btb.resize(numEntries); + + for (unsigned i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } + + idxMask = numEntries - 1; + + tagMask = (1 << tagBits) - 1; + + tagShiftAmt = instShiftAmt + floorLog2(numEntries); +} + +void +SimpleBTB::memInvalidate() +{ + for (unsigned i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } +} + +inline +unsigned +SimpleBTB::getIndex(Addr instPC, ThreadID tid) +{ + // Need to shift PC over by the word offset. + return ((instPC >> instShiftAmt) + ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) + & idxMask; +} + +inline +Addr +SimpleBTB::getTag(Addr instPC) +{ + return (instPC >> tagShiftAmt) & tagMask; +} + +SimpleBTB::BTBEntry * +SimpleBTB::findEntry(Addr instPC, ThreadID tid) +{ + unsigned btb_idx = getIndex(instPC, tid); + Addr inst_tag = getTag(instPC); + + assert(btb_idx < numEntries); + + if (btb[btb_idx].valid + && inst_tag == btb[btb_idx].tag + && btb[btb_idx].tid == tid) { + return &btb[btb_idx]; + } + + return nullptr; +} + +bool +SimpleBTB::valid(ThreadID tid, Addr instPC) +{ + BTBEntry *entry = findEntry(instPC, tid); + + return entry != nullptr; +} + +// @todo Create some sort of return struct that has both whether or not the +// address is valid, and also the address. For now will just use addr = 0 to +// represent invalid entry. +const PCStateBase * +SimpleBTB::lookup(ThreadID tid, Addr instPC, BranchType type) +{ + stats.lookups[type]++; + + BTBEntry *entry = findEntry(instPC, tid); + + if (entry) { + return entry->target.get(); + } + stats.misses[type]++; + return nullptr; +} + +const StaticInstPtr +SimpleBTB::getInst(ThreadID tid, Addr instPC) +{ + BTBEntry *entry = findEntry(instPC, tid); + + if (entry) { + return entry->inst; + } + return nullptr; +} + +void +SimpleBTB::update(ThreadID tid, Addr instPC, + const PCStateBase &target, + BranchType type, StaticInstPtr inst) +{ + unsigned btb_idx = getIndex(instPC, tid); + + assert(btb_idx < numEntries); + + stats.updates[type]++; + + btb[btb_idx].tid = tid; + btb[btb_idx].valid = true; + set(btb[btb_idx].target, target); + btb[btb_idx].tag = getTag(instPC); + btb[btb_idx].inst = inst; +} + +} // namespace branch_prediction +} // namespace gem5 diff --git a/src/cpu/pred/simple_btb.hh b/src/cpu/pred/simple_btb.hh new file mode 100644 index 0000000000..3c76890348 --- /dev/null +++ b/src/cpu/pred/simple_btb.hh @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CPU_PRED_SIMPLE_BTB_HH__ +#define __CPU_PRED_SIMPLE_BTB_HH__ + +#include "base/logging.hh" +#include "base/types.hh" +#include "cpu/pred/btb.hh" +#include "params/SimpleBTB.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +class SimpleBTB : public BranchTargetBuffer +{ + public: + SimpleBTB(const SimpleBTBParams ¶ms); + + void memInvalidate() override; + bool valid(ThreadID tid, Addr instPC) override; + const PCStateBase *lookup(ThreadID tid, Addr instPC, + BranchType type = BranchType::NoBranch) override; + void update(ThreadID tid, Addr instPC, const PCStateBase &target_pc, + BranchType type = BranchType::NoBranch, + StaticInstPtr inst = nullptr) override; + const StaticInstPtr getInst(ThreadID tid, Addr instPC) override; + + + private: + struct BTBEntry + { + /** The entry's tag. */ + Addr tag = 0; + + /** The entry's target. */ + std::unique_ptr target; + + /** The entry's thread id. */ + ThreadID tid; + + /** Whether or not the entry is valid. */ + bool valid = false; + + /** Pointer to the static branch instruction at this address */ + StaticInstPtr inst = nullptr; + }; + + + /** Returns the index into the BTB, based on the branch's PC. + * @param inst_PC The branch to look up. + * @return Returns the index into the BTB. + */ + inline unsigned getIndex(Addr instPC, ThreadID tid); + + /** Returns the tag bits of a given address. + * @param inst_PC The branch's address. + * @return Returns the tag bits. + */ + inline Addr getTag(Addr instPC); + + /** Internal call to find an address in the BTB + * @param instPC The branch's address. + * @return Returns a pointer to the BTB entry if found, nullptr otherwise. + */ + BTBEntry *findEntry(Addr instPC, ThreadID tid); + + /** The actual BTB. */ + std::vector btb; + + /** The number of entries in the BTB. */ + unsigned numEntries; + + /** The index mask. */ + unsigned idxMask; + + /** The number of tag bits per entry. */ + unsigned tagBits; + + /** The tag mask. */ + unsigned tagMask; + + /** Number of bits to shift PC when calculating index. */ + unsigned instShiftAmt; + + /** Number of bits to shift PC when calculating tag. */ + unsigned tagShiftAmt; + + /** Log2 NumThreads used for hashing threadid */ + unsigned log2NumThreads; +}; + +} // namespace branch_prediction +} // namespace gem5 + +#endif // __CPU_PRED_SIMPLE_BTB_HH__ diff --git a/src/dev/amdgpu/SConscript b/src/dev/amdgpu/SConscript index 428d1c56bc..b8ba454d48 100644 --- a/src/dev/amdgpu/SConscript +++ b/src/dev/amdgpu/SConscript @@ -39,6 +39,7 @@ SimObject('AMDGPU.py', sim_objects=['AMDGPUDevice', 'AMDGPUInterruptHandler', tags='x86 isa') Source('amdgpu_device.cc', tags='x86 isa') +Source('amdgpu_gfx.cc', tags='x86 isa') Source('amdgpu_nbio.cc', tags='x86 isa') Source('amdgpu_vm.cc', tags='x86 isa') Source('interrupt_handler.cc', tags='x86 isa') diff --git a/src/dev/amdgpu/amdgpu_device.cc b/src/dev/amdgpu/amdgpu_device.cc index 5cc8df424f..1b81c4d0b2 100644 --- a/src/dev/amdgpu/amdgpu_device.cc +++ b/src/dev/amdgpu/amdgpu_device.cc @@ -379,6 +379,9 @@ AMDGPUDevice::readMMIO(PacketPtr pkt, Addr offset) case GRBM_BASE: gpuvm.readMMIO(pkt, aperture_offset >> GRBM_OFFSET_SHIFT); break; + case GFX_BASE: + gfx.readMMIO(pkt, aperture_offset); + break; case MMHUB_BASE: gpuvm.readMMIO(pkt, aperture_offset >> MMHUB_OFFSET_SHIFT); break; @@ -507,6 +510,9 @@ AMDGPUDevice::writeMMIO(PacketPtr pkt, Addr offset) case NBIO_BASE: nbio.writeMMIO(pkt, aperture_offset); break; + case GFX_BASE: + gfx.writeMMIO(pkt, aperture_offset); + break; default: DPRINTF(AMDGPUDevice, "Unknown MMIO aperture for %#x\n", offset); break; diff --git a/src/dev/amdgpu/amdgpu_device.hh b/src/dev/amdgpu/amdgpu_device.hh index 56ed2f4fa8..7f69ec19f6 100644 --- a/src/dev/amdgpu/amdgpu_device.hh +++ b/src/dev/amdgpu/amdgpu_device.hh @@ -36,6 +36,7 @@ #include "base/bitunion.hh" #include "dev/amdgpu/amdgpu_defines.hh" +#include "dev/amdgpu/amdgpu_gfx.hh" #include "dev/amdgpu/amdgpu_nbio.hh" #include "dev/amdgpu/amdgpu_vm.hh" #include "dev/amdgpu/memory_manager.hh" @@ -109,6 +110,7 @@ class AMDGPUDevice : public PciDevice * Blocks of the GPU */ AMDGPUNbio nbio; + AMDGPUGfx gfx; AMDGPUMemoryManager *gpuMemMgr; AMDGPUInterruptHandler *deviceIH; AMDGPUVM gpuvm; diff --git a/src/dev/amdgpu/amdgpu_gfx.cc b/src/dev/amdgpu/amdgpu_gfx.cc new file mode 100644 index 0000000000..3d5b274b86 --- /dev/null +++ b/src/dev/amdgpu/amdgpu_gfx.cc @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/amdgpu/amdgpu_gfx.hh" + +#include "mem/packet_access.hh" +#include "sim/core.hh" + +namespace gem5 +{ + +void +AMDGPUGfx::readMMIO(PacketPtr pkt, Addr offset) +{ + switch (offset) { + case AMDGPU_MM_RLC_GPU_CLOCK_COUNT_LSB: + pkt->setLE(captured_clock_count); + break; + case AMDGPU_MM_RLC_GPU_CLOCK_COUNT_MSB: + pkt->setLE(captured_clock_count >> 32); + break; + default: + break; + } +} + +void +AMDGPUGfx::writeMMIO(PacketPtr pkt, Addr offset) +{ + switch (offset) { + case AMDGPU_MM_RLC_CAPTURE_GPU_CLOCK_COUNT: + // Use gem5 Ticks in nanoseconds are the counter. The first capture + // is expected to return zero. + if (captured_clock_count == 1) { + captured_clock_count = 0; + } else { + captured_clock_count = curTick() / sim_clock::as_int::ns; + } + break; + default: + break; + } +} + +} // namespace gem5 diff --git a/src/dev/amdgpu/amdgpu_gfx.hh b/src/dev/amdgpu/amdgpu_gfx.hh new file mode 100644 index 0000000000..c32b8624cf --- /dev/null +++ b/src/dev/amdgpu/amdgpu_gfx.hh @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_AMDGPU_AMDGPU_GFX_HH__ +#define __DEV_AMDGPU_AMDGPU_GFX_HH__ + +#include "base/types.hh" +#include "mem/packet.hh" + +/** + * MMIO offsets for GFX. This class handles MMIO reads/writes to the GFX_BASE + * aperture which are generally read/written by the gfx driver source here: + * + * drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c + * https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/blob/master/ + * drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c + * + * The MMIO addresses in the file are dword addresses. Here they are converted + * to byte addresses so gem5 does not need to shift the values. + */ + +// Registers used to read GPU clock count used in profiling +#define AMDGPU_MM_RLC_GPU_CLOCK_COUNT_LSB 0x13090 +#define AMDGPU_MM_RLC_GPU_CLOCK_COUNT_MSB 0x13094 +#define AMDGPU_MM_RLC_CAPTURE_GPU_CLOCK_COUNT 0x13098 + +namespace gem5 +{ + +class AMDGPUGfx +{ + public: + AMDGPUGfx() { } + + void readMMIO(PacketPtr pkt, Addr offset); + void writeMMIO(PacketPtr pkt, Addr offset); + + private: + /* + * GPU clock count at the time capture MMIO is received. + */ + uint64_t captured_clock_count = 1; +}; + +} // namespace gem5 + +#endif // __DEV_AMDGPU_AMDGPU_GFX_HH__ diff --git a/src/dev/hsa/hsa_signal.hh b/src/dev/hsa/hsa_signal.hh index 6acbcb7e1b..7d1f316f04 100644 --- a/src/dev/hsa/hsa_signal.hh +++ b/src/dev/hsa/hsa_signal.hh @@ -69,6 +69,12 @@ typedef struct amd_signal_s uint32_t reserved3[2]; } amd_signal_t; +typedef struct +{ + uint64_t start_ts; + uint64_t end_ts; +} amd_event_t; + } // namespace gem5 #endif // DEV_HSA_HSA_SIGNAL_H diff --git a/src/gpu-compute/gpu_command_processor.cc b/src/gpu-compute/gpu_command_processor.cc index db69ad5cbd..ecc5f1d98b 100644 --- a/src/gpu-compute/gpu_command_processor.cc +++ b/src/gpu-compute/gpu_command_processor.cc @@ -248,6 +248,10 @@ GPUCommandProcessor::submitDispatchPkt(void *raw_pkt, uint32_t queue_id, initABI(task); ++dynamic_task_id; + + // The driver expects the start time to be in ns + Tick start_ts = curTick() / sim_clock::as_int::ns; + dispatchStartTime.insert({disp_pkt->completion_signal, start_ts}); } void @@ -280,16 +284,6 @@ GPUCommandProcessor::sendCompletionSignal(Addr signal_handle) void GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff) { - Addr value_addr = getHsaSignalValueAddr(signal_handle); - - uint64_t *signalValue = new uint64_t; - auto cb = new DmaVirtCallback( - [ = ] (const uint64_t &) - { updateHsaSignalData(value_addr, diff, signalValue); }); - dmaReadVirt(value_addr, sizeof(uint64_t), cb, (void *)signalValue); - DPRINTF(GPUCommandProc, "updateHsaSignalAsync reading value addr %lx\n", - value_addr); - Addr mailbox_addr = getHsaSignalMailboxAddr(signal_handle); uint64_t *mailboxValue = new uint64_t; auto cb2 = new DmaVirtCallback( @@ -300,20 +294,6 @@ GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff) mailbox_addr); } -void -GPUCommandProcessor::updateHsaSignalData(Addr value_addr, int64_t diff, - uint64_t *prev_value) -{ - // Reuse the value allocated for the read - DPRINTF(GPUCommandProc, "updateHsaSignalData read %ld, writing %ld\n", - *prev_value, *prev_value + diff); - *prev_value += diff; - auto cb = new DmaVirtCallback( - [ = ] (const uint64_t &) - { updateHsaSignalDone(prev_value); }); - dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value); -} - void GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value) @@ -331,6 +311,20 @@ GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle, dmaReadVirt(event_addr, sizeof(uint64_t), cb, (void *)mailbox_value); } else { delete mailbox_value; + + Addr ts_addr = signal_handle + offsetof(amd_signal_t, start_ts); + + amd_event_t *event_ts = new amd_event_t; + event_ts->start_ts = dispatchStartTime[signal_handle]; + event_ts->end_ts = curTick() / sim_clock::as_int::ns; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaEventTs(signal_handle, event_ts); }); + dmaWriteVirt(ts_addr, sizeof(amd_event_t), cb, (void *)event_ts); + DPRINTF(GPUCommandProc, "updateHsaMailboxData reading timestamp addr " + "%lx\n", ts_addr); + + dispatchStartTime.erase(signal_handle); } } @@ -346,6 +340,52 @@ GPUCommandProcessor::updateHsaEventData(Addr signal_handle, [ = ] (const uint64_t &) { updateHsaSignalDone(event_value); }, *event_value); dmaWriteVirt(mailbox_addr, sizeof(uint64_t), cb, &cb->dmaBuffer, 0); + + Addr ts_addr = signal_handle + offsetof(amd_signal_t, start_ts); + + amd_event_t *event_ts = new amd_event_t; + event_ts->start_ts = dispatchStartTime[signal_handle]; + event_ts->end_ts = curTick() / sim_clock::as_int::ns; + auto cb2 = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaEventTs(signal_handle, event_ts); }); + dmaWriteVirt(ts_addr, sizeof(amd_event_t), cb2, (void *)event_ts); + DPRINTF(GPUCommandProc, "updateHsaEventData reading timestamp addr %lx\n", + ts_addr); + + dispatchStartTime.erase(signal_handle); +} + +void +GPUCommandProcessor::updateHsaEventTs(Addr signal_handle, + amd_event_t *ts) +{ + delete ts; + + Addr value_addr = getHsaSignalValueAddr(signal_handle); + int64_t diff = -1; + + uint64_t *signalValue = new uint64_t; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaSignalData(value_addr, diff, signalValue); }); + dmaReadVirt(value_addr, sizeof(uint64_t), cb, (void *)signalValue); + DPRINTF(GPUCommandProc, "updateHsaSignalAsync reading value addr %lx\n", + value_addr); +} + +void +GPUCommandProcessor::updateHsaSignalData(Addr value_addr, int64_t diff, + uint64_t *prev_value) +{ + // Reuse the value allocated for the read + DPRINTF(GPUCommandProc, "updateHsaSignalData read %ld, writing %ld\n", + *prev_value, *prev_value + diff); + *prev_value += diff; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaSignalDone(prev_value); }); + dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value); } void diff --git a/src/gpu-compute/gpu_command_processor.hh b/src/gpu-compute/gpu_command_processor.hh index 10407b9f93..f6783834eb 100644 --- a/src/gpu-compute/gpu_command_processor.hh +++ b/src/gpu-compute/gpu_command_processor.hh @@ -117,6 +117,7 @@ class GPUCommandProcessor : public DmaVirtDevice void updateHsaSignalDone(uint64_t *signal_value); void updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value); void updateHsaEventData(Addr signal_handle, uint64_t *event_value); + void updateHsaEventTs(Addr signal_handle, amd_event_t *event_value); uint64_t functionalReadHsaSignal(Addr signal_handle); @@ -148,6 +149,9 @@ class GPUCommandProcessor : public DmaVirtDevice HSAPacketProcessor *hsaPP; TranslationGenPtr translate(Addr vaddr, Addr size) override; + // Keep track of start times for task dispatches. + std::unordered_map dispatchStartTime; + /** * Perform a DMA read of the read_dispatch_id_field_base_byte_offset * field, which follows directly after the read_dispatch_id (the read diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index b439edf970..db215bd029 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -386,6 +386,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): "lpj=19988480", "norandmaps", "root={root_value}", + "disk_device={disk_device}", "rw", f"mem={self.get_memory().get_size()}", ] diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index ad130b7273..51db66913a 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -534,14 +534,19 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtsFile(os.path.join(outdir, "device.dts")) fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) - @overrides(KernelDiskWorkload) - def get_default_kernel_args(self) -> List[str]: - return ["console=ttyLIO0", "root={root_value}", "rw"] - @overrides(KernelDiskWorkload) def get_disk_device(self) -> str: return "/dev/lda" + @overrides(KernelDiskWorkload) + def get_default_kernel_args(self) -> List[str]: + return [ + "console=ttyLIO0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] + @overrides(KernelDiskWorkload) def _add_disk_to_board(self, disk_image: AbstractResource) -> None: # Note: This must be called after set_workload because it looks for an diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index 15e0cdf303..72b143e6ff 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -87,7 +87,7 @@ class KernelDiskWorkload: @abstractmethod def get_disk_device(self) -> str: """ - Get the disk device, e.g., "/dev/sda", where the disk image is placed. + Set a default disk device, in case user does not specify a disk device. :returns: The disk device. """ @@ -139,6 +139,7 @@ class KernelDiskWorkload: kernel: KernelResource, disk_image: DiskImageResource, bootloader: Optional[BootloaderResource] = None, + disk_device: Optional[str] = None, readfile: Optional[str] = None, readfile_contents: Optional[str] = None, kernel_args: Optional[List[str]] = None, @@ -171,6 +172,9 @@ class KernelDiskWorkload: # Abstract board. This function will not work otherwise. assert isinstance(self, AbstractBoard) + # Set the disk device + self._disk_device = disk_device + # If we are setting a workload of this type, we need to run as a # full-system simulation. self._set_fullsystem(True) @@ -182,7 +186,12 @@ class KernelDiskWorkload: self.workload.command_line = ( " ".join(kernel_args or self.get_default_kernel_args()) ).format( - root_value=self.get_default_kernel_root_val(disk_image=disk_image) + root_value=self.get_default_kernel_root_val(disk_image=disk_image), + disk_device=( + self._disk_device + if self._disk_device + else self.get_disk_device() + ), ) # Setting the bootloader information for ARM board. The current diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index 25f1fac562..d0000daffa 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -494,4 +494,9 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): @overrides(KernelDiskWorkload) def get_default_kernel_args(self) -> List[str]: - return ["console=ttyS0", "root={root_value}", "rw"] + return [ + "console=ttyS0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] diff --git a/src/python/gem5/components/boards/se_binary_workload.py b/src/python/gem5/components/boards/se_binary_workload.py index c62a1b67ea..cba268b2df 100644 --- a/src/python/gem5/components/boards/se_binary_workload.py +++ b/src/python/gem5/components/boards/se_binary_workload.py @@ -75,7 +75,6 @@ class SEBinaryWorkload: """Set up the system to run a specific binary. **Limitations** - * Only supports single threaded applications. * Dynamically linked executables are partially supported when the host ISA and the simulated ISA are the same. diff --git a/src/python/gem5/components/boards/x86_board.py b/src/python/gem5/components/boards/x86_board.py index 04fec617c1..01a0ac1f6b 100644 --- a/src/python/gem5/components/boards/x86_board.py +++ b/src/python/gem5/components/boards/x86_board.py @@ -318,4 +318,5 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload): "console=ttyS0", "lpj=7999923", "root={root_value}", + "disk_device={disk_device}", ] diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 9ca95839f8..a4e639801d 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -566,7 +566,12 @@ class RISCVMatchedBoard( @overrides(KernelDiskWorkload) def get_default_kernel_args(self) -> List[str]: - return ["console=ttyS0", "root={root_value}", "rw"] + return [ + "console=ttyS0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] @overrides(KernelDiskWorkload) def set_kernel_disk_workload( diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py index 4b8d2c1d32..ce265449c9 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py @@ -95,7 +95,7 @@ class U74FUPool(MinorFUPool): class U74BP(TournamentBP): - BTBEntries = 32 + btb = SimpleBTB(numEntries=32) RASSize = 12 localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2 localPredictorSize = 16384 diff --git a/util/dockerfiles/docker-compose.yaml b/util/dockerfiles/docker-compose.yaml index fcbc3e9f70..a4f585f6d7 100644 --- a/util/dockerfiles/docker-compose.yaml +++ b/util/dockerfiles/docker-compose.yaml @@ -1,3 +1,4 @@ +--- version: '2' services: