Merge branch 'develop' into workflows-for-new-runners
This commit is contained in:
263
.github/workflows/ci-tests.yaml
vendored
263
.github/workflows/ci-tests.yaml
vendored
@@ -1,105 +1,106 @@
|
|||||||
|
---
|
||||||
# This workflow runs after a pull-request has been approved by a reviewer.
|
# This workflow runs after a pull-request has been approved by a reviewer.
|
||||||
|
|
||||||
name: CI Tests
|
name: CI Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, edited, synchronize, ready_for_review]
|
types: [opened, edited, synchronize, ready_for_review]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-commit:
|
pre-commit:
|
||||||
# runs on github hosted runner
|
# runs on github hosted runner
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v3
|
- uses: actions/setup-python@v3
|
||||||
- uses: pre-commit/action@v3.0.0
|
- uses: pre-commit/action@v3.0.0
|
||||||
|
|
||||||
# ensures we have a change-id in every commit, needed for gerrit
|
# ensures we have a change-id in every commit, needed for gerrit
|
||||||
check-for-change-id:
|
check-for-change-id:
|
||||||
# runs on github hosted runner
|
# runs on github hosted runner
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Check for Change-Id
|
- name: Check for Change-Id
|
||||||
run: |
|
run: |
|
||||||
# loop through all the commits in the pull request
|
# 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
|
for commit in $(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}); do
|
||||||
git checkout $commit
|
git checkout $commit
|
||||||
if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ")
|
if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ")
|
||||||
then
|
then
|
||||||
# passes as long as at least one change-id exists in the pull request
|
# passes as long as at least one change-id exists in the pull request
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# if we reach this part, none of the commits had a change-id
|
# 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. "\
|
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) ; "\
|
"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."
|
"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
|
exit 1
|
||||||
|
|
||||||
unittests-all-opt:
|
unittests-all-opt:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
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
|
needs: [pre-commit, check-for-change-id] # only runs if pre-commit and change-id passes
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: CI Unittests
|
- name: CI Unittests
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: scons build/ALL/unittests.opt -j $(nproc)
|
run: scons build/ALL/unittests.opt -j $(nproc)
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
testlib-quick-matrix:
|
testlib-quick-matrix:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
# In order to make sure the environment is exactly the same, we run in
|
# 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
|
# the same container we use to build gem5 and run the testlib tests. This
|
||||||
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
||||||
needs: [pre-commit, check-for-change-id]
|
needs: [pre-commit, check-for-change-id]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
# Unfortunately the 'ubunutu-latest' image doesn't have jq installed.
|
# Unfortunately the 'ubunutu-latest' image doesn't have jq installed.
|
||||||
# We therefore need to install it as a step here.
|
# We therefore need to install it as a step here.
|
||||||
- name: Install jq
|
- name: Install jq
|
||||||
run: apt install -y jq
|
run: apt install -y jq
|
||||||
|
|
||||||
- name: Get directories for testlib-quick
|
- name: Get directories for testlib-quick
|
||||||
working-directory: "${{ github.workspace }}/tests"
|
working-directory: ${{ github.workspace }}/tests
|
||||||
id: dir-matrix
|
id: dir-matrix
|
||||||
run: echo "test-dirs-matrix=$(find gem5/* -type d -maxdepth 0 | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT
|
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
|
- name: Get the build targets for testlib-quick-gem5-builds
|
||||||
working-directory: "${{ github.workspace }}/tests"
|
working-directory: ${{ github.workspace }}/tests
|
||||||
id: build-matrix
|
id: build-matrix
|
||||||
run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT
|
run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
build-matrix: ${{ steps.build-matrix.outputs.build-matrix }}
|
build-matrix: ${{ steps.build-matrix.outputs.build-matrix }}
|
||||||
test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }}
|
test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }}
|
||||||
|
|
||||||
testlib-quick-gem5-builds:
|
testlib-quick-gem5-builds:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
||||||
needs: [pre-commit, check-for-change-id, testlib-quick-matrix]
|
needs: [pre-commit, check-for-change-id, testlib-quick-matrix]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }}
|
build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Build gem5
|
- name: Build gem5
|
||||||
run: scons ${{ matrix.build-target }} -j $(nproc)
|
run: scons ${{ matrix.build-target }} -j $(nproc)
|
||||||
|
|
||||||
# Upload the gem5 binary as an artifact.
|
# Upload the gem5 binary as an artifact.
|
||||||
# Note: the "achor.txt" file is a hack to make sure the paths are
|
# 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",
|
# Then upload-artifact will upload "ARM/gem5.opt" and "RISCV/gem5.opt",
|
||||||
# stripping the "build" directory. By adding the "anchor.txt" file, we
|
# stripping the "build" directory. By adding the "anchor.txt" file, we
|
||||||
# ensure the "build" directory is preserved.
|
# ensure the "build" directory is preserved.
|
||||||
- run: echo "anchor" > anchor.txt
|
- run: echo "anchor" > anchor.txt
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds
|
name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds
|
||||||
path: |
|
path: |
|
||||||
build/*/gem5.*
|
build/*/gem5.*
|
||||||
anchor.txt
|
anchor.txt
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
testlib-quick-execution:
|
testlib-quick-execution:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
||||||
needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds]
|
needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds]
|
||||||
timeout-minutes: 360 # 6 hours
|
timeout-minutes: 360 # 6 hours
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }}
|
test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Clean runner
|
- name: Clean runner
|
||||||
run:
|
run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true
|
||||||
rm -rf ./* || true
|
|
||||||
rm -rf ./.??* || true
|
|
||||||
rm -rf ~/.cache || true
|
|
||||||
|
|
||||||
# Checkout the repository then download the gem5.opt artifact.
|
# Checkout the repository then download the gem5.opt artifact.
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds
|
name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds
|
||||||
|
|
||||||
# Check that the gem5.opt artifact exists and is executable.
|
# Check that the gem5.opt artifact exists and is executable.
|
||||||
- name: Chmod gem5.{opt,debug,fast} to be executable
|
- name: Chmod gem5.{opt,debug,fast} to be executable
|
||||||
run: |
|
run: |
|
||||||
find . -name "gem5.opt" -exec chmod u+x {} \;
|
find . -name "gem5.opt" -exec chmod u+x {} \;
|
||||||
find . -name "gem5.debug" -exec chmod u+x {} \;
|
find . -name "gem5.debug" -exec chmod u+x {} \;
|
||||||
find . -name "gem5.fast" -exec chmod u+x {} \;
|
find . -name "gem5.fast" -exec chmod u+x {} \;
|
||||||
|
|
||||||
# Run the testlib quick tests in the given directory.
|
# Run the testlib quick tests in the given directory.
|
||||||
- name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests
|
- name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests
|
||||||
id: run-tests
|
id: run-tests
|
||||||
working-directory: ${{ github.workspace }}/tests
|
working-directory: ${{ github.workspace }}/tests
|
||||||
run: ./main.py run --skip-build -t $(nproc) -vv ${{ matrix.test-dir }}
|
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).
|
# Get the basename of the matrix.test-dir path (to name the artifact).
|
||||||
- name: Sanatize test-dir for artifact name
|
- name: Sanatize test-dir for artifact name
|
||||||
id: sanitize-test-dir
|
id: sanitize-test-dir
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT
|
run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
# Upload the tests/testing-results directory as an artifact.
|
# Upload the tests/testing-results directory as an artifact.
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
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
|
name: ci-tests-run-${{ github.run_number }}-attempt-${{ github.run_attempt }}-testlib-quick-${{ steps.sanitize-test-dir.outputs.sanatized-test-dir
|
||||||
path: tests/testing-results
|
}}-status-${{ steps.run-tests.outcome }}-output
|
||||||
retention-days: 30
|
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
|
# 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
|
# 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
|
# the testlib quick tests. This job is therefore a stub which will pass if
|
||||||
# all the testlib-quick-execution jobs pass.
|
# all the testlib-quick-execution jobs pass.
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
needs: testlib-quick-execution
|
needs: testlib-quick-execution
|
||||||
steps:
|
steps:
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|||||||
77
.github/workflows/compiler-tests.yaml
vendored
77
.github/workflows/compiler-tests.yaml
vendored
@@ -1,52 +1,57 @@
|
|||||||
|
---
|
||||||
# This workflow runs all of the compiler tests
|
# This workflow runs all of the compiler tests
|
||||||
|
|
||||||
name: Compiler Tests
|
name: Compiler Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Runs every Friday from 7AM UTC
|
# Runs every Friday from 7AM UTC
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '00 7 * * 5'
|
- cron: 00 7 * * 5
|
||||||
# Allows us to manually start workflow for testing
|
# Allows us to manually start workflow for testing
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# replication of compiler-tests.sh
|
# replication of compiler-tests.sh
|
||||||
all-compilers:
|
all-compilers:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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]
|
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,
|
||||||
opts: [.opt, .fast]
|
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,
|
||||||
runs-on: [self-hosted, linux, x64]
|
ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies]
|
||||||
timeout-minutes: 2880 # 48 hours
|
opts: [.opt, .fast]
|
||||||
container: gcr.io/gem5-test/${{ matrix.image }}:latest
|
runs-on: [self-hosted, linux, x64]
|
||||||
steps:
|
timeout-minutes: 2880 # 48 hours
|
||||||
- uses: actions/checkout@v3
|
container: gcr.io/gem5-test/${{ matrix.image }}:latest
|
||||||
with:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Compile build/ALL/gem5${{ matrix.opts }} with ${{ matrix.image }}
|
- 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)
|
run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/ALL/gem5${{ matrix.opts }} -j$(nproc)
|
||||||
timeout-minutes: 600 # 10 hours
|
timeout-minutes: 600 # 10 hours
|
||||||
|
|
||||||
# Tests the two latest gcc and clang supported compilers against all gem5 compilations.
|
# Tests the two latest gcc and clang supported compilers against all gem5 compilations.
|
||||||
latest-compilers-all-gem5-builds:
|
latest-compilers-all-gem5-builds:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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]
|
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,
|
||||||
image: [gcc-version-12, clang-version-16]
|
NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86,
|
||||||
opts: [.opt]
|
GCN3_X86]
|
||||||
runs-on: [self-hosted, linux, x64]
|
image: [gcc-version-12, clang-version-16]
|
||||||
timeout-minutes: 2880 # 48 hours
|
opts: [.opt]
|
||||||
container: gcr.io/gem5-test/${{ matrix.image }}:latest
|
runs-on: [self-hosted, linux, x64]
|
||||||
steps:
|
timeout-minutes: 2880 # 48 hours
|
||||||
- uses: actions/checkout@v3
|
container: gcr.io/gem5-test/${{ matrix.image }}:latest
|
||||||
with:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Compile build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} with ${{ matrix.image }}
|
- 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)
|
run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} -j$(nproc)
|
||||||
timeout-minutes: 600 # 10 hours
|
timeout-minutes: 600 # 10 hours
|
||||||
|
|||||||
472
.github/workflows/daily-tests.yaml
vendored
472
.github/workflows/daily-tests.yaml
vendored
@@ -1,286 +1,286 @@
|
|||||||
|
---
|
||||||
# This workflow runs all of the long tests within main.py, extra tests in nightly.sh, and unittests
|
# This workflow runs all of the long tests within main.py, extra tests in nightly.sh, and unittests
|
||||||
|
|
||||||
name: Daily Tests
|
name: Daily Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Runs every day from 7AM UTC
|
# Runs every day from 7AM UTC
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 7 * * *'
|
- cron: 0 7 * * *
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
name-artifacts:
|
name-artifacts:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
build-name: ${{ steps.artifact-name.outputs.name }}
|
build-name: ${{ steps.artifact-name.outputs.name }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- id: artifact-name
|
- id: artifact-name
|
||||||
run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT
|
run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
build-gem5:
|
build-gem5:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# NULL is in quotes since it is considered a keyword in yaml files
|
# 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
|
# this allows us to pass additional command line parameters
|
||||||
# the default is to add -j $(nproc), but some images
|
# the default is to add -j $(nproc), but some images
|
||||||
# require more specifications when built
|
# require more specifications when built
|
||||||
include:
|
include:
|
||||||
- command-line: -j $(nproc)
|
- command-line: -j $(nproc)
|
||||||
- image: ALL_CHI
|
- image: ALL_CHI
|
||||||
command-line: --default=ALL PROTOCOL=CHI -j $(nproc)
|
command-line: --default=ALL PROTOCOL=CHI -j $(nproc)
|
||||||
- image: ALL_MSI
|
- image: ALL_MSI
|
||||||
command-line: --default=ALL PROTOCOL=MSI -j $(nproc)
|
command-line: --default=ALL PROTOCOL=MSI -j $(nproc)
|
||||||
- image: ALL_MESI_Two_Level
|
- image: ALL_MESI_Two_Level
|
||||||
command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc)
|
command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc)
|
||||||
- image: NULL_MI_example
|
- image: NULL_MI_example
|
||||||
command-line: --default=NULL PROTOCOL=MI_example -j $(nproc)
|
command-line: --default=NULL PROTOCOL=MI_example -j $(nproc)
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
needs: name-artifacts
|
needs: name-artifacts
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Build gem5
|
- name: Build gem5
|
||||||
run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }}
|
run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }}
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }}
|
name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }}
|
||||||
path: build/${{ matrix.image }}/gem5.opt
|
path: build/${{ matrix.image }}/gem5.opt
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
# this builds both unittests.fast and unittests.debug
|
# this builds both unittests.fast and unittests.debug
|
||||||
unittests-fast-debug:
|
unittests-fast-debug:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
type: [fast, debug]
|
type: [fast, debug]
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: ALL/unittests.${{ matrix.type }} UnitTests
|
- name: ALL/unittests.${{ matrix.type }} UnitTests
|
||||||
run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc)
|
run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc)
|
||||||
|
|
||||||
# start running all of the long tests
|
# start running all of the long tests
|
||||||
testlib-long-tests:
|
testlib-long-tests:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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]
|
test-type: [arm_boot_tests, fs, gpu, insttest_se, learning_gem5, m5threads_test_atomic, memory, multi_isa, replacement_policies, riscv_boot_tests,
|
||||||
runs-on: [self-hosted, linux, x64]
|
stdlib, x86_boot_tests]
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
runs-on: [self-hosted, linux, x64]
|
||||||
needs: [name-artifacts, build-gem5]
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
timeout-minutes: 1440 # 24 hours for entire matrix to run
|
needs: [name-artifacts, build-gem5]
|
||||||
steps:
|
timeout-minutes: 1440 # 24 hours for entire matrix to run
|
||||||
- name: Clean runner
|
steps:
|
||||||
run:
|
- name: Clean runner
|
||||||
rm -rf ./* || true
|
run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true
|
||||||
rm -rf ./.??* || true
|
- uses: actions/checkout@v3
|
||||||
rm -rf ~/.cache || true
|
with:
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
# download all artifacts for each test
|
# download all artifacts for each test
|
||||||
# since long tests can't start until the build matrix completes,
|
# since long tests can't start until the build matrix completes,
|
||||||
# we download all artifacts from the build for each test
|
# we download all artifacts from the build for each test
|
||||||
# in this matrix
|
# in this matrix
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ALL
|
name: ${{needs.name-artifacts.outputs.build-name}}ALL
|
||||||
path: build/ALL
|
path: build/ALL
|
||||||
- run: chmod u+x build/ALL/gem5.opt
|
- run: chmod u+x build/ALL/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI
|
name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI
|
||||||
path: build/ALL_CHI
|
path: build/ALL_CHI
|
||||||
- run: chmod u+x build/ALL_CHI/gem5.opt
|
- run: chmod u+x build/ALL_CHI/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ARM
|
name: ${{needs.name-artifacts.outputs.build-name}}ARM
|
||||||
path: build/ARM
|
path: build/ARM
|
||||||
- run: chmod u+x build/ARM/gem5.opt
|
- run: chmod u+x build/ARM/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI
|
name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI
|
||||||
path: build/ALL_MSI
|
path: build/ALL_MSI
|
||||||
- run: chmod u+x build/ALL_MSI/gem5.opt
|
- run: chmod u+x build/ALL_MSI/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level
|
name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level
|
||||||
path: build/ALL_MESI_Two_Level
|
path: build/ALL_MESI_Two_Level
|
||||||
- run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt
|
- run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}NULL
|
name: ${{needs.name-artifacts.outputs.build-name}}NULL
|
||||||
path: build/NULL
|
path: build/NULL
|
||||||
- run: chmod u+x build/NULL/gem5.opt
|
- run: chmod u+x build/NULL/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example
|
name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example
|
||||||
path: build/NULL_MI_example
|
path: build/NULL_MI_example
|
||||||
- run: chmod u+x build/NULL_MI_example/gem5.opt
|
- run: chmod u+x build/NULL_MI_example/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}RISCV
|
name: ${{needs.name-artifacts.outputs.build-name}}RISCV
|
||||||
path: build/RISCV
|
path: build/RISCV
|
||||||
- run: chmod u+x build/RISCV/gem5.opt
|
- run: chmod u+x build/RISCV/gem5.opt
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86
|
name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86
|
||||||
path: build/VEGA_X86
|
path: build/VEGA_X86
|
||||||
- run: chmod u+x build/VEGA_X86/gem5.opt
|
- run: chmod u+x build/VEGA_X86/gem5.opt
|
||||||
# run test
|
# run test
|
||||||
- name: long ${{ matrix.test-type }} tests
|
- name: long ${{ matrix.test-type }} tests
|
||||||
working-directory: ${{ github.workspace }}/tests
|
working-directory: ${{ github.workspace }}/tests
|
||||||
run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc)
|
run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc)
|
||||||
- name: create zip of results
|
- name: create zip of results
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
run: |
|
run: |
|
||||||
apt-get -y install zip
|
apt-get -y install zip
|
||||||
zip -r output.zip tests/testing-results
|
zip -r output.zip tests/testing-results
|
||||||
- name: upload zip
|
- name: upload zip
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
env:
|
env:
|
||||||
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
||||||
with:
|
with:
|
||||||
name: ${{ env.MY_STEP_VAR }}
|
name: ${{ env.MY_STEP_VAR }}
|
||||||
path: output.zip
|
path: output.zip
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
# split library example tests into runs based on Suite UID
|
# split library example tests into runs based on Suite UID
|
||||||
# so that they don't hog the runners for too long
|
# so that they don't hog the runners for too long
|
||||||
testlib-long-gem5_library_example_tests:
|
testlib-long-gem5_library_example_tests:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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]
|
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,
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
gem5-library-example-arm-ubuntu-run-test-ALL-x86_64-opt, gem5-library-example-riscvmatched-hello-ALL-x86_64-opt]
|
||||||
needs: [name-artifacts, build-gem5]
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
timeout-minutes: 1440 # 24 hours
|
needs: [name-artifacts, build-gem5]
|
||||||
steps:
|
timeout-minutes: 1440 # 24 hours
|
||||||
- name: Clean runner
|
steps:
|
||||||
run:
|
- name: Clean runner
|
||||||
rm -rf ./* || true
|
run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true
|
||||||
rm -rf ./.??* || true
|
- uses: actions/checkout@v3
|
||||||
rm -rf ~/.cache || true
|
with:
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.name-artifacts.outputs.build-name}}ALL
|
name: ${{needs.name-artifacts.outputs.build-name}}ALL
|
||||||
path: build/ALL
|
path: build/ALL
|
||||||
- run: chmod u+x build/ALL/gem5.opt
|
- run: chmod u+x build/ALL/gem5.opt
|
||||||
- name: long ${{ matrix.test-type }} gem5_library_example_tests
|
- name: long ${{ matrix.test-type }} gem5_library_example_tests
|
||||||
working-directory: ${{ github.workspace }}/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
|
run: ./main.py run --uid SuiteUID:tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py:test-${{ matrix.test-type }} --length=long
|
||||||
- name: create zip of results
|
--skip-build -vv
|
||||||
if: success() || failure()
|
- name: create zip of results
|
||||||
run: |
|
if: success() || failure()
|
||||||
apt-get -y install zip
|
run: |
|
||||||
zip -r output.zip tests/testing-results
|
apt-get -y install zip
|
||||||
- name: upload zip
|
zip -r output.zip tests/testing-results
|
||||||
if: success() || failure()
|
- name: upload zip
|
||||||
uses: actions/upload-artifact@v3
|
if: success() || failure()
|
||||||
env:
|
uses: actions/upload-artifact@v3
|
||||||
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
env:
|
||||||
with:
|
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
||||||
name: ${{ env.MY_STEP_VAR }}
|
with:
|
||||||
path: output.zip
|
name: ${{ env.MY_STEP_VAR }}
|
||||||
retention-days: 7
|
path: output.zip
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
retention-days: 7
|
||||||
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
# This runs the SST-gem5 integration compilation and tests it with
|
# This runs the SST-gem5 integration compilation and tests it with
|
||||||
# ext/sst/sst/example.py.
|
# ext/sst/sst/example.py.
|
||||||
sst-test:
|
sst-test:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/sst-env:latest
|
container: gcr.io/gem5-test/sst-env:latest
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Build RISCV/libgem5_opt.so with SST
|
- name: Build RISCV/libgem5_opt.so with SST
|
||||||
run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc)
|
run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc)
|
||||||
- name: Compile ext/sst
|
- name: Compile ext/sst
|
||||||
working-directory: ${{ github.workspace }}/ext/sst
|
working-directory: ${{ github.workspace }}/ext/sst
|
||||||
run: make -j $(nproc)
|
run: make -j $(nproc)
|
||||||
- name: Run SST test
|
- name: Run SST test
|
||||||
working-directory: ${{ github.workspace }}/ext/sst
|
working-directory: ${{ github.workspace }}/ext/sst
|
||||||
run: sst --add-lib-path=./ sst/example.py
|
run: sst --add-lib-path=./ sst/example.py
|
||||||
|
|
||||||
# This runs the gem5 within SystemC ingration and runs a simple hello-world
|
# This runs the gem5 within SystemC ingration and runs a simple hello-world
|
||||||
# simulation with it.
|
# simulation with it.
|
||||||
systemc-test:
|
systemc-test:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/systemc-env:latest
|
container: gcr.io/gem5-test/systemc-env:latest
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Build ARM/gem5.opt
|
- name: Build ARM/gem5.opt
|
||||||
run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc)
|
run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc)
|
||||||
- name: Build ARM/libgem5_opt.so
|
- 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
|
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
|
- name: Compile gem5 withing SystemC
|
||||||
working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc
|
working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc
|
||||||
run: make
|
run: make
|
||||||
- name: Run gem5 within SystemC test
|
- 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
|
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
|
- 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
|
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.
|
# Runs the gem5 Nighyly GPU tests.
|
||||||
gpu-tests:
|
gpu-tests:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/gcn-gpu:latest
|
container: gcr.io/gem5-test/gcn-gpu:latest
|
||||||
timeout-minutes: 720 # 12 hours
|
timeout-minutes: 720 # 12 hours
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Compile build/GCN3_X86/gem5.opt
|
- name: Compile build/GCN3_X86/gem5.opt
|
||||||
run: scons build/GCN3_X86/gem5.opt -j $(nproc)
|
run: scons build/GCN3_X86/gem5.opt -j $(nproc)
|
||||||
- name: Get Square test-prog from gem5-resources
|
- name: Get Square test-prog from gem5-resources
|
||||||
uses: wei/wget@v1
|
uses: wei/wget@v1
|
||||||
with:
|
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
|
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)
|
- name: Run Square test with GCN3_X86/gem5.opt (SE mode)
|
||||||
run: |
|
run: |
|
||||||
mkdir -p tests/testing-results
|
mkdir -p tests/testing-results
|
||||||
./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square
|
./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square
|
||||||
- name: Get allSyncPrims-1kernel from gem5-resources
|
- name: Get allSyncPrims-1kernel from gem5-resources
|
||||||
uses: wei/wget@v1
|
uses: wei/wget@v1
|
||||||
with:
|
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
|
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)
|
- 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"
|
run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="sleepMutex 10 16
|
||||||
- name: Run allSyncPrims-1kernel lfTreeBarrUsing test with GCN3_X86/gem5.opt (SE mode)
|
4"
|
||||||
run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="lfTreeBarrUniq 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"
|
||||||
|
|||||||
79
.github/workflows/docker-build.yaml
vendored
79
.github/workflows/docker-build.yaml
vendored
@@ -1,53 +1,54 @@
|
|||||||
|
---
|
||||||
name: Docker images build and push
|
name: Docker images build and push
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
obtain-dockerfiles:
|
obtain-dockerfiles:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: dockerfiles
|
name: dockerfiles
|
||||||
path: util/dockerfiles
|
path: util/dockerfiles
|
||||||
|
|
||||||
# This builds and pushes the docker image.
|
# This builds and pushes the docker image.
|
||||||
build-and-push:
|
build-and-push:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
needs: obtain-dockerfiles
|
needs: obtain-dockerfiles
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: dockerfiles
|
name: dockerfiles
|
||||||
path: dockerfiles-docker-build
|
path: dockerfiles-docker-build
|
||||||
|
|
||||||
- uses: docker/setup-qemu-action@v2
|
- uses: docker/setup-qemu-action@v2
|
||||||
name: Setup QEMU
|
name: Setup QEMU
|
||||||
|
|
||||||
- uses: docker/setup-buildx-action@v2
|
- uses: docker/setup-buildx-action@v2
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
|
|
||||||
- uses: docker/login-action@v2
|
- uses: docker/login-action@v2
|
||||||
name: Login to the GitHub Container Registry
|
name: Login to the GitHub Container Registry
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push with bake
|
- name: Build and push with bake
|
||||||
uses: docker/bake-action@v4
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
workdir: ./dockerfiles-docker-build
|
workdir: ./dockerfiles-docker-build
|
||||||
files: docker-bake.hcl
|
files: docker-bake.hcl
|
||||||
push: true
|
push: true
|
||||||
|
|||||||
93
.github/workflows/gpu-tests.yaml
vendored
93
.github/workflows/gpu-tests.yaml
vendored
@@ -1,60 +1,61 @@
|
|||||||
|
---
|
||||||
# This workflow runs all of the very-long tests within main.py
|
# This workflow runs all of the very-long tests within main.py
|
||||||
|
|
||||||
name: Weekly Tests
|
name: Weekly Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Runs every Sunday from 7AM UTC
|
# Runs every Sunday from 7AM UTC
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '00 7 * * 6'
|
- cron: 00 7 * * 6
|
||||||
# Allows us to manually start workflow for testing
|
# Allows us to manually start workflow for testing
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-gem5:
|
build-gem5:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/gcn-gpu:latest
|
container: gcr.io/gem5-test/gcn-gpu:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Build gem5
|
- name: Build gem5
|
||||||
run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style
|
run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3
|
name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3
|
||||||
path: build/GCN3_X86/gem5.opt
|
path: build/GCN3_X86/gem5.opt
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
HACC-tests:
|
HACC-tests:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/gcn-gpu:latest
|
container: gcr.io/gem5-test/gcn-gpu:latest
|
||||||
needs: build-gem5
|
needs: build-gem5
|
||||||
timeout-minutes: 120 # 2 hours
|
timeout-minutes: 120 # 2 hours
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3
|
name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3
|
||||||
path: build/GCN3_X86
|
path: build/GCN3_X86
|
||||||
- run: chmod u+x build/GCN3_X86/gem5.opt
|
- run: chmod u+x build/GCN3_X86/gem5.opt
|
||||||
- name: make hip directory
|
- name: make hip directory
|
||||||
run: mkdir hip
|
run: mkdir hip
|
||||||
- name: Compile m5ops and x86
|
- name: Compile m5ops and x86
|
||||||
working-directory: ${{ github.workspace }}/util/m5
|
working-directory: ${{ github.workspace }}/util/m5
|
||||||
run: |
|
run: |
|
||||||
export TERM=xterm-256color
|
export TERM=xterm-256color
|
||||||
scons build/x86/out/m5
|
scons build/x86/out/m5
|
||||||
- name: Download tests
|
- name: Download tests
|
||||||
working-directory: ${{ github.workspace }}/hip
|
working-directory: ${{ github.workspace }}/hip
|
||||||
run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest
|
run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest
|
||||||
- name: Run HACC tests
|
- name: Run HACC tests
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: |
|
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"
|
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"
|
||||||
|
|||||||
26
.github/workflows/utils.yaml
vendored
26
.github/workflows/utils.yaml
vendored
@@ -1,19 +1,21 @@
|
|||||||
|
---
|
||||||
# This workflow file contains miscellaneous tasks to manage the repository.
|
# This workflow file contains miscellaneous tasks to manage the repository.
|
||||||
name: Utils for Repository
|
name: Utils for Repository
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '30 1 * * *'
|
- cron: 30 1 * * *
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# This job runs the stale action to close issues that have been inactive for 30 days.
|
# 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.
|
# It is scheduled to run every day at 1:30 AM UTC.
|
||||||
close-stale-issues:
|
close-stale-issues:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v8.0.0
|
- uses: actions/stale@v8.0.0
|
||||||
with:
|
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.'
|
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,
|
||||||
days-before-stale: 21
|
please open a new issue and reference this one.
|
||||||
days-before-close: 7
|
days-before-stale: 21
|
||||||
any-of-labels: 'needs details'
|
days-before-close: 7
|
||||||
|
any-of-labels: needs details
|
||||||
|
|||||||
174
.github/workflows/weekly-tests.yaml
vendored
174
.github/workflows/weekly-tests.yaml
vendored
@@ -1,110 +1,108 @@
|
|||||||
|
---
|
||||||
# This workflow runs all of the very-long tests within main.py
|
# This workflow runs all of the very-long tests within main.py
|
||||||
|
|
||||||
name: Weekly Tests
|
name: Weekly Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Runs every Sunday from 7AM UTC
|
# Runs every Sunday from 7AM UTC
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '00 7 * * 6'
|
- cron: 00 7 * * 6
|
||||||
# Allows us to manually start workflow for testing
|
# Allows us to manually start workflow for testing
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-gem5:
|
build-gem5:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
outputs:
|
outputs:
|
||||||
build-name: ${{ steps.artifact-name.outputs.name }}
|
build-name: ${{ steps.artifact-name.outputs.name }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- id: artifact-name
|
- id: artifact-name
|
||||||
run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT
|
run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT
|
||||||
- name: Build gem5
|
- name: Build gem5
|
||||||
run: |
|
run: |
|
||||||
scons build/ALL/gem5.opt -j $(nproc)
|
scons build/ALL/gem5.opt -j $(nproc)
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.artifact-name.outputs.name }}
|
name: ${{ steps.artifact-name.outputs.name }}
|
||||||
path: build/ALL/gem5.opt
|
path: build/ALL/gem5.opt
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
# start running the very-long tests
|
# start running the very-long tests
|
||||||
testlib-very-long-tests:
|
testlib-very-long-tests:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests]
|
test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests]
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
needs: [build-gem5]
|
needs: [build-gem5]
|
||||||
timeout-minutes: 4320 # 3 days
|
timeout-minutes: 4320 # 3 days
|
||||||
steps:
|
steps:
|
||||||
- name: Clean runner
|
- name: Clean runner
|
||||||
run:
|
run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true
|
||||||
rm -rf ./* || true
|
- uses: actions/checkout@v3
|
||||||
rm -rf ./.??* || true
|
with:
|
||||||
rm -rf ~/.cache || true
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{needs.build-gem5.outputs.build-name}}
|
name: ${{needs.build-gem5.outputs.build-name}}
|
||||||
path: build/ALL
|
path: build/ALL
|
||||||
- run: chmod u+x build/ALL/gem5.opt
|
- run: chmod u+x build/ALL/gem5.opt
|
||||||
- name: very-long ${{ matrix.test-type }}
|
- name: very-long ${{ matrix.test-type }}
|
||||||
working-directory: ${{ github.workspace }}/tests
|
working-directory: ${{ github.workspace }}/tests
|
||||||
run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc)
|
run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc)
|
||||||
- name: create zip of results
|
- name: create zip of results
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
run: |
|
run: |
|
||||||
apt-get -y install zip
|
apt-get -y install zip
|
||||||
zip -r output.zip tests/testing-results
|
zip -r output.zip tests/testing-results
|
||||||
- name: upload zip
|
- name: upload zip
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
env:
|
env:
|
||||||
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}}
|
||||||
with:
|
with:
|
||||||
name: ${{ env.MY_STEP_VAR }}
|
name: ${{ env.MY_STEP_VAR }}
|
||||||
path: output.zip
|
path: output.zip
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
- run: echo "This job's status is ${{ job.status }}."
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
dramsys-tests:
|
dramsys-tests:
|
||||||
runs-on: [self-hosted, linux, x64]
|
runs-on: [self-hosted, linux, x64]
|
||||||
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest
|
||||||
timeout-minutes: 4320 # 3 days
|
timeout-minutes: 4320 # 3 days
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Scheduled workflows run on the default branch by default. We
|
# Scheduled workflows run on the default branch by default. We
|
||||||
# therefore need to explicitly checkout the develop branch.
|
# therefore need to explicitly checkout the develop branch.
|
||||||
ref: develop
|
ref: develop
|
||||||
|
|
||||||
- name: Checkout DRAMSys
|
- name: Checkout DRAMSys
|
||||||
working-directory: ${{ github.workspace }}/ext/dramsys
|
working-directory: ${{ github.workspace }}/ext/dramsys
|
||||||
run: |
|
run: |
|
||||||
git clone https://github.com/tukl-msd/DRAMSys DRAMSys
|
git clone https://github.com/tukl-msd/DRAMSys DRAMSys
|
||||||
cd DRAMSys
|
cd DRAMSys
|
||||||
git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f
|
git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
|
|
||||||
# gem5 is built separately because it depends on the DRAMSys library
|
# gem5 is built separately because it depends on the DRAMSys library
|
||||||
- name: Build gem5
|
- name: Build gem5
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: scons build/ALL/gem5.opt -j $(nproc)
|
run: scons build/ALL/gem5.opt -j $(nproc)
|
||||||
|
|
||||||
- name: Run DRAMSys Checks
|
- name: Run DRAMSys Checks
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: |
|
run: |
|
||||||
./build/ALL/gem5.opt configs/example/gem5_library/dramsys/arm-hello-dramsys.py
|
./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/gem5_library/dramsys/dramsys-traffic.py
|
||||||
./build/ALL/gem5.opt configs/example/dramsys.py
|
./build/ALL/gem5.opt configs/example/dramsys.py
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# Copyright (c) 2022 Arm Limited
|
# Copyright (c) 2022 Arm Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
@@ -33,57 +34,61 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# 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:
|
default_language_version:
|
||||||
python: python3
|
python: python3
|
||||||
|
|
||||||
exclude: |
|
exclude: |
|
||||||
(?x)^(
|
(?x)^(
|
||||||
ext/(?!testlib/).*|
|
ext/(?!testlib/).*|
|
||||||
build/.*|
|
build/.*|
|
||||||
src/systemc/ext/.*|
|
src/systemc/ext/.*|
|
||||||
src/systemc/tests/.*/.*|
|
src/systemc/tests/.*/.*|
|
||||||
src/python/m5/ext/pyfdt/.*|
|
src/python/m5/ext/pyfdt/.*|
|
||||||
tests/.*/ref/.*
|
tests/.*/ref/.*
|
||||||
)$
|
)$
|
||||||
|
|
||||||
default_stages: [commit]
|
default_stages: [commit]
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v4.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: check-json
|
- id: check-json
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- id: mixed-line-ending
|
- id: mixed-line-ending
|
||||||
args: [--fix=lf]
|
args: [--fix=lf]
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
|
||||||
rev: 22.6.0
|
rev: 0.2.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: yamlfmt
|
||||||
- repo: local
|
- repo: https://github.com/psf/black
|
||||||
hooks:
|
rev: 22.6.0
|
||||||
- id: gem5-style-checker
|
hooks:
|
||||||
name: gem5 style checker
|
- id: black
|
||||||
entry: util/git-pre-commit.py
|
- repo: local
|
||||||
always_run: true
|
hooks:
|
||||||
exclude: ".*"
|
- id: gem5-style-checker
|
||||||
language: system
|
name: gem5 style checker
|
||||||
description: 'The gem5 style checker hook.'
|
entry: util/git-pre-commit.py
|
||||||
- id: gem5-commit-msg-checker
|
always_run: true
|
||||||
name: gem5 commit msg checker
|
exclude: .*
|
||||||
entry: ext/git-commit-msg
|
language: system
|
||||||
language: system
|
description: The gem5 style checker hook.
|
||||||
stages: [commit-msg]
|
- id: gem5-commit-msg-checker
|
||||||
description: 'The gem5 commit message checker hook.'
|
name: gem5 commit msg checker
|
||||||
- id: gerrit-commit-msg-job
|
entry: ext/git-commit-msg
|
||||||
name: gerrit commit message job
|
language: system
|
||||||
entry: util/gerrit-commit-msg-hook
|
stages: [commit-msg]
|
||||||
language: system
|
description: The gem5 commit message checker hook.
|
||||||
stages: [commit-msg]
|
- id: gerrit-commit-msg-job
|
||||||
description: 'Adds Change-ID to the commit message. Needed by Gerrit.'
|
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.
|
||||||
|
|||||||
299
MAINTAINERS.yaml
299
MAINTAINERS.yaml
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
# See CONTRIBUTING.md for details of gem5's contribution process.
|
# See CONTRIBUTING.md for details of gem5's contribution process.
|
||||||
#
|
#
|
||||||
# This file contains a list of gem5's subsystems and their
|
# This file contains a list of gem5's subsystems and their
|
||||||
@@ -40,246 +41,246 @@
|
|||||||
# targeting that subsystem.
|
# targeting that subsystem.
|
||||||
|
|
||||||
arch:
|
arch:
|
||||||
desc: >-
|
desc: >-
|
||||||
General architecture-specific components
|
General architecture-specific components
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
arch-arm:
|
arch-arm:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
arch-gcn3:
|
arch-gcn3:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Sinclair <sinclair@cs.wisc.edu>
|
- Matt Sinclair <sinclair@cs.wisc.edu>
|
||||||
- Matt Porema <matthew.porema@amd.com>
|
- Matt Porema <matthew.porema@amd.com>
|
||||||
|
|
||||||
arch-vega:
|
arch-vega:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Sinclair <sinclair@cs.wisc.edu>
|
- Matt Sinclair <sinclair@cs.wisc.edu>
|
||||||
- Matt Porema <matthew.porema@amd.com>
|
- Matt Porema <matthew.porema@amd.com>
|
||||||
|
|
||||||
arch-mips:
|
arch-mips:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
arch-power:
|
arch-power:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
arch-riscv:
|
arch-riscv:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
arch-sparc:
|
arch-sparc:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
arch-x86:
|
arch-x86:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
base:
|
base:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
base-stats:
|
base-stats:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
configs:
|
configs:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
cpu:
|
cpu:
|
||||||
desc: >-
|
desc: >-
|
||||||
General changes to all CPU models (e.g., BaseCPU)
|
General changes to all CPU models (e.g., BaseCPU)
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
cpu-kvm:
|
cpu-kvm:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
cpu-minor:
|
cpu-minor:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
cpu-o3:
|
cpu-o3:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
cpu-simple:
|
cpu-simple:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
dev-hsa:
|
dev-hsa:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Poremba <matthew.poremba@amd.com>
|
- Matt Poremba <matthew.poremba@amd.com>
|
||||||
|
|
||||||
dev-amdgpu:
|
dev-amdgpu:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Poremba <matthew.poremba@amd.com>
|
- Matt Poremba <matthew.poremba@amd.com>
|
||||||
|
|
||||||
dev-virtio:
|
dev-virtio:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
dev-arm:
|
dev-arm:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
ext:
|
ext:
|
||||||
desc: >-
|
desc: >-
|
||||||
Components external to gem5
|
Components external to gem5
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
ext-testlib:
|
ext-testlib:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
|
|
||||||
fastmodel:
|
fastmodel:
|
||||||
desc: >-
|
desc: >-
|
||||||
Changes relating to ARM Fast Models
|
Changes relating to ARM Fast Models
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
gpu-compute:
|
gpu-compute:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Poremba <matthew.poremba@amd.com>
|
- Matt Poremba <matthew.poremba@amd.com>
|
||||||
|
|
||||||
learning-gem5:
|
learning-gem5:
|
||||||
desc: >-
|
desc: >-
|
||||||
The code and configs for the Learning gem5 book
|
The code and configs for the Learning gem5 book
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
|
|
||||||
stdlib:
|
stdlib:
|
||||||
desc: >-
|
desc: >-
|
||||||
The gem5 standard library found under `src/python/gem5`
|
The gem5 standard library found under `src/python/gem5`
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
|
|
||||||
mem:
|
mem:
|
||||||
desc: >-
|
desc: >-
|
||||||
General memory system (e.g., XBar, Packet)
|
General memory system (e.g., XBar, Packet)
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
mem-cache:
|
mem-cache:
|
||||||
desc: >-
|
desc: >-
|
||||||
Classic caches and coherence
|
Classic caches and coherence
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
mem-dram:
|
mem-dram:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
mem-garnet:
|
mem-garnet:
|
||||||
desc: >-
|
desc: >-
|
||||||
Garnet subcomponent of Ruby
|
Garnet subcomponent of Ruby
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
mem-ruby:
|
mem-ruby:
|
||||||
desc: >-
|
desc: >-
|
||||||
Ruby structures and protocols
|
Ruby structures and protocols
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Matt Sinclair <sinclair@cs.wisc.edu>
|
- Matt Sinclair <sinclair@cs.wisc.edu>
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
misc:
|
misc:
|
||||||
desc: >-
|
desc: >-
|
||||||
Anything outside of the other categories
|
Anything outside of the other categories
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
python:
|
python:
|
||||||
desc: >-
|
desc: >-
|
||||||
Python SimObject wrapping and infrastructure
|
Python SimObject wrapping and infrastructure
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
desc: >-
|
desc: >-
|
||||||
The gem5-resources repo with auxiliary resources for simulation
|
The gem5-resources repo with auxiliary resources for simulation
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
scons:
|
scons:
|
||||||
desc: >-
|
desc: >-
|
||||||
Build system
|
Build system
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
sim:
|
sim:
|
||||||
desc: >-
|
desc: >-
|
||||||
General simulation components
|
General simulation components
|
||||||
status: orphaned
|
status: orphaned
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|
||||||
sim-se:
|
sim-se:
|
||||||
desc: >-
|
desc: >-
|
||||||
Syscall emulation
|
Syscall emulation
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
system-arm:
|
system-arm:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
- Giacomo Travaglini <giacomo.travaglini@arm.com>
|
||||||
- Andreas Sandberg <andreas.sandberg@arm.com>
|
- Andreas Sandberg <andreas.sandberg@arm.com>
|
||||||
|
|
||||||
systemc:
|
systemc:
|
||||||
desc: >-
|
desc: >-
|
||||||
Code for the gem5 SystemC implementation and interface
|
Code for the gem5 SystemC implementation and interface
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
desc: >-
|
desc: >-
|
||||||
testing changes
|
testing changes
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
|
|
||||||
util:
|
util:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
util-docker:
|
util-docker:
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
|
|
||||||
util-m5:
|
util-m5:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
util-gem5art:
|
util-gem5art:
|
||||||
status: orphaned
|
status: orphaned
|
||||||
|
|
||||||
website:
|
website:
|
||||||
desc: >-
|
desc: >-
|
||||||
The gem5-website repo which contains the gem5.org site
|
The gem5-website repo which contains the gem5.org site
|
||||||
status: maintained
|
status: maintained
|
||||||
maintainers:
|
maintainers:
|
||||||
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
- Bobby R. Bruce <bbruce@ucdavis.edu>
|
||||||
experts:
|
experts:
|
||||||
- Jason Lowe-Power <jason@lowepower.com>
|
- Jason Lowe-Power <jason@lowepower.com>
|
||||||
|
|||||||
@@ -1679,7 +1679,13 @@ class HPI_MMU(ArmMMU):
|
|||||||
dtb = ArmTLB(entry_type="data", size=256)
|
dtb = ArmTLB(entry_type="data", size=256)
|
||||||
|
|
||||||
|
|
||||||
|
class HPI_BTB(SimpleBTB):
|
||||||
|
numEntries = 128
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
class HPI_BP(TournamentBP):
|
class HPI_BP(TournamentBP):
|
||||||
|
btb = HPI_BTB()
|
||||||
localPredictorSize = 64
|
localPredictorSize = 64
|
||||||
localCtrBits = 2
|
localCtrBits = 2
|
||||||
localHistoryTableSize = 64
|
localHistoryTableSize = 64
|
||||||
@@ -1687,8 +1693,6 @@ class HPI_BP(TournamentBP):
|
|||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 1024
|
choicePredictorSize = 1024
|
||||||
choiceCtrBits = 2
|
choiceCtrBits = 2
|
||||||
BTBEntries = 128
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 8
|
RASSize = 8
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
58
configs/common/cores/arm/O3_ARM_Etrace.py
Normal file
58
configs/common/cores/arm/O3_ARM_Etrace.py
Normal file
@@ -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,
|
||||||
|
)
|
||||||
@@ -107,14 +107,18 @@ class O3_ARM_v7a_FUP(FUPool):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class O3_ARM_v7a_BTB(SimpleBTB):
|
||||||
|
numEntries = 2048
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
# Bi-Mode Branch Predictor
|
# Bi-Mode Branch Predictor
|
||||||
class O3_ARM_v7a_BP(BiModeBP):
|
class O3_ARM_v7a_BP(BiModeBP):
|
||||||
|
btb = O3_ARM_v7a_BTB()
|
||||||
globalPredictorSize = 8192
|
globalPredictorSize = 8192
|
||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 8192
|
choicePredictorSize = 8192
|
||||||
choiceCtrBits = 2
|
choiceCtrBits = 2
|
||||||
BTBEntries = 2048
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 16
|
RASSize = 16
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
@@ -104,14 +104,18 @@ class ex5_big_FUP(FUPool):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ex5_big_BTB(SimpleBTB):
|
||||||
|
numEntries = 4096
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
# Bi-Mode Branch Predictor
|
# Bi-Mode Branch Predictor
|
||||||
class ex5_big_BP(BiModeBP):
|
class ex5_big_BP(BiModeBP):
|
||||||
|
btb = ex5_big_BTB()
|
||||||
globalPredictorSize = 4096
|
globalPredictorSize = 4096
|
||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 1024
|
choicePredictorSize = 1024
|
||||||
choiceCtrBits = 3
|
choiceCtrBits = 3
|
||||||
BTBEntries = 4096
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 48
|
RASSize = 48
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
@@ -338,56 +338,15 @@ class FastmodelCluster(CpuCluster):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BaseSimpleSystem(ArmSystem):
|
class ClusterSystem:
|
||||||
cache_line_size = 64
|
"""
|
||||||
|
Base class providing cpu clusters generation/handling methods to
|
||||||
def __init__(self, mem_size, platform, **kwargs):
|
SE/FS systems
|
||||||
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)))
|
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
self._clusters = []
|
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):
|
def numCpuClusters(self):
|
||||||
return len(self._clusters)
|
return len(self._clusters)
|
||||||
|
|
||||||
@@ -423,6 +382,80 @@ class BaseSimpleSystem(ArmSystem):
|
|||||||
cluster.connectMemSide(cluster_mem_bus)
|
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):
|
class SimpleSystem(BaseSimpleSystem):
|
||||||
"""
|
"""
|
||||||
Meant to be used with the classic memory model
|
Meant to be used with the classic memory model
|
||||||
|
|||||||
191
configs/example/arm/etrace_se.py
Normal file
191
configs/example/arm/etrace_se.py
Normal file
@@ -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()
|
||||||
@@ -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):
|
def get_processes(cmd):
|
||||||
"""Interprets commands to run and returns a list of processes"""
|
"""Interprets commands to run and returns a list of processes"""
|
||||||
|
|
||||||
@@ -150,7 +84,31 @@ def get_processes(cmd):
|
|||||||
def create(args):
|
def create(args):
|
||||||
"""Create and configure the system object."""
|
"""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
|
# Tell components about the expected physical memory ranges. This
|
||||||
# is, for example, used by the MemConfig helper to determine where
|
# is, for example, used by the MemConfig helper to determine where
|
||||||
@@ -160,6 +118,9 @@ def create(args):
|
|||||||
# Configure the off-chip memory system.
|
# Configure the off-chip memory system.
|
||||||
MemConfig.config_mem(args, 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
|
# Parse the command line and get a list of Processes instances
|
||||||
# that we can pass to gem5.
|
# that we can pass to gem5.
|
||||||
processes = get_processes(args.commands_to_run)
|
processes = get_processes(args.commands_to_run)
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ board.set_se_simpoint_workload(
|
|||||||
)
|
)
|
||||||
|
|
||||||
dir = Path(args.checkpoint_path)
|
dir = Path(args.checkpoint_path)
|
||||||
dir.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
simulator = Simulator(
|
simulator = Simulator(
|
||||||
board=board,
|
board=board,
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ class cmdScheduler {
|
|||||||
std::string name;
|
std::string name;
|
||||||
physicalAddr PhysicalAddr;
|
physicalAddr PhysicalAddr;
|
||||||
// sorting the commands according to their scheduling time.
|
// sorting the commands according to their scheduling time.
|
||||||
struct commandItemSorter : public std::binary_function<commandItem&,
|
struct commandItemSorter {
|
||||||
commandItem&, bool>{
|
|
||||||
bool operator()(const commandItem& lhs,
|
bool operator()(const commandItem& lhs,
|
||||||
const commandItem& rhs) const
|
const commandItem& rhs) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class PCState : public GenericISA::UPCState<4>
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void
|
void
|
||||||
set(Addr val)
|
set(Addr val) override
|
||||||
{
|
{
|
||||||
Base::set(val);
|
Base::set(val);
|
||||||
npc(val + (thumb() ? 2 : 4));
|
npc(val + (thumb() ? 2 : 4));
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ class DelaySlotPCState : public SimplePCState<InstWidth>
|
|||||||
void nnpc(Addr val) { _nnpc = val; }
|
void nnpc(Addr val) { _nnpc = val; }
|
||||||
|
|
||||||
void
|
void
|
||||||
set(Addr val)
|
set(Addr val) override
|
||||||
{
|
{
|
||||||
Base::set(val);
|
Base::set(val);
|
||||||
nnpc(val + 2 * InstWidth);
|
nnpc(val + 2 * InstWidth);
|
||||||
@@ -563,7 +563,7 @@ class DelaySlotUPCState : public DelaySlotPCState<InstWidth>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set(Addr val)
|
set(Addr val) override
|
||||||
{
|
{
|
||||||
Base::set(val);
|
Base::set(val);
|
||||||
this->upc(0);
|
this->upc(0);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class PCState : public GenericISA::UPCState<8>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set(Addr val)
|
set(Addr val) override
|
||||||
{
|
{
|
||||||
Base::set(val);
|
Base::set(val);
|
||||||
_size = 0;
|
_size = 0;
|
||||||
|
|||||||
@@ -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) 2012 Mark D. Hill and David A. Wood
|
||||||
# Copyright (c) 2015 The University of Wisconsin
|
# Copyright (c) 2015 The University of Wisconsin
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
@@ -25,10 +37,46 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# 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.params import *
|
||||||
from m5.proxy 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):
|
class IndirectPredictor(SimObject):
|
||||||
type = "IndirectPredictor"
|
type = "IndirectPredictor"
|
||||||
@@ -63,11 +111,12 @@ class BranchPredictor(SimObject):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
|
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")
|
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(
|
indirectBranchPred = Param.IndirectPredictor(
|
||||||
SimpleIndirectPredictor(),
|
SimpleIndirectPredictor(),
|
||||||
"Indirect branch predictor, set to NULL to disable indirect predictions",
|
"Indirect branch predictor, set to NULL to disable indirect predictions",
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# -*- mode:python -*-
|
# -*- 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
|
# Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
@@ -28,8 +40,12 @@
|
|||||||
|
|
||||||
Import('*')
|
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',
|
'LocalBP', 'TournamentBP', 'BiModeBP', 'TAGEBase', 'TAGE', 'LoopPredictor',
|
||||||
'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB',
|
'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB',
|
||||||
'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L',
|
'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L',
|
||||||
@@ -41,17 +57,16 @@ SimObject('BranchPredictor.py', sim_objects=[
|
|||||||
'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB',
|
'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB',
|
||||||
'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB',
|
'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB',
|
||||||
'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB',
|
'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB',
|
||||||
'MultiperspectivePerceptronTAGE8KB'])
|
'MultiperspectivePerceptronTAGE8KB'],
|
||||||
|
enums=['BranchType'])
|
||||||
|
|
||||||
DebugFlag('Indirect')
|
|
||||||
Source('bpred_unit.cc')
|
Source('bpred_unit.cc')
|
||||||
Source('2bit_local.cc')
|
Source('2bit_local.cc')
|
||||||
Source('btb.cc')
|
|
||||||
Source('simple_indirect.cc')
|
Source('simple_indirect.cc')
|
||||||
Source('indirect.cc')
|
Source('indirect.cc')
|
||||||
Source('ras.cc')
|
Source('ras.cc')
|
||||||
Source('tournament.cc')
|
Source('tournament.cc')
|
||||||
Source ('bi_mode.cc')
|
Source('bi_mode.cc')
|
||||||
Source('tage_base.cc')
|
Source('tage_base.cc')
|
||||||
Source('tage.cc')
|
Source('tage.cc')
|
||||||
Source('loop_predictor.cc')
|
Source('loop_predictor.cc')
|
||||||
@@ -66,6 +81,10 @@ Source('statistical_corrector.cc')
|
|||||||
Source('tage_sc_l.cc')
|
Source('tage_sc_l.cc')
|
||||||
Source('tage_sc_l_8KB.cc')
|
Source('tage_sc_l_8KB.cc')
|
||||||
Source('tage_sc_l_64KB.cc')
|
Source('tage_sc_l_64KB.cc')
|
||||||
|
Source('btb.cc')
|
||||||
|
Source('simple_btb.cc')
|
||||||
|
DebugFlag('Indirect')
|
||||||
|
DebugFlag('BTB')
|
||||||
DebugFlag('FreeList')
|
DebugFlag('FreeList')
|
||||||
DebugFlag('Branch')
|
DebugFlag('Branch')
|
||||||
DebugFlag('Tage')
|
DebugFlag('Tage')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2012, 2014 ARM Limited
|
* 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
|
* Copyright (c) 2012 Mark D. Hill and David A. Wood
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
@@ -59,10 +59,7 @@ BPredUnit::BPredUnit(const Params ¶ms)
|
|||||||
: SimObject(params),
|
: SimObject(params),
|
||||||
numThreads(params.numThreads),
|
numThreads(params.numThreads),
|
||||||
predHist(numThreads),
|
predHist(numThreads),
|
||||||
BTB(params.BTBEntries,
|
btb(params.btb),
|
||||||
params.BTBTagSize,
|
|
||||||
params.instShiftAmt,
|
|
||||||
params.numThreads),
|
|
||||||
RAS(numThreads),
|
RAS(numThreads),
|
||||||
iPred(params.indirectBranchPred),
|
iPred(params.indirectBranchPred),
|
||||||
stats(this),
|
stats(this),
|
||||||
@@ -218,10 +215,13 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
|
|||||||
if (inst->isDirectCtrl() || !iPred) {
|
if (inst->isDirectCtrl() || !iPred) {
|
||||||
++stats.BTBLookups;
|
++stats.BTBLookups;
|
||||||
// Check BTB on direct branches
|
// 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;
|
++stats.BTBHits;
|
||||||
// If it's not a return, use the BTB to get target addr.
|
// 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,
|
DPRINTF(Branch,
|
||||||
"[tid:%i] [sn:%llu] Instruction %s predicted "
|
"[tid:%i] [sn:%llu] Instruction %s predicted "
|
||||||
"target is %s\n",
|
"target is %s\n",
|
||||||
@@ -482,7 +482,8 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
|
|||||||
hist_it->seqNum, hist_it->pc);
|
hist_it->seqNum, hist_it->pc);
|
||||||
|
|
||||||
++stats.BTBUpdates;
|
++stats.BTBUpdates;
|
||||||
BTB.update(hist_it->pc, corr_target, tid);
|
btb->update(tid, hist_it->pc, corr_target,
|
||||||
|
getBranchType(hist_it->inst));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Actually not Taken
|
//Actually not Taken
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2012, 2014 ARM Limited
|
* 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
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
#include "cpu/pred/branch_type.hh"
|
||||||
#include "cpu/pred/btb.hh"
|
#include "cpu/pred/btb.hh"
|
||||||
#include "cpu/pred/indirect.hh"
|
#include "cpu/pred/indirect.hh"
|
||||||
#include "cpu/pred/ras.hh"
|
#include "cpu/pred/ras.hh"
|
||||||
@@ -152,7 +153,14 @@ class BPredUnit : public SimObject
|
|||||||
* @param inst_PC The PC to look up.
|
* @param inst_PC The PC to look up.
|
||||||
* @return Whether the BTB contains the given PC.
|
* @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
|
* 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.
|
* @return The address of the target of the branch.
|
||||||
*/
|
*/
|
||||||
const PCStateBase *
|
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.
|
* @param target_PC The branch's target that will be added to the BTB.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BTBUpdate(Addr instPC, const PCStateBase &target)
|
BTBUpdate(ThreadID tid, Addr instPC, const PCStateBase &target)
|
||||||
{
|
{
|
||||||
++stats.BTBUpdates;
|
++stats.BTBUpdates;
|
||||||
BTB.update(instPC, target, 0);
|
return btb->update(tid, instPC, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -295,7 +303,7 @@ class BPredUnit : public SimObject
|
|||||||
std::vector<History> predHist;
|
std::vector<History> predHist;
|
||||||
|
|
||||||
/** The BTB. */
|
/** The BTB. */
|
||||||
DefaultBTB BTB;
|
BranchTargetBuffer* btb;
|
||||||
|
|
||||||
/** The per-thread return address stack. */
|
/** The per-thread return address stack. */
|
||||||
std::vector<ReturnAddrStack> RAS;
|
std::vector<ReturnAddrStack> RAS;
|
||||||
|
|||||||
91
src/cpu/pred/branch_type.hh
Normal file
91
src/cpu/pred/branch_type.hh
Normal file
@@ -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__
|
||||||
@@ -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
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -28,119 +40,59 @@
|
|||||||
|
|
||||||
#include "cpu/pred/btb.hh"
|
#include "cpu/pred/btb.hh"
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
|
||||||
#include "base/trace.hh"
|
|
||||||
#include "debug/Fetch.hh"
|
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace branch_prediction
|
namespace branch_prediction
|
||||||
{
|
{
|
||||||
|
|
||||||
DefaultBTB::DefaultBTB(unsigned _numEntries,
|
BranchTargetBuffer::BranchTargetBuffer(const Params ¶ms)
|
||||||
unsigned _tagBits,
|
: ClockedObject(params),
|
||||||
unsigned _instShiftAmt,
|
numThreads(params.numThreads),
|
||||||
unsigned _num_threads)
|
stats(this)
|
||||||
: numEntries(_numEntries),
|
|
||||||
tagBits(_tagBits),
|
|
||||||
instShiftAmt(_instShiftAmt),
|
|
||||||
log2NumThreads(floorLog2(_num_threads))
|
|
||||||
{
|
{
|
||||||
DPRINTF(Fetch, "BTB: Creating BTB object.\n");
|
}
|
||||||
|
|
||||||
if (!isPowerOf2(numEntries)) {
|
BranchTargetBuffer::BranchTargetBufferStats::BranchTargetBufferStats(
|
||||||
fatal("BTB entries is not a power of 2!");
|
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
|
} // namespace branch_prediction
|
||||||
|
|||||||
@@ -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
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -29,9 +41,13 @@
|
|||||||
#ifndef __CPU_PRED_BTB_HH__
|
#ifndef __CPU_PRED_BTB_HH__
|
||||||
#define __CPU_PRED_BTB_HH__
|
#define __CPU_PRED_BTB_HH__
|
||||||
|
|
||||||
|
|
||||||
#include "arch/generic/pcstate.hh"
|
#include "arch/generic/pcstate.hh"
|
||||||
#include "base/logging.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/types.hh"
|
#include "cpu/pred/branch_type.hh"
|
||||||
|
#include "cpu/static_inst.hh"
|
||||||
|
#include "params/BranchTargetBuffer.hh"
|
||||||
|
#include "sim/clocked_object.hh"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
@@ -39,93 +55,73 @@ namespace gem5
|
|||||||
namespace branch_prediction
|
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<PCStateBase> target;
|
|
||||||
|
|
||||||
/** The entry's thread id. */
|
|
||||||
ThreadID tid;
|
|
||||||
|
|
||||||
/** Whether or not the entry is valid. */
|
|
||||||
bool valid = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Creates a BTB with the given number of entries, number of bits per
|
typedef BranchTargetBufferParams Params;
|
||||||
* tag, and instruction offset amount.
|
typedef enums::BranchType BranchType;
|
||||||
* @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);
|
|
||||||
|
|
||||||
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 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.
|
* @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.
|
/** Updates the BTB with the target of a branch.
|
||||||
* @param inst_pc The address of the branch being updated.
|
* @param inst_pc The address of the branch being updated.
|
||||||
* @param target_pc The target address of the branch.
|
* @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:
|
/** Update BTB statistics
|
||||||
/** 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);
|
virtual void incorrectTarget(Addr inst_pc,
|
||||||
|
BranchType type = BranchType::NoBranch)
|
||||||
|
{
|
||||||
|
stats.mispredict[type]++;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the tag bits of a given address.
|
protected:
|
||||||
* @param inst_PC The branch's address.
|
/** Number of the threads for which the branch history is maintained. */
|
||||||
* @return Returns the tag bits.
|
const unsigned numThreads;
|
||||||
*/
|
|
||||||
inline Addr getTag(Addr instPC);
|
|
||||||
|
|
||||||
/** The actual BTB. */
|
struct BranchTargetBufferStats : public statistics::Group
|
||||||
std::vector<BTBEntry> btb;
|
{
|
||||||
|
BranchTargetBufferStats(statistics::Group *parent);
|
||||||
|
|
||||||
/** The number of entries in the BTB. */
|
statistics::Vector lookups;
|
||||||
unsigned numEntries;
|
statistics::Vector misses;
|
||||||
|
statistics::Vector updates;
|
||||||
|
statistics::Vector mispredict;
|
||||||
|
statistics::Scalar evictions;
|
||||||
|
|
||||||
/** The index mask. */
|
} stats;
|
||||||
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 branch_prediction
|
||||||
|
|||||||
176
src/cpu/pred/simple_btb.cc
Normal file
176
src/cpu/pred/simple_btb.cc
Normal file
@@ -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
|
||||||
136
src/cpu/pred/simple_btb.hh
Normal file
136
src/cpu/pred/simple_btb.hh
Normal file
@@ -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<PCStateBase> 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<BTBEntry> 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__
|
||||||
@@ -39,6 +39,7 @@ SimObject('AMDGPU.py', sim_objects=['AMDGPUDevice', 'AMDGPUInterruptHandler',
|
|||||||
tags='x86 isa')
|
tags='x86 isa')
|
||||||
|
|
||||||
Source('amdgpu_device.cc', 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_nbio.cc', tags='x86 isa')
|
||||||
Source('amdgpu_vm.cc', tags='x86 isa')
|
Source('amdgpu_vm.cc', tags='x86 isa')
|
||||||
Source('interrupt_handler.cc', tags='x86 isa')
|
Source('interrupt_handler.cc', tags='x86 isa')
|
||||||
|
|||||||
@@ -379,6 +379,9 @@ AMDGPUDevice::readMMIO(PacketPtr pkt, Addr offset)
|
|||||||
case GRBM_BASE:
|
case GRBM_BASE:
|
||||||
gpuvm.readMMIO(pkt, aperture_offset >> GRBM_OFFSET_SHIFT);
|
gpuvm.readMMIO(pkt, aperture_offset >> GRBM_OFFSET_SHIFT);
|
||||||
break;
|
break;
|
||||||
|
case GFX_BASE:
|
||||||
|
gfx.readMMIO(pkt, aperture_offset);
|
||||||
|
break;
|
||||||
case MMHUB_BASE:
|
case MMHUB_BASE:
|
||||||
gpuvm.readMMIO(pkt, aperture_offset >> MMHUB_OFFSET_SHIFT);
|
gpuvm.readMMIO(pkt, aperture_offset >> MMHUB_OFFSET_SHIFT);
|
||||||
break;
|
break;
|
||||||
@@ -507,6 +510,9 @@ AMDGPUDevice::writeMMIO(PacketPtr pkt, Addr offset)
|
|||||||
case NBIO_BASE:
|
case NBIO_BASE:
|
||||||
nbio.writeMMIO(pkt, aperture_offset);
|
nbio.writeMMIO(pkt, aperture_offset);
|
||||||
break;
|
break;
|
||||||
|
case GFX_BASE:
|
||||||
|
gfx.writeMMIO(pkt, aperture_offset);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF(AMDGPUDevice, "Unknown MMIO aperture for %#x\n", offset);
|
DPRINTF(AMDGPUDevice, "Unknown MMIO aperture for %#x\n", offset);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "base/bitunion.hh"
|
#include "base/bitunion.hh"
|
||||||
#include "dev/amdgpu/amdgpu_defines.hh"
|
#include "dev/amdgpu/amdgpu_defines.hh"
|
||||||
|
#include "dev/amdgpu/amdgpu_gfx.hh"
|
||||||
#include "dev/amdgpu/amdgpu_nbio.hh"
|
#include "dev/amdgpu/amdgpu_nbio.hh"
|
||||||
#include "dev/amdgpu/amdgpu_vm.hh"
|
#include "dev/amdgpu/amdgpu_vm.hh"
|
||||||
#include "dev/amdgpu/memory_manager.hh"
|
#include "dev/amdgpu/memory_manager.hh"
|
||||||
@@ -109,6 +110,7 @@ class AMDGPUDevice : public PciDevice
|
|||||||
* Blocks of the GPU
|
* Blocks of the GPU
|
||||||
*/
|
*/
|
||||||
AMDGPUNbio nbio;
|
AMDGPUNbio nbio;
|
||||||
|
AMDGPUGfx gfx;
|
||||||
AMDGPUMemoryManager *gpuMemMgr;
|
AMDGPUMemoryManager *gpuMemMgr;
|
||||||
AMDGPUInterruptHandler *deviceIH;
|
AMDGPUInterruptHandler *deviceIH;
|
||||||
AMDGPUVM gpuvm;
|
AMDGPUVM gpuvm;
|
||||||
|
|||||||
73
src/dev/amdgpu/amdgpu_gfx.cc
Normal file
73
src/dev/amdgpu/amdgpu_gfx.cc
Normal file
@@ -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<uint32_t>(captured_clock_count);
|
||||||
|
break;
|
||||||
|
case AMDGPU_MM_RLC_GPU_CLOCK_COUNT_MSB:
|
||||||
|
pkt->setLE<uint32_t>(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
|
||||||
75
src/dev/amdgpu/amdgpu_gfx.hh
Normal file
75
src/dev/amdgpu/amdgpu_gfx.hh
Normal file
@@ -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__
|
||||||
@@ -69,6 +69,12 @@ typedef struct amd_signal_s
|
|||||||
uint32_t reserved3[2];
|
uint32_t reserved3[2];
|
||||||
} amd_signal_t;
|
} amd_signal_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t start_ts;
|
||||||
|
uint64_t end_ts;
|
||||||
|
} amd_event_t;
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
#endif // DEV_HSA_HSA_SIGNAL_H
|
#endif // DEV_HSA_HSA_SIGNAL_H
|
||||||
|
|||||||
@@ -248,6 +248,10 @@ GPUCommandProcessor::submitDispatchPkt(void *raw_pkt, uint32_t queue_id,
|
|||||||
|
|
||||||
initABI(task);
|
initABI(task);
|
||||||
++dynamic_task_id;
|
++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
|
void
|
||||||
@@ -280,16 +284,6 @@ GPUCommandProcessor::sendCompletionSignal(Addr signal_handle)
|
|||||||
void
|
void
|
||||||
GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff)
|
GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff)
|
||||||
{
|
{
|
||||||
Addr value_addr = getHsaSignalValueAddr(signal_handle);
|
|
||||||
|
|
||||||
uint64_t *signalValue = new uint64_t;
|
|
||||||
auto cb = new DmaVirtCallback<uint64_t>(
|
|
||||||
[ = ] (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);
|
Addr mailbox_addr = getHsaSignalMailboxAddr(signal_handle);
|
||||||
uint64_t *mailboxValue = new uint64_t;
|
uint64_t *mailboxValue = new uint64_t;
|
||||||
auto cb2 = new DmaVirtCallback<uint64_t>(
|
auto cb2 = new DmaVirtCallback<uint64_t>(
|
||||||
@@ -300,20 +294,6 @@ GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff)
|
|||||||
mailbox_addr);
|
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<uint64_t>(
|
|
||||||
[ = ] (const uint64_t &)
|
|
||||||
{ updateHsaSignalDone(prev_value); });
|
|
||||||
dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle,
|
GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle,
|
||||||
uint64_t *mailbox_value)
|
uint64_t *mailbox_value)
|
||||||
@@ -331,6 +311,20 @@ GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle,
|
|||||||
dmaReadVirt(event_addr, sizeof(uint64_t), cb, (void *)mailbox_value);
|
dmaReadVirt(event_addr, sizeof(uint64_t), cb, (void *)mailbox_value);
|
||||||
} else {
|
} else {
|
||||||
delete mailbox_value;
|
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<uint64_t>(
|
||||||
|
[ = ] (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 &)
|
[ = ] (const uint64_t &)
|
||||||
{ updateHsaSignalDone(event_value); }, *event_value);
|
{ updateHsaSignalDone(event_value); }, *event_value);
|
||||||
dmaWriteVirt(mailbox_addr, sizeof(uint64_t), cb, &cb->dmaBuffer, 0);
|
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<uint64_t>(
|
||||||
|
[ = ] (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<uint64_t>(
|
||||||
|
[ = ] (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<uint64_t>(
|
||||||
|
[ = ] (const uint64_t &)
|
||||||
|
{ updateHsaSignalDone(prev_value); });
|
||||||
|
dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class GPUCommandProcessor : public DmaVirtDevice
|
|||||||
void updateHsaSignalDone(uint64_t *signal_value);
|
void updateHsaSignalDone(uint64_t *signal_value);
|
||||||
void updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value);
|
void updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value);
|
||||||
void updateHsaEventData(Addr signal_handle, uint64_t *event_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);
|
uint64_t functionalReadHsaSignal(Addr signal_handle);
|
||||||
|
|
||||||
@@ -148,6 +149,9 @@ class GPUCommandProcessor : public DmaVirtDevice
|
|||||||
HSAPacketProcessor *hsaPP;
|
HSAPacketProcessor *hsaPP;
|
||||||
TranslationGenPtr translate(Addr vaddr, Addr size) override;
|
TranslationGenPtr translate(Addr vaddr, Addr size) override;
|
||||||
|
|
||||||
|
// Keep track of start times for task dispatches.
|
||||||
|
std::unordered_map<Addr, Tick> dispatchStartTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a DMA read of the read_dispatch_id_field_base_byte_offset
|
* Perform a DMA read of the read_dispatch_id_field_base_byte_offset
|
||||||
* field, which follows directly after the read_dispatch_id (the read
|
* field, which follows directly after the read_dispatch_id (the read
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload):
|
|||||||
"lpj=19988480",
|
"lpj=19988480",
|
||||||
"norandmaps",
|
"norandmaps",
|
||||||
"root={root_value}",
|
"root={root_value}",
|
||||||
|
"disk_device={disk_device}",
|
||||||
"rw",
|
"rw",
|
||||||
f"mem={self.get_memory().get_size()}",
|
f"mem={self.get_memory().get_size()}",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -534,14 +534,19 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
fdt.writeDtsFile(os.path.join(outdir, "device.dts"))
|
fdt.writeDtsFile(os.path.join(outdir, "device.dts"))
|
||||||
fdt.writeDtbFile(os.path.join(outdir, "device.dtb"))
|
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)
|
@overrides(KernelDiskWorkload)
|
||||||
def get_disk_device(self) -> str:
|
def get_disk_device(self) -> str:
|
||||||
return "/dev/lda"
|
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)
|
@overrides(KernelDiskWorkload)
|
||||||
def _add_disk_to_board(self, disk_image: AbstractResource) -> None:
|
def _add_disk_to_board(self, disk_image: AbstractResource) -> None:
|
||||||
# Note: This must be called after set_workload because it looks for an
|
# Note: This must be called after set_workload because it looks for an
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class KernelDiskWorkload:
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_disk_device(self) -> str:
|
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.
|
:returns: The disk device.
|
||||||
"""
|
"""
|
||||||
@@ -139,6 +139,7 @@ class KernelDiskWorkload:
|
|||||||
kernel: KernelResource,
|
kernel: KernelResource,
|
||||||
disk_image: DiskImageResource,
|
disk_image: DiskImageResource,
|
||||||
bootloader: Optional[BootloaderResource] = None,
|
bootloader: Optional[BootloaderResource] = None,
|
||||||
|
disk_device: Optional[str] = None,
|
||||||
readfile: Optional[str] = None,
|
readfile: Optional[str] = None,
|
||||||
readfile_contents: Optional[str] = None,
|
readfile_contents: Optional[str] = None,
|
||||||
kernel_args: Optional[List[str]] = None,
|
kernel_args: Optional[List[str]] = None,
|
||||||
@@ -171,6 +172,9 @@ class KernelDiskWorkload:
|
|||||||
# Abstract board. This function will not work otherwise.
|
# Abstract board. This function will not work otherwise.
|
||||||
assert isinstance(self, AbstractBoard)
|
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
|
# If we are setting a workload of this type, we need to run as a
|
||||||
# full-system simulation.
|
# full-system simulation.
|
||||||
self._set_fullsystem(True)
|
self._set_fullsystem(True)
|
||||||
@@ -182,7 +186,12 @@ class KernelDiskWorkload:
|
|||||||
self.workload.command_line = (
|
self.workload.command_line = (
|
||||||
" ".join(kernel_args or self.get_default_kernel_args())
|
" ".join(kernel_args or self.get_default_kernel_args())
|
||||||
).format(
|
).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
|
# Setting the bootloader information for ARM board. The current
|
||||||
|
|||||||
@@ -494,4 +494,9 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
|
|
||||||
@overrides(KernelDiskWorkload)
|
@overrides(KernelDiskWorkload)
|
||||||
def get_default_kernel_args(self) -> List[str]:
|
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",
|
||||||
|
]
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ class SEBinaryWorkload:
|
|||||||
"""Set up the system to run a specific binary.
|
"""Set up the system to run a specific binary.
|
||||||
|
|
||||||
**Limitations**
|
**Limitations**
|
||||||
* Only supports single threaded applications.
|
|
||||||
* Dynamically linked executables are partially supported when the host
|
* Dynamically linked executables are partially supported when the host
|
||||||
ISA and the simulated ISA are the same.
|
ISA and the simulated ISA are the same.
|
||||||
|
|
||||||
|
|||||||
@@ -318,4 +318,5 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
"console=ttyS0",
|
"console=ttyS0",
|
||||||
"lpj=7999923",
|
"lpj=7999923",
|
||||||
"root={root_value}",
|
"root={root_value}",
|
||||||
|
"disk_device={disk_device}",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -566,7 +566,12 @@ class RISCVMatchedBoard(
|
|||||||
|
|
||||||
@overrides(KernelDiskWorkload)
|
@overrides(KernelDiskWorkload)
|
||||||
def get_default_kernel_args(self) -> List[str]:
|
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)
|
@overrides(KernelDiskWorkload)
|
||||||
def set_kernel_disk_workload(
|
def set_kernel_disk_workload(
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class U74FUPool(MinorFUPool):
|
|||||||
|
|
||||||
|
|
||||||
class U74BP(TournamentBP):
|
class U74BP(TournamentBP):
|
||||||
BTBEntries = 32
|
btb = SimpleBTB(numEntries=32)
|
||||||
RASSize = 12
|
RASSize = 12
|
||||||
localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2
|
localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2
|
||||||
localPredictorSize = 16384
|
localPredictorSize = 16384
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
---
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|||||||
Reference in New Issue
Block a user