From d34295359878d130e4ed86e0cce5b08651173cd4 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Sat, 12 Sep 2026 12:02:37 +0800
Subject: [PATCH 01/36] feat: support P2E bank difftest
---
.../privatepath/PrivateMemBackend.scala | 20 +++++++++----------
bbdev | 2 +-
bebop | 2 +-
examples/balls/smatmul/emu/src/smatmul.rs | 14 +++----------
4 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
index bb5aea19..39009d85 100644
--- a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
@@ -105,15 +105,6 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
}
}
- def getFreePbankId(): UInt = {
- val hasFree = mappingTable.map(_.valid === false.B).reduce(_ || _)
- when(!hasFree) {
- assert(false.B, "PrivateMemBackend allocation failed: no free physical bank\n")
- }
- val freePbankId = mappingTable.indexWhere(_.valid === false.B)
- freePbankId
- }
-
// -----------------------------------------------------------------------------
// Default Value
// -----------------------------------------------------------------------------
@@ -150,7 +141,14 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
bank.io.sramWrite.resp.ready := true.B
}
- io.config.ready := true.B
+ val realloc = io.config.bits.group_id === 0.U
+ val freePbankMask =
+ VecInit(mappingTable.map(entry => !entry.valid || (realloc && entry.vbank_id === io.config.bits.vbank_id)))
+ val hasFreePbank = freePbankMask.asUInt.orR
+ io.config.ready := !io.config.bits.alloc || hasFreePbank
+ when(io.config.valid && io.config.bits.alloc && !hasFreePbank) {
+ assert(false.B, "PrivateMemBackend allocation failed: no free physical bank\n")
+ }
// -----------------------------------------------------------------------------
// Bank Alloc/Release
@@ -160,7 +158,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val vbank = io.config.bits.vbank_id
val vbankIdx = vbank(privateVbankIdWidth - 1, 0)
when(io.config.bits.alloc) {
- val freePbank = getFreePbankId()
+ val freePbank = PriorityEncoder(freePbankMask)
// Match bemu mset: realloc of the same vbank frees prior physical banks first.
// MemConfiger emits one fire per group; only group 0 drops the old mapping.
when(io.config.bits.group_id === 0.U) {
diff --git a/bbdev b/bbdev
index bd0298c5..4f40306b 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit bd0298c50aa7daa2be03746859c54546c4caae73
+Subproject commit 4f40306b6fa8a98b5369bcadfd218bd152fac7b7
diff --git a/bebop b/bebop
index 490c9aa9..de876a89 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit 490c9aa942a9425727ab7db37eb67075ba234149
+Subproject commit de876a89bfe4c1ad29240b59e1ab26b8220948b7
diff --git a/examples/balls/smatmul/emu/src/smatmul.rs b/examples/balls/smatmul/emu/src/smatmul.rs
index 8be7f56f..2bde413b 100644
--- a/examples/balls/smatmul/emu/src/smatmul.rs
+++ b/examples/balls/smatmul/emu/src/smatmul.rs
@@ -31,11 +31,6 @@ fn read_i32(bank: &[u8], row: usize, lane: usize) -> i32 {
i32::from_le_bytes(bank[offset..offset + 4].try_into().unwrap())
}
-fn write_i32(bank: &mut [u8], row: usize, lane: usize, value: i32) {
- let offset = row * bank_row_bytes() + lane * 4;
- bank[offset..offset + 4].copy_from_slice(&value.to_le_bytes());
-}
-
pub(crate) fn exec_bias(xs1: u64, xs2: u64, ctx: &mut ExecContext) -> u64 {
let bank = rs1_b0(xs1);
let input_base = (xs2 & 0x3f) as usize;
@@ -178,12 +173,9 @@ pub(crate) fn exec_smatmul(xs1: u64, xs2: u64, ctx: &mut ExecContext) -> u64 {
let pc = pbank(ctx, c_bank);
for row in 0..rows {
for col in 0..cols {
- write_i32(
- &mut ctx.banks[pc],
- output_base + row * 4 + col / 4,
- col % 4,
- chain.accumulators[row * cols + col],
- );
+ let offset = (output_base + row * 4 + col / 4) * bank_row_bytes() + col % 4 * 4;
+ ctx.banks[pc][offset..offset + 4]
+ .copy_from_slice(&chain.accumulators[row * cols + col].to_le_bytes());
}
}
} else {
From d8815a849f5fb7b0b6f05584c2b1839acfdd7e61 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Sat, 12 Sep 2026 18:23:44 +0800
Subject: [PATCH 02/36] fix: adapt bank difftest to latest main
---
.../frontend/globalrs/GlobalROB.scala | 20 +++++++++++---
.../backend/shared/SharedMemBackend.scala | 26 ++++++++++---------
.../memdomain/frontend/mem/MemConfiger.scala | 11 +++++++-
bb-tests/workloads/scripts/build.py | 16 ++++++++++++
4 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index 656e1511..9fc3c10d 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -8,6 +8,7 @@ import framework.top.GlobalConfig
import framework.frontend.decoder.{DomainId, PostGDCmd}
import framework.frontend.scoreboard.{BankAccessInfo, BankAliasTable, BankScoreboard}
import framework.memdomain.frontend.cmd.decoder.DISA.MSET_BITPAT
+import framework.memdomain.backend.shared.SharedMemLayout
@instantiable
class GlobalROB(val b: GlobalConfig) extends Module {
@@ -85,7 +86,8 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val headPtr = RegInit(0.U(idWidth.W))
val tailPtr = RegInit(0.U(idWidth.W))
val issuedCount = RegInit(0.U(log2Up(robDepth + 1).W))
- val bankCols = RegInit(VecInit(Seq.fill(b.memDomain.virtualBankCount)(0.U(log2Up(b.memDomain.bankNum + 1).W))))
+ private val bankColWidth = log2Up(b.memDomain.bankNum + 1)
+ val bankCols = RegInit(VecInit(Seq.fill(b.memDomain.virtualBankCount)(0.U(bankColWidth.W))))
// In-flight ownership is tracked in the architectural vbank namespace.
private val vbankMaskWidth = b.memDomain.virtualBankCount
val vbankBusy = RegInit(0.U(vbankMaskWidth.W))
@@ -401,10 +403,20 @@ class GlobalROB(val b: GlobalConfig) extends Module {
commitMask(i) := hits.reduce(_ || _)
when(commitMask(i)) {
when(robEntries(i).cmd.domain_id === DomainId.MEM && robEntries(i).cmd.cmd.funct === MSET_BITPAT) {
- val bank = robEntries(i).cmd.bankAccess.wr_bank_id(b.memDomain.vbankIdWidth - 1, 0)
- val col = robEntries(i).cmd.cmd.rs2Data(9, 5)
+ val bankId = robEntries(i).cmd.bankAccess.wr_bank_id
+ val bank = bankId(b.memDomain.vbankIdWidth - 1, 0)
+ val col = robEntries(i).cmd.cmd.rs2Data(9, 5)
when(robEntries(i).cmd.cmd.rs2Data(10)) {
- bankCols(bank) := Mux(col === 0.U, b.memDomain.bankNum.U, col)
+ val fullCol = if (b.memDomain.sharedEnable) {
+ Mux(
+ bankId >= b.frontend.shared_bank_id_base.U && bankId < b.memDomain.virtualBankCount.U,
+ SharedMemLayout.totalBank(b).U(bankColWidth.W),
+ b.memDomain.bankNum.U(bankColWidth.W)
+ )
+ } else {
+ b.memDomain.bankNum.U(bankColWidth.W)
+ }
+ bankCols(bank) := Mux(col === 0.U, fullCol, col)
}.otherwise {
bankCols(bank) := 0.U
}
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
index 8e257005..1c78b64d 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
@@ -77,6 +77,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
): Unit = {
val duplicate = mappingTable.map(entry =>
entry.valid &&
+ !(group_id === 0.U && entry.hart_id === hart_id && entry.vbank_id === vbank_id) &&
(entry.hart_id === hart_id) &&
(entry.vbank_id === vbank_id) &&
(entry.group_id === group_id)
@@ -110,16 +111,6 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
}
}
- def getFreePbankId(): UInt = {
- val hasFree = mappingTable.map(_.valid === false.B).reduce(_ || _)
- when(!hasFree) {
- assert(false.B, "SharedMemBackend allocation failed: no free physical shared bank\n")
- }
-
- val freePbankId = mappingTable.indexWhere(_.valid === false.B)
- freePbankId
- }
-
// -----------------------------------------------------------------------------
// Default Value
// -----------------------------------------------------------------------------
@@ -156,7 +147,18 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
bank.io.sramWrite.resp.ready := true.B
}
- io.config.ready := true.B
+ val realloc = io.config.bits.group_id === 0.U
+
+ val freePbankMask = VecInit(mappingTable.map(entry =>
+ !entry.valid ||
+ (realloc && entry.hart_id === io.config.bits.hart_id && entry.vbank_id === io.config.bits.vbank_id)
+ ))
+
+ val hasFreePbank = freePbankMask.asUInt.orR
+ io.config.ready := !io.config.bits.alloc || hasFreePbank
+ when(io.config.valid && io.config.bits.alloc && !hasFreePbank) {
+ assert(false.B, "SharedMemBackend allocation failed: no free physical shared bank\n")
+ }
// -----------------------------------------------------------------------------
// Bank Alloc/Release
@@ -167,7 +169,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
when(io.config.bits.group_id === 0.U) {
clearVbank(io.config.bits.hart_id, io.config.bits.vbank_id)
}
- val pbankId = getFreePbankId()
+ val pbankId = PriorityEncoder(freePbankMask)
printf(
p"[SharedMemBackend][ALLOC] hart=${io.config.bits.hart_id} vbank=0x${Hexadecimal(io.config.bits.vbank_id)} " +
p"group=${io.config.bits.group_id} pbank=$pbankId is_multi=${io.config.bits.is_multi}\n"
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
index 9836ef49..5341435b 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._
import framework.top.GlobalConfig
import framework.balldomain.blink.BankWrite
+import framework.memdomain.backend.shared.SharedMemLayout
import framework.memdomain.frontend.cmd.rs.{MemRsComplete, MemRsIssue}
import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate}
@@ -78,7 +79,15 @@ class MemConfiger(val b: GlobalConfig) extends Module {
when(io.cmdReq.fire) {
val rawCol = io.cmdReq.bits.cmd.special(9, 5)
val alloc = io.cmdReq.bits.cmd.special(10)
- val fullCol = b.memDomain.bankNum.U(col_reg.getWidth.W)
+ val fullCol = if (b.memDomain.sharedEnable) {
+ Mux(
+ io.cmdReq.bits.cmd.is_shared,
+ SharedMemLayout.totalBank(b).U(col_reg.getWidth.W),
+ b.memDomain.bankNum.U(col_reg.getWidth.W)
+ )
+ } else {
+ b.memDomain.bankNum.U(col_reg.getWidth.W)
+ }
state := config
col_reg := Mux(alloc && rawCol === 0.U, fullCol, Mux(rawCol > 1.U, rawCol, 1.U))
diff --git a/bb-tests/workloads/scripts/build.py b/bb-tests/workloads/scripts/build.py
index 6129dc56..67c9fead 100644
--- a/bb-tests/workloads/scripts/build.py
+++ b/bb-tests/workloads/scripts/build.py
@@ -368,6 +368,22 @@ def build_workload(
logger=logger,
task_scope=task_scope,
)
+ _run(
+ [
+ "ninja",
+ "-C",
+ str(compiler_build),
+ f"-j{os.cpu_count() or 1}",
+ f"buckyball-compiler-{chip}",
+ "buddy-opt",
+ "frontend/Python/python-package-buddy",
+ ],
+ cwd=root,
+ env=env,
+ prefix="buddy python package",
+ logger=logger,
+ task_scope=task_scope,
+ )
ninja = ["ninja", "-C", str(build), f"-j{os.cpu_count() or 1}"]
if ninja_arg:
ninja.append(ninja_arg)
From 096cf13986d75d0c39b3e2af3a92ad9c1af96863 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:11:26 +0800
Subject: [PATCH 03/36] fix: clean CI workspace before checkout
---
.github/scripts/ci_repo_lock.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 78443d93..9a1f447e 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -24,9 +24,9 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
git fetch --force --prune origin "${want_sha}"
+ git clean -ffd
git checkout --detach "${want_sha}"
git reset --hard "${want_sha}"
- git clean -ffd
# rm -rf arch/out
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
From 284d85c08b4bde3b480963f9e7993b371349ba4d Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:13:00 +0800
Subject: [PATCH 04/36] fix: clean CI workspace before prepare
---
.github/workflows/check.yaml | 1 +
.github/workflows/regression.yml | 1 +
2 files changed, 2 insertions(+)
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index c4a2d06e..e2270bef 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -43,6 +43,7 @@ jobs:
set -euo pipefail
root=~/Code/buckyball
source "${root}/.github/scripts/setproxy.sh"
+ git -C "${root}" clean -ffd
bash "${root}/.github/scripts/ci_repo_lock.sh" \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index cc5c709b..61c29ee1 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -44,6 +44,7 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
+ git -C "${root}" clean -ffd
bash "${root}/.github/scripts/ci_repo_lock.sh" \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
From 6b4dee5d388b81bb46bfd0702efc59a6625cbd3a Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:14:44 +0800
Subject: [PATCH 05/36] fix: purge stale CI submodule worktrees
---
.github/scripts/ci_repo_lock.sh | 3 ++-
.github/workflows/check.yaml | 3 ++-
.github/workflows/regression.yml | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 9a1f447e..d5bd4837 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -24,7 +24,8 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
git fetch --force --prune origin "${want_sha}"
- git clean -ffd
+ git submodule deinit --all --force
+ git clean -ffdx
git checkout --detach "${want_sha}"
git reset --hard "${want_sha}"
# rm -rf arch/out
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index e2270bef..4384e71c 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -43,7 +43,8 @@ jobs:
set -euo pipefail
root=~/Code/buckyball
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" clean -ffd
+ git -C "${root}" submodule deinit --all --force
+ git -C "${root}" clean -ffdx
bash "${root}/.github/scripts/ci_repo_lock.sh" \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 61c29ee1..4817a997 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -44,7 +44,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" clean -ffd
+ git -C "${root}" submodule deinit --all --force
+ git -C "${root}" clean -ffdx
bash "${root}/.github/scripts/ci_repo_lock.sh" \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
From 70b4264d7641ca58aec40038013ca31fddbfddad Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:17:25 +0800
Subject: [PATCH 06/36] fix: execute CI reset script from target revision
---
.github/scripts/ci_repo_lock.sh | 5 ++---
.github/workflows/check.yaml | 5 ++---
.github/workflows/regression.yml | 5 ++---
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index d5bd4837..1fafa08e 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -24,10 +24,9 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
git fetch --force --prune origin "${want_sha}"
- git submodule deinit --all --force
- git clean -ffdx
- git checkout --detach "${want_sha}"
+ git checkout --detach --force "${want_sha}"
git reset --hard "${want_sha}"
+ git clean -ffd
# rm -rf arch/out
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index 4384e71c..e394d524 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -43,9 +43,8 @@ jobs:
set -euo pipefail
root=~/Code/buckyball
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" submodule deinit --all --force
- git -C "${root}" clean -ffdx
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Check pre-commit
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 4817a997..03cc69cc 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -44,9 +44,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" submodule deinit --all --force
- git -C "${root}" clean -ffdx
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Install config
From c596c1a1516ee67b32c6abb7a53cb06c966e2e72 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:18:57 +0800
Subject: [PATCH 07/36] fix: update only current CI submodules
---
.github/scripts/ci_repo_lock.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 1fafa08e..d937942f 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -31,7 +31,7 @@ repo_reset() {
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
git submodule sync
- git submodule update --init --force
+ git submodule update --init --force -- $(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)
for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
git -C "${repo}/${submodule}" reset --hard
git -C "${repo}/${submodule}" clean -ffd
From 8e10b2111356ead3b8f6cb6a501784e5c6e41a88 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:20:11 +0800
Subject: [PATCH 08/36] fix: reset CI parent before submodules
---
.github/scripts/ci_repo_lock.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index d937942f..cbe82e9d 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -24,8 +24,8 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
git fetch --force --prune origin "${want_sha}"
- git checkout --detach --force "${want_sha}"
- git reset --hard "${want_sha}"
+ git -c submodule.recurse=false checkout --detach --force "${want_sha}"
+ git -c submodule.recurse=false reset --hard "${want_sha}"
git clean -ffd
# rm -rf arch/out
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
From c3e2bef999daa697082a8b3c40f9680f273cac18 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:21:38 +0800
Subject: [PATCH 09/36] fix: derive CI submodules from target tree
---
.github/scripts/ci_repo_lock.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index cbe82e9d..4e7e8a96 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -31,7 +31,7 @@ repo_reset() {
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
git submodule sync
- git submodule update --init --force -- $(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)
+ git submodule update --init --force -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
git -C "${repo}/${submodule}" reset --hard
git -C "${repo}/${submodule}" clean -ffd
From b39220631afe5098fd26a5267bf912de18a233c2 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:22:55 +0800
Subject: [PATCH 10/36] fix: disable recursive fetch in CI reset
---
.github/scripts/ci_repo_lock.sh | 2 +-
.github/workflows/check.yaml | 2 +-
.github/workflows/regression.yml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 4e7e8a96..fee8fa76 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -23,7 +23,7 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
- git fetch --force --prune origin "${want_sha}"
+ git fetch --force --prune --no-recurse-submodules origin "${want_sha}"
git -c submodule.recurse=false checkout --detach --force "${want_sha}"
git -c submodule.recurse=false reset --hard "${want_sha}"
git clean -ffd
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index e394d524..119a288d 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -43,7 +43,7 @@ jobs:
set -euo pipefail
root=~/Code/buckyball
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune origin "${CHECKOUT_SHA}"
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 03cc69cc..b289d637 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -44,7 +44,7 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune origin "${CHECKOUT_SHA}"
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
From 2139aae541567ac45435830dc5ea3cc46cc121ae Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:25:49 +0800
Subject: [PATCH 11/36] fix: provision clean CI runtime
---
.github/workflows/check.yaml | 2 ++
.github/workflows/regression.yml | 2 ++
2 files changed, 4 insertions(+)
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index 119a288d..54b8db57 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -46,6 +46,8 @@ jobs:
git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
+ cd "${root}"
+ nix build
- name: Check pre-commit
shell: zsh {0}
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index b289d637..ec21ead0 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -47,6 +47,8 @@ jobs:
git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
+ cd "${root}"
+ nix build
- name: Install config
shell: zsh {0}
From 4ff7a1e9da6f66755938f431a591fb4401f37e0d Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 15:40:03 +0800
Subject: [PATCH 12/36] fix: make clean CI setup reproducible
---
.github/workflows/check.yaml | 4 ++++
.github/workflows/regression.yml | 4 ++++
.../framework/frontend/globalrs/GlobalROB.scala | 17 +++++++++--------
.../backend/shared/SharedMemBackend.scala | 4 ++--
.../memdomain/frontend/mem/MemConfiger.scala | 17 +++++++++--------
sourceme.sh | 1 +
6 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index 54b8db57..d879339b 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -48,6 +48,10 @@ jobs:
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
cd "${root}"
nix build
+ cd "${root}/bbdev"
+ nix develop -c true
+ cd "${root}/bebop"
+ nix develop -c true
- name: Check pre-commit
shell: zsh {0}
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index ec21ead0..0a26ec7d 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -49,6 +49,10 @@ jobs:
prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
cd "${root}"
nix build
+ cd "${root}/bbdev"
+ nix develop -c true
+ cd "${root}/bebop"
+ nix develop -c true
- name: Install config
shell: zsh {0}
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index 9fc3c10d..da586879 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -407,15 +407,16 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val bank = bankId(b.memDomain.vbankIdWidth - 1, 0)
val col = robEntries(i).cmd.cmd.rs2Data(9, 5)
when(robEntries(i).cmd.cmd.rs2Data(10)) {
- val fullCol = if (b.memDomain.sharedEnable) {
- Mux(
- bankId >= b.frontend.shared_bank_id_base.U && bankId < b.memDomain.virtualBankCount.U,
- SharedMemLayout.totalBank(b).U(bankColWidth.W),
+ val fullCol =
+ if (b.memDomain.sharedEnable) {
+ Mux(
+ bankId >= b.frontend.shared_bank_id_base.U && bankId < b.memDomain.virtualBankCount.U,
+ SharedMemLayout.totalBank(b).U(bankColWidth.W),
+ b.memDomain.bankNum.U(bankColWidth.W)
+ )
+ } else {
b.memDomain.bankNum.U(bankColWidth.W)
- )
- } else {
- b.memDomain.bankNum.U(bankColWidth.W)
- }
+ }
bankCols(bank) := Mux(col === 0.U, fullCol, col)
}.otherwise {
bankCols(bank) := 0.U
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
index 1c78b64d..d5e4b068 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
@@ -147,14 +147,14 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
bank.io.sramWrite.resp.ready := true.B
}
- val realloc = io.config.bits.group_id === 0.U
+ val realloc = io.config.bits.group_id === 0.U
val freePbankMask = VecInit(mappingTable.map(entry =>
!entry.valid ||
(realloc && entry.hart_id === io.config.bits.hart_id && entry.vbank_id === io.config.bits.vbank_id)
))
- val hasFreePbank = freePbankMask.asUInt.orR
+ val hasFreePbank = freePbankMask.asUInt.orR
io.config.ready := !io.config.bits.alloc || hasFreePbank
when(io.config.valid && io.config.bits.alloc && !hasFreePbank) {
assert(false.B, "SharedMemBackend allocation failed: no free physical shared bank\n")
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
index 5341435b..b3109be6 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
@@ -79,15 +79,16 @@ class MemConfiger(val b: GlobalConfig) extends Module {
when(io.cmdReq.fire) {
val rawCol = io.cmdReq.bits.cmd.special(9, 5)
val alloc = io.cmdReq.bits.cmd.special(10)
- val fullCol = if (b.memDomain.sharedEnable) {
- Mux(
- io.cmdReq.bits.cmd.is_shared,
- SharedMemLayout.totalBank(b).U(col_reg.getWidth.W),
+ val fullCol =
+ if (b.memDomain.sharedEnable) {
+ Mux(
+ io.cmdReq.bits.cmd.is_shared,
+ SharedMemLayout.totalBank(b).U(col_reg.getWidth.W),
+ b.memDomain.bankNum.U(col_reg.getWidth.W)
+ )
+ } else {
b.memDomain.bankNum.U(col_reg.getWidth.W)
- )
- } else {
- b.memDomain.bankNum.U(col_reg.getWidth.W)
- }
+ }
state := config
col_reg := Mux(alloc && rawCol === 0.U, fullCol, Mux(rawCol > 1.U, rawCol, 1.U))
diff --git a/sourceme.sh b/sourceme.sh
index 83fd3d30..6c6e1f4c 100644
--- a/sourceme.sh
+++ b/sourceme.sh
@@ -50,6 +50,7 @@ export PATH="${RESULT_PATH}/bin:${PATH}"
# bbdev CLI and Python utils
export PATH="${BBDIR}/bbdev:${PATH}"
export PYTHONPATH="${BBDIR}/bbdev/api:${PYTHONPATH}"
+export PYTHONPATH="${BBDIR}/thirdparty/soc-framework/ip:${PYTHONPATH}"
# firesim manager
From 555abca34a5108565731b69eb78921246d455d4d Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 16:19:46 +0800
Subject: [PATCH 13/36] fix: initialize nested submodules for regression builds
---
.github/scripts/ci_repo_lock.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index fee8fa76..3aa3dd3d 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -31,7 +31,7 @@ repo_reset() {
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
git submodule sync
- git submodule update --init --force -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
+ git submodule update --init --force --recursive -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
git -C "${repo}/${submodule}" reset --hard
git -C "${repo}/${submodule}" clean -ffd
From 098040a762518a290ef32294bc6ad3ee61242abb Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 16:33:25 +0800
Subject: [PATCH 14/36] fix: initialize only required nested submodule
---
.github/scripts/ci_repo_lock.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 3aa3dd3d..d180e8b9 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -31,7 +31,8 @@ repo_reset() {
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
git submodule sync
- git submodule update --init --force --recursive -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
+ git submodule update --init --force -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
+ git submodule update --init --force -- compiler/thirdparty/buddy-mlir/llvm
for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
git -C "${repo}/${submodule}" reset --hard
git -C "${repo}/${submodule}" clean -ffd
From 455a59447c91aa31d02f4a8702ebb1e7a7835254 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Mon, 14 Sep 2026 16:35:49 +0800
Subject: [PATCH 15/36] fix: update nested submodule from its repository
---
.github/scripts/ci_repo_lock.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index d180e8b9..45ab9bc1 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -32,7 +32,8 @@ repo_reset() {
rm -rf compiler/thirdparty/buddy-mlir/build
git submodule sync
git submodule update --init --force -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
- git submodule update --init --force -- compiler/thirdparty/buddy-mlir/llvm
+ git -C compiler/thirdparty/buddy-mlir submodule sync
+ git -C compiler/thirdparty/buddy-mlir submodule update --init --force -- llvm
for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
git -C "${repo}/${submodule}" reset --hard
git -C "${repo}/${submodule}" clean -ffd
From 58bb59b54323b371ef9deacf633fe5823610e001 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Tue, 15 Sep 2026 16:09:17 +0800
Subject: [PATCH 16/36] Fix poly Verilator CI regression
---
.../main/scala/framework/balldomain/blink/bank.scala | 2 +-
.../framework/balldomain/decoder/BallDecodeCmd.scala | 8 ++++----
.../balldomain/decoder/BallDomainDecoder.scala | 3 ++-
.../framework/balldomain/rs/reservationStation.scala | 6 +++---
.../framework/frontend/decoder/GobalDecoder.scala | 6 +++---
.../scala/framework/frontend/globalrs/GlobalROB.scala | 2 +-
.../src/main/scala/framework/memdomain/MemDomain.scala | 2 +-
.../scala/framework/memdomain/backend/MemBackend.scala | 4 ++--
.../framework/memdomain/backend/MemBackendTypes.scala | 2 +-
.../framework/memdomain/backend/accpipe/AccPipe.scala | 4 ++--
.../backend/privatepath/PrivateMemBackend.scala | 6 +++---
.../framework/memdomain/backend/shared/SharedMem.scala | 4 ++--
.../memdomain/backend/shared/SharedMemBackend.scala | 4 ++--
.../framework/memdomain/configs/MemDomainParam.scala | 3 +++
.../framework/memdomain/frontend/MemFrontend.scala | 2 +-
.../framework/memdomain/frontend/mem/MemConfiger.scala | 10 +++++-----
.../framework/memdomain/frontend/mem/MemLoader.scala | 8 ++++----
.../framework/memdomain/frontend/mem/MemStorer.scala | 8 ++++----
.../system/core/accelerator/BuckyballAccelerator.scala | 2 +-
.../src/main/scala/sims/verilator/TargetConfigs.scala | 8 ++++++--
.../poly/regression/batch/verilator/workloads-elf.toml | 4 ++++
.../vecmat16_atranspose_16x16-main.cpp | 3 +++
22 files changed, 58 insertions(+), 43 deletions(-)
create mode 100644 examples/chips/poly/regression/batch/verilator/workloads-elf.toml
diff --git a/arch/src/main/scala/framework/balldomain/blink/bank.scala b/arch/src/main/scala/framework/balldomain/blink/bank.scala
index 65f1dd55..8bfedeaf 100644
--- a/arch/src/main/scala/framework/balldomain/blink/bank.scala
+++ b/arch/src/main/scala/framework/balldomain/blink/bank.scala
@@ -23,7 +23,7 @@ trait HasBallId {
trait HasAccGroupId {
val b: GlobalConfig
- val group_id = Input(UInt(log2Up(b.memDomain.bankNum).W))
+ val group_id = Input(UInt(b.memDomain.groupIdWidth.W))
}
class BankRead(val b: GlobalConfig) extends Bundle with HasBankId with HasRobId with HasBallId with HasAccGroupId {
diff --git a/arch/src/main/scala/framework/balldomain/decoder/BallDecodeCmd.scala b/arch/src/main/scala/framework/balldomain/decoder/BallDecodeCmd.scala
index 6519643b..e34e6f58 100644
--- a/arch/src/main/scala/framework/balldomain/decoder/BallDecodeCmd.scala
+++ b/arch/src/main/scala/framework/balldomain/decoder/BallDecodeCmd.scala
@@ -8,7 +8,7 @@ import chisel3.util._
* and framework infrastructure (BallReservationStation, BBus). The
* concrete decode logic (funct7 → BID/operands) lives in user code.
*/
-class BallDecodeCmd(numBanks: Int, iterLen: Int) extends Bundle {
+class BallDecodeCmd(numBanks: Int, iterLen: Int, groupCountWidth: Int) extends Bundle {
val bid = UInt(5.W)
val funct7 = UInt(7.W)
val iter = UInt(iterLen.W)
@@ -23,9 +23,9 @@ class BallDecodeCmd(numBanks: Int, iterLen: Int) extends Bundle {
val op1_bank = UInt(log2Up(numBanks).W)
val op2_bank = UInt(log2Up(numBanks).W)
val wr_bank = UInt(log2Up(numBanks).W)
- val op1_col = UInt(5.W)
- val op2_col = UInt(5.W)
- val wr_col = UInt(5.W)
+ val op1_col = UInt(groupCountWidth.W)
+ val op2_col = UInt(groupCountWidth.W)
+ val wr_col = UInt(groupCountWidth.W)
// MMIO metadata bank: which main bank's MMIO region to access
val meta_bank = UInt(log2Up(numBanks).W)
diff --git a/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala b/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
index e195bd7c..eef7ba14 100644
--- a/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
+++ b/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
@@ -24,7 +24,8 @@ class BallDomainDecoder(val b: GlobalConfig) extends Module {
@public
val cmd_i = IO(Flipped(Decoupled(new PostGDCmd(b))))
@public
- val ball_decode_cmd_o = IO(Decoupled(new BallDecodeCmd(b.memDomain.virtualBankCount, iterLen)))
+ val ball_decode_cmd_o =
+ IO(Decoupled(new BallDecodeCmd(b.memDomain.virtualBankCount, iterLen, b.memDomain.groupCountWidth)))
cmd_i.ready := ball_decode_cmd_o.ready
diff --git a/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala b/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
index e8fbf5ab..f66acff3 100644
--- a/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
+++ b/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
@@ -8,7 +8,7 @@ import framework.balldomain.decoder.BallDecodeCmd
// Ball domain issue interface - includes global rob_id
class BallRsIssue(b: GlobalConfig) extends Bundle {
- val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len)
+ val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len, b.memDomain.groupCountWidth)
// Global ROB ID
val rob_id = UInt(log2Up(b.frontend.rob_entries).W)
val is_sub = Bool()
@@ -38,7 +38,7 @@ class BallReservationStation(val b: GlobalConfig) extends Module {
@public
val ball_decode_cmd_i = IO(Flipped(new DecoupledIO(new Bundle {
- val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len)
+ val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len, b.memDomain.groupCountWidth)
// Global ROB ID
val rob_id = UInt(log2Up(b.frontend.rob_entries).W)
val is_sub = Bool()
@@ -59,7 +59,7 @@ class BallReservationStation(val b: GlobalConfig) extends Module {
// Simple FIFO queue, only for buffering
val fifo = Module(new Queue(
new Bundle {
- val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len)
+ val cmd = new BallDecodeCmd(b.memDomain.virtualBankCount, b.frontend.iter_len, b.memDomain.groupCountWidth)
val rob_id = UInt(log2Up(b.frontend.rob_entries).W)
val is_sub = Bool()
val sub_rob_id = UInt(log2Up(b.frontend.sub_rob_depth * 4).W)
diff --git a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
index 854e12f6..e645ecf6 100644
--- a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
+++ b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
@@ -24,9 +24,9 @@ class PostGDCmd(val b: GlobalConfig) extends Bundle {
val ball_bid = UInt(5.W)
val cmd = new RoCCCommandBB(b.core.xLen)
val bankAccess = new BankAccessInfo(b.frontend.bank_id_len)
- val op1_col = UInt(log2Up(b.memDomain.bankNum + 1).W)
- val op2_col = UInt(log2Up(b.memDomain.bankNum + 1).W)
- val wr_col = UInt(log2Up(b.memDomain.bankNum + 1).W)
+ val op1_col = UInt(b.memDomain.groupCountWidth.W)
+ val op2_col = UInt(b.memDomain.groupCountWidth.W)
+ val wr_col = UInt(b.memDomain.groupCountWidth.W)
val isFence = Bool()
val isBarrier = Bool()
}
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index da586879..688438a7 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -86,7 +86,7 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val headPtr = RegInit(0.U(idWidth.W))
val tailPtr = RegInit(0.U(idWidth.W))
val issuedCount = RegInit(0.U(log2Up(robDepth + 1).W))
- private val bankColWidth = log2Up(b.memDomain.bankNum + 1)
+ private val bankColWidth = b.memDomain.groupCountWidth
val bankCols = RegInit(VecInit(Seq.fill(b.memDomain.virtualBankCount)(0.U(bankColWidth.W))))
// In-flight ownership is tracked in the architectural vbank namespace.
private val vbankMaskWidth = b.memDomain.virtualBankCount
diff --git a/arch/src/main/scala/framework/memdomain/MemDomain.scala b/arch/src/main/scala/framework/memdomain/MemDomain.scala
index f8821fdb..52191b13 100644
--- a/arch/src/main/scala/framework/memdomain/MemDomain.scala
+++ b/arch/src/main/scala/framework/memdomain/MemDomain.scala
@@ -55,7 +55,7 @@ class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val shared_config = Decoupled(new MemConfigerIO(b))
val shared_query_valid = Output(Bool())
val shared_query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val shared_query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val shared_query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
})
val frontend: Instance[MemFrontend] = Instantiate(new MemFrontend(b)(edge))
diff --git a/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
index af056433..da712a68 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
@@ -24,12 +24,12 @@ class MemBackend(val b: GlobalConfig) extends Module {
// Query interface: shared query goes out, private query handled internally.
val shared_query_valid = Output(Bool())
val shared_query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val shared_query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val shared_query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
// Original query interface from frontend
val query_vbank_id = Input(UInt(b.memDomain.vbankIdWidth.W))
val query_is_shared = Input(Bool())
- val query_group_count = Output(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val query_group_count = Output(UInt(b.memDomain.groupCountWidth.W))
})
// Keep the private backend datapath unchanged and isolate it in a dedicated module.
diff --git a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
index e0c4dd78..0eaac0cd 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
@@ -9,7 +9,7 @@ class MemRequestIO(b: GlobalConfig) extends Bundle {
val write = Flipped(new SramWriteIO(b)) // midend sends write req into backend
val read = Flipped(new SramReadIO(b)) // midend sends read req into backend
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val group_id = Output(UInt(log2Up(b.memDomain.bankNum).W))
+ val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val is_shared = Output(Bool())
val hart_id = Output(UInt(b.core.xLen.W))
val rob_id = Output(UInt(log2Up(b.frontend.rob_entries).W))
diff --git a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
index f591ce7a..48313f3c 100644
--- a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
@@ -20,7 +20,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
val is_multi = Input(Bool())
val busy = Output(Bool())
- val group_id = Output(UInt(log2Up(b.memDomain.bankNum).W))
+ val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val hart_id = Output(UInt(b.core.xLen.W))
})
@@ -30,7 +30,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
// to access wrong physical addresses while matmul writes used unshifted addresses.
//group_id output
- val group_id_reg = RegInit(0.U(log2Up(b.memDomain.bankNum).W))
+ val group_id_reg = RegInit(0.U(b.memDomain.groupIdWidth.W))
io.group_id := group_id_reg
//Bank_id output
diff --git a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
index 39009d85..6ed56dcd 100644
--- a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
@@ -19,7 +19,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// Query interface for frontend to get group count
val query_vbank_id = Input(UInt(b.memDomain.vbankIdWidth.W))
- val query_group_count = Output(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val query_group_count = Output(UInt(b.memDomain.groupCountWidth.W))
})
val banks: Seq[Instance[SramBank]] = Seq.fill(b.memDomain.bankNum)(Instantiate(new SramBank(b)))
@@ -52,7 +52,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val valid = Bool()
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
- val group_id = UInt(log2Up(b.memDomain.bankNum).W)
+ val group_id = UInt(b.memDomain.groupIdWidth.W)
}
val mappingTable = RegInit(VecInit(Seq.fill(b.memDomain.bankNum)(0.U.asTypeOf(new MappingTableEntry))))
@@ -81,7 +81,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// The private namespace is bounded by the frontend contract, while
// multi-bank groups remain represented individually in mappingTable.
val groupCountByVbank = RegInit(
- VecInit(Seq.fill(privateVbankCount)(0.U(log2Up(b.memDomain.bankNum + 1).W)))
+ VecInit(Seq.fill(privateVbankCount)(0.U(b.memDomain.groupCountWidth.W)))
)
def addEntry(
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
index e791a5f2..a506bc6c 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
@@ -48,14 +48,14 @@ object SharedMemLayout {
class SharedMemReadReq(val b: GlobalConfig) extends Bundle {
val hartid = UInt(b.core.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
- val group_id = UInt(log2Up(b.memDomain.bankNum).W)
+ val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
}
class SharedMemWriteReq(val b: GlobalConfig) extends Bundle {
val hartid = UInt(b.core.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
- val group_id = UInt(log2Up(b.memDomain.bankNum).W)
+ val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
val mask = Vec(b.memDomain.bankMaskLen, Bool())
val data = UInt(b.memDomain.bankWidth.W)
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
index d5e4b068..ccf085b1 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
@@ -24,7 +24,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
val query_valid = Input(Vec(nCores, Bool()))
val query_hart_id = Input(Vec(nCores, UInt(b.core.xLen.W)))
val query_vbank_id = Input(Vec(nCores, UInt(b.memDomain.vbankIdWidth.W)))
- val query_group_count = Output(Vec(nCores, UInt(log2Up(b.memDomain.bankNum + 1).W)))
+ val query_group_count = Output(Vec(nCores, UInt(b.memDomain.groupCountWidth.W)))
})
val banks: Seq[Instance[SramBank]] = Seq.fill(totalBanks)(Instantiate(new SramBank(b)))
@@ -58,7 +58,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
val hart_id = UInt(b.core.xLen.W)
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
- val group_id = UInt(log2Up(b.memDomain.bankNum).W)
+ val group_id = UInt(b.memDomain.groupIdWidth.W)
}
val mappingTable = RegInit(VecInit(Seq.fill(totalBanks)(0.U.asTypeOf(new MappingTableEntry))))
diff --git a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
index 96d7cb23..173b255c 100644
--- a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
+++ b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
@@ -38,6 +38,9 @@ case class MemDomainParam(
val mmioBankBytes: Int = mmioBankEntries * (mmioBankWidth / 8)
val mmioTotalBytes: Int = mmioBankNum * mmioBankBytes
val vbankIdWidth: Int = chisel3.util.log2Up(virtualBankCount)
+ val maxGroupCount: Int = math.max(bankNum, if (sharedEnable) sharedEntries / bankEntries else bankNum)
+ val groupCountWidth: Int = chisel3.util.log2Up(maxGroupCount + 1)
+ val groupIdWidth: Int = chisel3.util.log2Up(maxGroupCount)
}
object MemDomainParam {
diff --git a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
index 070215e8..0e950e28 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
@@ -58,7 +58,7 @@ class MemFrontend(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
// Query interface to backend for group count
val query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val query_is_shared = Output(Bool())
- val query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
val hartid = Input(UInt(b.core.xLen.W))
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
index b3109be6..1df707f3 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
@@ -13,7 +13,7 @@ class MemConfigerIO(val b: GlobalConfig) extends Bundle {
val is_shared = Output(Bool())
val is_multi = Output(Bool())
val alloc = Output(Bool())
- val group_id = Output(UInt(log2Up(b.memDomain.bankNum).W))
+ val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val hart_id = Output(UInt(b.core.xLen.W))
}
@@ -35,13 +35,13 @@ class MemConfiger(val b: GlobalConfig) extends Module {
val state = RegInit(idle)
val alloc_reg = RegInit(false.B)
val is_shared_reg = RegInit(false.B)
- val col_reg = RegInit(0.U(log2Up(b.memDomain.bankNum + 1).W))
+ val col_reg = RegInit(0.U(b.memDomain.groupCountWidth.W))
val clear_reg = RegInit(false.B)
val vbank_id_reg = RegInit(0.U(b.memDomain.vbankIdWidth.W))
val rob_id_reg = RegInit(0.U(rob_id_width.W))
val is_sub_reg = RegInit(false.B)
val sub_rob_id_reg = RegInit(0.U(log2Up(b.frontend.sub_rob_depth * 4).W))
- val counter = RegInit(0.U(log2Up(b.memDomain.bankNum + 1).W))
+ val counter = RegInit(0.U(b.memDomain.groupCountWidth.W))
val zeroLastRow = RegInit(false.B)
val zeroLines: Instance[ZeroLineGenerator] = Instantiate(new ZeroLineGenerator(b.memDomain.bankWidth))
@@ -66,7 +66,7 @@ class MemConfiger(val b: GlobalConfig) extends Module {
io.bankWrite.bank_id := vbank_id_reg
io.bankWrite.rob_id := rob_id_reg
io.bankWrite.ball_id := 0.U
- io.bankWrite.group_id := counter(log2Up(b.memDomain.bankNum) - 1, 0)
+ io.bankWrite.group_id := counter(b.memDomain.groupIdWidth - 1, 0)
zeroLines.io.req.valid := state === zeroReq
zeroLines.io.req.bits.rows := b.memDomain.bankEntries.U
@@ -111,7 +111,7 @@ class MemConfiger(val b: GlobalConfig) extends Module {
io.config.bits.is_shared := is_shared_reg
io.config.bits.alloc := alloc_reg
io.config.bits.vbank_id := vbank_id_reg
- io.config.bits.group_id := counter(log2Up(b.memDomain.bankNum) - 1, 0)
+ io.config.bits.group_id := counter(b.memDomain.groupIdWidth - 1, 0)
io.config.valid := true.B
when(io.config.fire) {
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemLoader.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemLoader.scala
index e92efb6b..38af4916 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemLoader.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemLoader.scala
@@ -33,7 +33,7 @@ class MemLoader(val b: GlobalConfig) extends Module {
val query_valid = Output(Bool())
val query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val query_is_shared = Output(Bool())
- val query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
// Propagate decoded shared/private access intent.
val is_shared = Output(Bool())
@@ -55,8 +55,8 @@ class MemLoader(val b: GlobalConfig) extends Module {
val is_shared_reg = RegInit(false.B)
// Group counter for multi-bank writes
- val group_counter = RegInit(0.U(log2Up(b.memDomain.bankNum + 1).W))
- val group_count_reg = RegInit(0.U(log2Up(b.memDomain.bankNum + 1).W))
+ val group_counter = RegInit(0.U(b.memDomain.groupCountWidth.W))
+ val group_count_reg = RegInit(0.U(b.memDomain.groupCountWidth.W))
val rowAddr = RegInit(0.U(log2Ceil(b.memDomain.bankEntries).W))
// MMIO routing info (latched at cmdReq.fire, exposed to upper level)
@@ -116,7 +116,7 @@ class MemLoader(val b: GlobalConfig) extends Module {
io.bankWrite.rob_id := rob_id_reg
io.bankWrite.bank_id := wr_bank_reg
io.bankWrite.ball_id := 0.U
- io.bankWrite.group_id := group_counter(log2Up(b.memDomain.bankNum) - 1, 0)
+ io.bankWrite.group_id := group_counter(b.memDomain.groupIdWidth - 1, 0)
io.is_shared := is_shared_reg
// cmdResp (Decoupled): hold valid until accepted
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemStorer.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemStorer.scala
index dab5eb88..f426377f 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemStorer.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemStorer.scala
@@ -33,7 +33,7 @@ class MemStorer(val b: GlobalConfig) extends Module {
val query_valid = Output(Bool())
val query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val query_is_shared = Output(Bool())
- val query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
// Propagate decoded shared/private access intent.
val is_shared = Output(Bool())
@@ -52,11 +52,11 @@ class MemStorer(val b: GlobalConfig) extends Module {
val iter_reg = RegInit(0.U(b.frontend.iter_len.W))
val rd_bank_reg = RegInit(0.U(b.memDomain.vbankIdWidth.W))
val stride_reg = RegInit(1.U(19.W))
- val group_count_reg = RegInit(1.U(log2Up(b.memDomain.bankNum + 1).W))
+ val group_count_reg = RegInit(1.U(b.memDomain.groupCountWidth.W))
val is_shared_reg = RegInit(false.B)
val addr_counter = RegInit(0.U(b.frontend.iter_len.W))
- val group_counter = RegInit(0.U(log2Up(b.memDomain.bankNum + 1).W))
+ val group_counter = RegInit(0.U(b.memDomain.groupCountWidth.W))
val cursor = RegInit(0.U(b.memDomain.memAddrLen.W))
val rowDelta = RegInit(0.U(b.memDomain.memAddrLen.W))
@@ -133,7 +133,7 @@ class MemStorer(val b: GlobalConfig) extends Module {
io.bankRead.rob_id := rob_id_reg
io.bankRead.bank_id := target_bank
io.bankRead.ball_id := 0.U
- io.bankRead.group_id := group_counter(log2Up(b.memDomain.bankNum) - 1, 0)
+ io.bankRead.group_id := group_counter(b.memDomain.groupIdWidth - 1, 0)
io.is_shared := is_shared_reg
io.bankRead.io.req.valid := (state === s_issue_sram_req)
diff --git a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
index 83d51f1f..15869068 100644
--- a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
+++ b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
@@ -57,7 +57,7 @@ class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module
val shared_config = Decoupled(new MemConfigerIO(b))
val shared_query_valid = Output(Bool())
val shared_query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val shared_query_group_count = Input(UInt(log2Up(b.memDomain.bankNum + 1).W))
+ val shared_query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
// Barrier interface — connected to tile-level BarrierUnit
val barrier_arrive = Output(Bool())
diff --git a/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala b/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
index 6cdcd8a1..145798c8 100644
--- a/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
+++ b/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
@@ -1,10 +1,14 @@
package sims.verilator
-import org.chipsalliance.cde.config.Config
+import org.chipsalliance.cde.config.{Config, Parameters}
class BuckyballPolyVerilatorConfig
extends Config(
- new BBSimConfig(maxHarts = 20) ++
+ (if (sys.env.get("CI").contains("true"))
+ new freechips.rocketchip.subsystem.WithoutTLMonitors
+ else
+ new Config(Parameters.empty)) ++
+ new BBSimConfig(maxHarts = 20) ++
new WithCustomBootROM ++
new examples.poly.BuckyballPolyConfig
)
diff --git a/examples/chips/poly/regression/batch/verilator/workloads-elf.toml b/examples/chips/poly/regression/batch/verilator/workloads-elf.toml
new file mode 100644
index 00000000..8ab0aa98
--- /dev/null
+++ b/examples/chips/poly/regression/batch/verilator/workloads-elf.toml
@@ -0,0 +1,4 @@
+[workloads]
+tests = [
+ "poly-decode-ctest-chip-vecmat16_atranspose_16x16-multicore-baremetal",
+]
diff --git a/examples/chips/poly/workloads/ctests/vecmat16_atranspose_16x16/vecmat16_atranspose_16x16-main.cpp b/examples/chips/poly/workloads/ctests/vecmat16_atranspose_16x16/vecmat16_atranspose_16x16-main.cpp
index 68db9463..efe27760 100644
--- a/examples/chips/poly/workloads/ctests/vecmat16_atranspose_16x16/vecmat16_atranspose_16x16-main.cpp
+++ b/examples/chips/poly/workloads/ctests/vecmat16_atranspose_16x16/vecmat16_atranspose_16x16-main.cpp
@@ -9,6 +9,9 @@ volatile int test_result = 1;
int main() {
core_id_t id = bb_get_core_id();
+ if (id.tile != 0)
+ for (;;)
+ asm volatile("wfi");
if (id.core < 3)
return prefill_main(id);
if (id.core < 5)
From 2b6750847788216e94a794aef53dd27e85247679 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Tue, 15 Sep 2026 16:15:08 +0800
Subject: [PATCH 17/36] Format Scala files for CI
---
.../framework/balldomain/decoder/BallDomainDecoder.scala | 3 ++-
.../framework/memdomain/configs/MemDomainParam.scala | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala b/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
index eef7ba14..ca6db292 100644
--- a/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
+++ b/arch/src/main/scala/framework/balldomain/decoder/BallDomainDecoder.scala
@@ -22,7 +22,8 @@ class BallDomainDecoder(val b: GlobalConfig) extends Module {
val iterLen = b.frontend.iter_len
@public
- val cmd_i = IO(Flipped(Decoupled(new PostGDCmd(b))))
+ val cmd_i = IO(Flipped(Decoupled(new PostGDCmd(b))))
+
@public
val ball_decode_cmd_o =
IO(Decoupled(new BallDecodeCmd(b.memDomain.virtualBankCount, iterLen, b.memDomain.groupCountWidth)))
diff --git a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
index 173b255c..10571603 100644
--- a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
+++ b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
@@ -35,10 +35,10 @@ case class MemDomainParam(
mmioReadWidth: Int) {
// MMIO derived values
- val mmioBankBytes: Int = mmioBankEntries * (mmioBankWidth / 8)
- val mmioTotalBytes: Int = mmioBankNum * mmioBankBytes
- val vbankIdWidth: Int = chisel3.util.log2Up(virtualBankCount)
- val maxGroupCount: Int = math.max(bankNum, if (sharedEnable) sharedEntries / bankEntries else bankNum)
+ val mmioBankBytes: Int = mmioBankEntries * (mmioBankWidth / 8)
+ val mmioTotalBytes: Int = mmioBankNum * mmioBankBytes
+ val vbankIdWidth: Int = chisel3.util.log2Up(virtualBankCount)
+ val maxGroupCount: Int = math.max(bankNum, if (sharedEnable) sharedEntries / bankEntries else bankNum)
val groupCountWidth: Int = chisel3.util.log2Up(maxGroupCount + 1)
val groupIdWidth: Int = chisel3.util.log2Up(maxGroupCount)
}
From 2e472be3ed3fd6670c40a1c947187f1fe91991e2 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Tue, 15 Sep 2026 19:22:57 +0800
Subject: [PATCH 18/36] Fix CI jobs using stale repo lock script
---
.github/workflows/check.yaml | 3 ++-
.github/workflows/regression.yml | 15 ++++++++++-----
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index d879339b..7be0238e 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -118,7 +118,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Nix build
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 0a26ec7d..4c0c4749 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -96,7 +96,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: DC area
@@ -162,7 +163,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Chip UVM
@@ -214,7 +216,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: FPGA buildbitstream
@@ -272,7 +275,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: FPGA check
@@ -327,7 +331,8 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- bash "${root}/.github/scripts/ci_repo_lock.sh" \
+ git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
+ git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Model build
From 4a4ebd972a8e8ee478d988931e92fb913bfadbe2 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Tue, 15 Sep 2026 23:32:40 +0800
Subject: [PATCH 19/36] fix: repair P2E regression workloads
---
.github/workflows/regression.yml | 4 +++-
.../smatmul/verify/filelists/smatmul_ball.f | 6 +++++-
.../regression/batch/p2e/workloads-elf.toml | 11 ++++++++++
.../regression/batch/p2e/workloads-pk.toml | 4 ++++
.../regression/batch/p2e/workloads-elf.toml | 21 +++++++++++++++++++
.../regression/batch/p2e/workloads-pk.toml | 4 ++++
.../regression/batch/p2e/workloads-pk.toml | 2 +-
.../regression/batch/p2e/workloads-elf.toml | 4 ++++
.../regression/batch/p2e/workloads-pk.toml | 4 ++++
.../regression/batch/p2e/workloads-pk.toml | 2 +-
10 files changed, 58 insertions(+), 4 deletions(-)
create mode 100644 examples/chips/goban/regression/batch/p2e/workloads-elf.toml
create mode 100644 examples/chips/goban/regression/batch/p2e/workloads-pk.toml
create mode 100644 examples/chips/multi-rocket/regression/batch/p2e/workloads-elf.toml
create mode 100644 examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
create mode 100644 examples/chips/poly/regression/batch/p2e/workloads-elf.toml
create mode 100644 examples/chips/poly/regression/batch/p2e/workloads-pk.toml
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 4c0c4749..8271ad48 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -227,7 +227,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
cd "${root}"
- rm -rf "${root}"/bebop/build/"${{ matrix.chip }}"-*/
+ for build_dir in "${root}"/bebop/build/"${{ matrix.chip }}"-*(N); do
+ rm -rf "${build_dir}"
+ done
nix develop -c bbdev bebop-p2e --verilog '--chip ${{ matrix.chip }}'
nix develop -c bbdev bebop-p2e --buildbitstream '--chip ${{ matrix.chip }}'
bits=("${root}"/bebop/build/"${{ matrix.chip }}"-*/fpgaCompDir/bitstream.bit(N))
diff --git a/examples/balls/smatmul/verify/filelists/smatmul_ball.f b/examples/balls/smatmul/verify/filelists/smatmul_ball.f
index bc43b7b9..0e290bb6 100644
--- a/examples/balls/smatmul/verify/filelists/smatmul_ball.f
+++ b/examples/balls/smatmul/verify/filelists/smatmul_ball.f
@@ -17,7 +17,11 @@
@UVM@/src/ball/bb_blink_if.sv
@UVM@/src/ball/bb_uvm_pkg.sv
--f @RTL@/filelist.f
+@RTL@/PE.sv
+@RTL@/Array.sv
+@RTL@/SMatMulUnit.sv
+@RTL@/SMatMulBall.sv
+@RTL@/@SMATMUL_ACCUMULATOR@
src/pkg/smatmul_pkg.sv
src/tb_top.sv
diff --git a/examples/chips/goban/regression/batch/p2e/workloads-elf.toml b/examples/chips/goban/regression/batch/p2e/workloads-elf.toml
new file mode 100644
index 00000000..fd68ff34
--- /dev/null
+++ b/examples/chips/goban/regression/batch/p2e/workloads-elf.toml
@@ -0,0 +1,11 @@
+[workloads]
+tests = [
+ "goban-goban-ctest-chip-topology_smoke_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-barrier_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-barrier_mvin_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-shared_barrier_mvin_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-shared_same_vbank_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-shared_multigroup_mvin_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-shared_transpose_test-multicore-baremetal.hex",
+ "goban-goban-ctest-chip-shared_smatmul_quant_int2fp_pipeline_test-multicore-baremetal.hex",
+]
diff --git a/examples/chips/goban/regression/batch/p2e/workloads-pk.toml b/examples/chips/goban/regression/batch/p2e/workloads-pk.toml
new file mode 100644
index 00000000..f58f0893
--- /dev/null
+++ b/examples/chips/goban/regression/batch/p2e/workloads-pk.toml
@@ -0,0 +1,4 @@
+[workloads]
+tests = [
+ "goban-goban-ctest-chip-topology_smoke_test-multicore-baremetal.hex",
+]
diff --git a/examples/chips/multi-rocket/regression/batch/p2e/workloads-elf.toml b/examples/chips/multi-rocket/regression/batch/p2e/workloads-elf.toml
new file mode 100644
index 00000000..eb387388
--- /dev/null
+++ b/examples/chips/multi-rocket/regression/batch/p2e/workloads-elf.toml
@@ -0,0 +1,21 @@
+[workloads]
+tests = [
+ "multi-rocket-rocket-ctest-benchmark-embench_aha-mont64-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_crc32-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_edn-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_huffbench-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_matmult-int-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_minver-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_nbody-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_nettle-aes-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_nettle-sha256-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_nsichneu-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_picojpeg-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_qrduino-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_sglib-combined-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_slre-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_st-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_statemate-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_ud-baremetal.hex",
+ "multi-rocket-rocket-ctest-benchmark-embench_wikisort-baremetal.hex",
+]
diff --git a/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml b/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
new file mode 100644
index 00000000..c94cb2bd
--- /dev/null
+++ b/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
@@ -0,0 +1,4 @@
+[workloads]
+tests = [
+ "multi-rocket-rocket-ctest-benchmark-embench_aha-mont64-baremetal.hex",
+]
diff --git a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
index e873b216..c1ce0f89 100644
--- a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
+++ b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
@@ -1,4 +1,4 @@
[workloads]
tests = [
- "fw_payload-pebble-pk.hex",
+ "pebble-pebble-ctest-residual_add_lut_test-baremetal.hex",
]
diff --git a/examples/chips/poly/regression/batch/p2e/workloads-elf.toml b/examples/chips/poly/regression/batch/p2e/workloads-elf.toml
new file mode 100644
index 00000000..e447bec5
--- /dev/null
+++ b/examples/chips/poly/regression/batch/p2e/workloads-elf.toml
@@ -0,0 +1,4 @@
+[workloads]
+tests = [
+ "poly-decode-ctest-chip-vecmat16_atranspose_16x16-multicore-baremetal.hex",
+]
diff --git a/examples/chips/poly/regression/batch/p2e/workloads-pk.toml b/examples/chips/poly/regression/batch/p2e/workloads-pk.toml
new file mode 100644
index 00000000..e447bec5
--- /dev/null
+++ b/examples/chips/poly/regression/batch/p2e/workloads-pk.toml
@@ -0,0 +1,4 @@
+[workloads]
+tests = [
+ "poly-decode-ctest-chip-vecmat16_atranspose_16x16-multicore-baremetal.hex",
+]
diff --git a/examples/chips/toy/regression/batch/p2e/workloads-pk.toml b/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
index 8ca9ccb1..af6ce18c 100644
--- a/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
+++ b/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
@@ -1,4 +1,4 @@
[workloads]
tests = [
- "fw_payload-toy-pk.hex",
+ "toy-toy-ctest-mmio_minimal_test-baremetal.hex",
]
From d3bb373ed6d6df3e094beaec0fdb2d92a2f767d8 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Wed, 16 Sep 2026 17:53:05 +0800
Subject: [PATCH 20/36] ci: extend FPGA bitstream timeout
---
.github/workflows/regression.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 8271ad48..70faef28 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -192,6 +192,7 @@ jobs:
name: fpga-bitstream-${{ matrix.chip }}
needs: gate
runs-on: check
+ timeout-minutes: 720
strategy:
fail-fast: false
matrix:
From f8e8e8cfc91960d85de9b7d5db56020414b60e2d Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Thu, 17 Sep 2026 13:44:36 +0800
Subject: [PATCH 21/36] fix: preserve Verilator top module output
---
arch/src/main/scala/sims/verilator/TargetConfig.scala | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/src/main/scala/sims/verilator/TargetConfig.scala b/arch/src/main/scala/sims/verilator/TargetConfig.scala
index 7a75d6a7..61010e64 100644
--- a/arch/src/main/scala/sims/verilator/TargetConfig.scala
+++ b/arch/src/main/scala/sims/verilator/TargetConfig.scala
@@ -146,17 +146,21 @@ object Elaborate extends App {
sys.exit(1)
}
- val firtoolOpts = args.drop(1)
+ val rawFirtoolOpts = args.drop(1)
- val outDir = firtoolOpts.collectFirst {
+ val outDir = rawFirtoolOpts.collectFirst {
case opt if opt.startsWith("-o=") => opt.stripPrefix("-o=")
}.getOrElse {
throw new Exception("missing -o=
in firtool opts")
}
+ val firtoolOpts = rawFirtoolOpts.filterNot { opt =>
+ opt == "--split-verilog" || opt.startsWith("-o=")
+ }
+
ChiselStage.emitSystemVerilogFile(
new BBSimHarness()(config.toInstance),
firtoolOpts = firtoolOpts,
- args = Array("--target-dir", outDir)
+ args = Array("--target-dir", outDir, "--split-verilog")
)
}
From 4bcaf6b9d5265803753ef1b92051b7c83c5e70c5 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Thu, 17 Sep 2026 15:44:07 +0800
Subject: [PATCH 22/36] fix: preserve P2E top module output
---
arch/src/main/scala/sims/p2e/TargetConfigs.scala | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/src/main/scala/sims/p2e/TargetConfigs.scala b/arch/src/main/scala/sims/p2e/TargetConfigs.scala
index 21fb5a58..c3adf051 100644
--- a/arch/src/main/scala/sims/p2e/TargetConfigs.scala
+++ b/arch/src/main/scala/sims/p2e/TargetConfigs.scala
@@ -109,22 +109,26 @@ object Elaborate extends App {
sys.exit(1)
}
- val firtoolOpts = args.drop(1)
+ val rawFirtoolOpts = args.drop(1)
- val outDir = firtoolOpts.collectFirst {
+ val outDir = rawFirtoolOpts.collectFirst {
case opt if opt.startsWith("-o=") => opt.stripPrefix("-o=")
}.getOrElse {
throw new Exception("missing -o= in firtool opts")
}
+ val firtoolOpts = rawFirtoolOpts.filterNot { opt =>
+ opt == "--split-verilog" || opt.startsWith("-o=")
+ }
+
ChiselStage.emitSystemVerilogFile(
new P2EHarness()(config.toInstance),
firtoolOpts = firtoolOpts,
- args = Array("--target-dir", outDir)
+ args = Array("--target-dir", outDir, "--split-verilog")
)
ChiselStage.emitSystemVerilogFile(
new P2ETop,
firtoolOpts = firtoolOpts,
- args = Array("--target-dir", outDir)
+ args = Array("--target-dir", outDir, "--split-verilog")
)
}
From ea0e48e6a151465c5065da4ddd153090a8962a0d Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Fri, 18 Sep 2026 00:21:45 +0800
Subject: [PATCH 23/36] fix: stabilize P2E bank difftest build
---
examples/cores/pebble/configs/default.toml | 35 +++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/examples/cores/pebble/configs/default.toml b/examples/cores/pebble/configs/default.toml
index 8f6d405c..41d3c08e 100644
--- a/examples/cores/pebble/configs/default.toml
+++ b/examples/cores/pebble/configs/default.toml
@@ -6,4 +6,37 @@ memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+
+[rocketCore]
+xLen = 64
+pgLevels = 3
+useVM = true
+useZba = true
+useZbb = true
+useZbs = true
+haveCFlush = true
+
+[rocketCore.mulDiv]
+enable = true
+mulUnroll = 8
+mulEarlyOut = true
+divEarlyOut = true
+
+[rocketCore.fpu]
+enable = true
+minFLen = 16
+fLen = 64
+
+[rocketCore.dcache]
+nSets = 32
+nWays = 4
+nMSHRs = 0
+
+[rocketCore.icache]
+nSets = 64
+nWays = 8
+
+[rocketCore.btb]
+enable = true
+nEntries = 28
+nRAS = 6
From e9f47d71b7eb8173f158f29cf2c85ad01e4dfd5e Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Fri, 18 Sep 2026 08:42:54 +0800
Subject: [PATCH 24/36] Delete examples/cores/pebble/configs/default.toml
---
examples/cores/pebble/configs/default.toml | 42 ----------------------
1 file changed, 42 deletions(-)
delete mode 100644 examples/cores/pebble/configs/default.toml
diff --git a/examples/cores/pebble/configs/default.toml b/examples/cores/pebble/configs/default.toml
deleted file mode 100644
index 41d3c08e..00000000
--- a/examples/cores/pebble/configs/default.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-# Pebble Core Configuration (default)
-
-kind = "rocket"
-balldomain = "balldomains/default.toml"
-memdomain = "memdomains/default.toml"
-frontend = "frontends/default.toml"
-gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-
-[rocketCore]
-xLen = 64
-pgLevels = 3
-useVM = true
-useZba = true
-useZbb = true
-useZbs = true
-haveCFlush = true
-
-[rocketCore.mulDiv]
-enable = true
-mulUnroll = 8
-mulEarlyOut = true
-divEarlyOut = true
-
-[rocketCore.fpu]
-enable = true
-minFLen = 16
-fLen = 64
-
-[rocketCore.dcache]
-nSets = 32
-nWays = 4
-nMSHRs = 0
-
-[rocketCore.icache]
-nSets = 64
-nWays = 8
-
-[rocketCore.btb]
-enable = true
-nEntries = 28
-nRAS = 6
From 602756410609cacdad11c739e551636327ae396e Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Fri, 18 Sep 2026 08:38:02 +0800
Subject: [PATCH 25/36] revert: use shared Rocket config for Pebble
---
examples/cores/pebble/configs/default.toml | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 examples/cores/pebble/configs/default.toml
diff --git a/examples/cores/pebble/configs/default.toml b/examples/cores/pebble/configs/default.toml
new file mode 100644
index 00000000..8f6d405c
--- /dev/null
+++ b/examples/cores/pebble/configs/default.toml
@@ -0,0 +1,9 @@
+# Pebble Core Configuration (default)
+
+kind = "rocket"
+balldomain = "balldomains/default.toml"
+memdomain = "memdomains/default.toml"
+frontend = "frontends/default.toml"
+gpdomain = "gpdomains/default.toml"
+core = "core/default.toml"
+rocketCore = "../../rocket/configs/rocketCore.toml"
From 3c7cb3ecdf12fab8e77fd9958e210894bae3ba80 Mon Sep 17 00:00:00 2001
From: daiyongyuan <1533208939@qq.com>
Date: Fri, 18 Sep 2026 20:38:59 +0800
Subject: [PATCH 26/36] fix: restore regression coverage and explicit compiler
builds
---
.github/workflows/regression.yml | 13 ++++++++++++-
bb-tests/workloads/scripts/build.py | 16 ----------------
.../goban/regression/batch/p2e/workloads-pk.toml | 4 ----
.../regression/batch/p2e/workloads-pk.toml | 4 ----
.../regression/batch/p2e/workloads-pk.toml | 2 +-
.../poly/regression/batch/p2e/workloads-pk.toml | 4 ----
.../toy/regression/batch/p2e/workloads-pk.toml | 2 +-
7 files changed, 14 insertions(+), 31 deletions(-)
delete mode 100644 examples/chips/goban/regression/batch/p2e/workloads-pk.toml
delete mode 100644 examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
delete mode 100644 examples/chips/poly/regression/batch/p2e/workloads-pk.toml
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 70faef28..40bb560d 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -260,14 +260,19 @@ jobs:
include:
- chip: toy
run_fpga_check: true
+ run_fpga_pk: true
- chip: pebble
run_fpga_check: true
+ run_fpga_pk: true
- chip: goban
run_fpga_check: true
+ run_fpga_pk: false
- chip: poly
run_fpga_check: true
+ run_fpga_pk: false
- chip: multi-rocket
run_fpga_check: true
+ run_fpga_pk: false
env:
BB_ROOT: ~/Code/buckyball
steps:
@@ -295,10 +300,15 @@ jobs:
printf '%s\n' "${bits[@]}" >&2
exit 1
fi
+ nix develop -c bbdev compiler --build "--chip ${{ matrix.chip }}"
nix develop -c bbdev workload --build "--chip ${{ matrix.chip }}"
nix develop -c bbdev workload --tohex "--chip ${{ matrix.chip }}"
nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test elf-tests"
- nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test pk-tests"
+
+ if [[ "${{ matrix.run_fpga_pk }}" == "true" ]]; then
+ nix develop -c bbdev kernel --build "--chip ${{ matrix.chip }}"
+ nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test pk-tests"
+ fi
- name: Exit repo lock
if: always() && matrix.run_fpga_check
@@ -348,6 +358,7 @@ jobs:
echo "ERROR: eval-performance requires a real model, got model=none" >&2
exit 1
fi
+ nix develop -c bbdev compiler --build "--chip ${{ matrix.chip }}"
nix develop -c bbdev workload --build "--chip ${{ matrix.chip }} --model ${{ matrix.model }}"
nix develop -c bbdev kernel --build "--chip ${{ matrix.chip }} --model ${{ matrix.model }}"
diff --git a/bb-tests/workloads/scripts/build.py b/bb-tests/workloads/scripts/build.py
index 67c9fead..6129dc56 100644
--- a/bb-tests/workloads/scripts/build.py
+++ b/bb-tests/workloads/scripts/build.py
@@ -368,22 +368,6 @@ def build_workload(
logger=logger,
task_scope=task_scope,
)
- _run(
- [
- "ninja",
- "-C",
- str(compiler_build),
- f"-j{os.cpu_count() or 1}",
- f"buckyball-compiler-{chip}",
- "buddy-opt",
- "frontend/Python/python-package-buddy",
- ],
- cwd=root,
- env=env,
- prefix="buddy python package",
- logger=logger,
- task_scope=task_scope,
- )
ninja = ["ninja", "-C", str(build), f"-j{os.cpu_count() or 1}"]
if ninja_arg:
ninja.append(ninja_arg)
diff --git a/examples/chips/goban/regression/batch/p2e/workloads-pk.toml b/examples/chips/goban/regression/batch/p2e/workloads-pk.toml
deleted file mode 100644
index f58f0893..00000000
--- a/examples/chips/goban/regression/batch/p2e/workloads-pk.toml
+++ /dev/null
@@ -1,4 +0,0 @@
-[workloads]
-tests = [
- "goban-goban-ctest-chip-topology_smoke_test-multicore-baremetal.hex",
-]
diff --git a/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml b/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
deleted file mode 100644
index c94cb2bd..00000000
--- a/examples/chips/multi-rocket/regression/batch/p2e/workloads-pk.toml
+++ /dev/null
@@ -1,4 +0,0 @@
-[workloads]
-tests = [
- "multi-rocket-rocket-ctest-benchmark-embench_aha-mont64-baremetal.hex",
-]
diff --git a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
index c1ce0f89..e873b216 100644
--- a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
+++ b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
@@ -1,4 +1,4 @@
[workloads]
tests = [
- "pebble-pebble-ctest-residual_add_lut_test-baremetal.hex",
+ "fw_payload-pebble-pk.hex",
]
diff --git a/examples/chips/poly/regression/batch/p2e/workloads-pk.toml b/examples/chips/poly/regression/batch/p2e/workloads-pk.toml
deleted file mode 100644
index e447bec5..00000000
--- a/examples/chips/poly/regression/batch/p2e/workloads-pk.toml
+++ /dev/null
@@ -1,4 +0,0 @@
-[workloads]
-tests = [
- "poly-decode-ctest-chip-vecmat16_atranspose_16x16-multicore-baremetal.hex",
-]
diff --git a/examples/chips/toy/regression/batch/p2e/workloads-pk.toml b/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
index af6ce18c..8ca9ccb1 100644
--- a/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
+++ b/examples/chips/toy/regression/batch/p2e/workloads-pk.toml
@@ -1,4 +1,4 @@
[workloads]
tests = [
- "toy-toy-ctest-mmio_minimal_test-baremetal.hex",
+ "fw_payload-toy-pk.hex",
]
From 7ebf69f6ed90a36ff29aa1caf3bf86cdcd48d577 Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Sat, 19 Sep 2026 19:52:04 +0800
Subject: [PATCH 27/36] refactor: reformat and improve CI repo lock script for
better handling of submodules
---
.github/scripts/ci_repo_lock.sh | 19 ++--
.github/workflows/check.yaml | 14 ++-
.github/workflows/regression.yml | 66 +++++++------
arch/build.sc | 19 ++--
.../src/main/resources/arbiter_checker.svh | 4 +-
.../src/main/resources/arbiter_driver.svh | 18 ++--
.../src/main/resources/arbiter_interface.sv | 12 ++-
.../axis/src/main/resources/arbiter_tb.sv | 36 +++----
.../axis/src/main/resources/arbiter_test.svh | 6 +-
.../axis/src/main/resources/interface.sv | 9 +-
.../axis/src/main/resources/master_tb.sv | 28 +++---
.../axis/src/main/resources/slave_tb.sv | 28 +++---
.../scala/framework/mem-core/cache/build.sc | 21 ----
.../mem-core/cache/src/csrc/README.md | 0
.../cache/src/main/resources/README.md | 0
.../mem-core/chi/src/main/scala/Emit.scala | 2 +
.../src/main/scala/hnf}/ChiHome.scala | 3 +-
.../src/main/scala/rnf}/BankedChiCache.scala | 2 +-
.../src/main/scala/rnf}/CachePort.scala | 2 +-
.../src/main/scala/rnf}/ChiCache.scala | 2 +-
.../src/main/scala/rni}/NpuRegion.scala | 2 +-
.../src/main/scala/{ => snf}/MemoryNode.scala | 3 +-
.../main/scala/{ => snf}/SramEndpoint.scala | 3 +-
.../framework/mem-core/coherence/build.sc | 7 +-
.../src/main/scala/CoherentSystem.scala | 5 +-
.../src/main/scala/RootPageTableWalker.scala | 2 +-
.../scala/framework/root/root-chip/build.sc | 9 +-
.../scala/chip/mesh/CoherentMeshSystem.scala | 5 +-
.../system/configloader/ChipLoader.scala | 25 ++---
bbdev | 2 +-
.../balls/gemmini/verify/casegen/Cargo.lock | 7 ++
.../balls/gemmini/verify/casegen/Cargo.toml | 7 ++
.../balls/gemmini/verify/casegen/src/lib.rs | 4 +
.../gemmini/verify/filelists/gemmini_ball.f | 29 ++++++
.../verify/src/common/gemmini_defs.svh | 3 +
.../gemmini/verify/src/pkg/gemmini_pkg.sv | 7 ++
examples/balls/gemmini/verify/src/tb_top.sv | 81 +++++++++++++++
.../gemmini/verify/src/tests/gemmini_test.svh | 98 +++++++++++++++++++
examples/chips/goban/configs/chip.toml | 4 +
examples/chips/multi-rocket/configs/chip.toml | 4 +
examples/chips/pebble/configs/chip.toml | 4 +
examples/chips/poly/configs/chip.toml | 4 +
examples/chips/toy/configs/chip.toml | 4 +
.../boom/configs/{ => cpu/boom}/boomCore.toml | 0
examples/cores/boom/configs/cpu/default.toml | 2 +
examples/cores/boom/configs/default.toml | 3 +-
.../core => decode/configs/cpu}/default.toml | 2 +
examples/cores/decode/configs/default.toml | 4 +-
.../core => goban/configs/cpu}/default.toml | 2 +
examples/cores/goban/configs/default.toml | 4 +-
.../core => pebble/configs/cpu}/default.toml | 2 +
.../pebble/configs/cpu/rocket/rocketCore.toml | 32 ++++++
examples/cores/pebble/configs/default.toml | 4 +-
.../core => prefill/configs/cpu}/default.toml | 2 +
examples/cores/prefill/configs/default.toml | 4 +-
.../cores/rocket/configs/cpu/default.toml | 2 +
.../configs/{ => cpu/rocket}/rocketCore.toml | 0
examples/cores/rocket/configs/default.toml | 3 +-
examples/cores/toy/configs/core/default.toml | 6 --
examples/cores/toy/configs/cpu/default.toml | 8 ++
examples/cores/toy/configs/default.toml | 4 +-
examples/cores/toy/configs/demo.toml | 4 +-
62 files changed, 492 insertions(+), 206 deletions(-)
delete mode 100644 arch/src/main/scala/framework/mem-core/cache/build.sc
delete mode 100644 arch/src/main/scala/framework/mem-core/cache/src/csrc/README.md
delete mode 100644 arch/src/main/scala/framework/mem-core/cache/src/main/resources/README.md
rename arch/src/main/scala/framework/mem-core/{coherence/src/main/scala => chi/src/main/scala/hnf}/ChiHome.scala (99%)
rename arch/src/main/scala/framework/mem-core/{cache/src/main/scala => chi/src/main/scala/rnf}/BankedChiCache.scala (99%)
rename arch/src/main/scala/framework/mem-core/{cache/src/main/scala => chi/src/main/scala/rnf}/CachePort.scala (96%)
rename arch/src/main/scala/framework/mem-core/{cache/src/main/scala => chi/src/main/scala/rnf}/ChiCache.scala (99%)
rename arch/src/main/scala/framework/mem-core/{coherence/src/main/scala => chi/src/main/scala/rni}/NpuRegion.scala (99%)
rename arch/src/main/scala/framework/mem-core/chi/src/main/scala/{ => snf}/MemoryNode.scala (99%)
rename arch/src/main/scala/framework/mem-core/chi/src/main/scala/{ => snf}/SramEndpoint.scala (98%)
create mode 100644 examples/balls/gemmini/verify/casegen/Cargo.lock
create mode 100644 examples/balls/gemmini/verify/casegen/Cargo.toml
create mode 100644 examples/balls/gemmini/verify/casegen/src/lib.rs
create mode 100644 examples/balls/gemmini/verify/filelists/gemmini_ball.f
create mode 100644 examples/balls/gemmini/verify/src/common/gemmini_defs.svh
create mode 100644 examples/balls/gemmini/verify/src/pkg/gemmini_pkg.sv
create mode 100644 examples/balls/gemmini/verify/src/tb_top.sv
create mode 100644 examples/balls/gemmini/verify/src/tests/gemmini_test.svh
rename examples/cores/boom/configs/{ => cpu/boom}/boomCore.toml (100%)
create mode 100644 examples/cores/boom/configs/cpu/default.toml
rename examples/cores/{pebble/configs/core => decode/configs/cpu}/default.toml (51%)
rename examples/cores/{prefill/configs/core => goban/configs/cpu}/default.toml (51%)
rename examples/cores/{goban/configs/core => pebble/configs/cpu}/default.toml (61%)
create mode 100644 examples/cores/pebble/configs/cpu/rocket/rocketCore.toml
rename examples/cores/{decode/configs/core => prefill/configs/cpu}/default.toml (51%)
create mode 100644 examples/cores/rocket/configs/cpu/default.toml
rename examples/cores/rocket/configs/{ => cpu/rocket}/rocketCore.toml (100%)
delete mode 100644 examples/cores/toy/configs/core/default.toml
create mode 100644 examples/cores/toy/configs/cpu/default.toml
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index 45ab9bc1..ec729fee 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -23,21 +23,22 @@ exec 9>"${LOCK_FILE}"
repo_reset() {
cd "${repo}"
- git fetch --force --prune --no-recurse-submodules origin "${want_sha}"
- git -c submodule.recurse=false checkout --detach --force "${want_sha}"
- git -c submodule.recurse=false reset --hard "${want_sha}"
+
+ # buckyball repository it self never depend on submodules in submodules unless llvm in buddy-mlir
+ git fetch --force --prune origin "${want_sha}"
+ git -c checkout --detach --force "${want_sha}"
+ git -c reset --hard "${want_sha}"
git clean -ffd
- # rm -rf arch/out
+
+ rm -rf arch/out
rm -rf compiler/thirdparty/buddy-mlir/llvm/build
rm -rf compiler/thirdparty/buddy-mlir/build
+
git submodule sync
- git submodule update --init --force -- $(git ls-tree -r "${want_sha}" | awk '$1 == "160000" { print $4 }')
+ git submodule update --init --force
git -C compiler/thirdparty/buddy-mlir submodule sync
git -C compiler/thirdparty/buddy-mlir submodule update --init --force -- llvm
- for submodule in bbdev bebop compiler/thirdparty/buddy-mlir; do
- git -C "${repo}/${submodule}" reset --hard
- git -C "${repo}/${submodule}" clean -ffd
- done
+ git submodule foreach 'git clean -ffd'
have_sha="$(git rev-parse HEAD)"
if [[ "${have_sha}" != "${want_sha}" ]]; then
echo "ERROR: checkout is ${have_sha}, expected ${want_sha}" >&2
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index 7be0238e..496468c0 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -43,10 +43,13 @@ jobs:
set -euo pipefail
root=~/Code/buckyball
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
- prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
cd "${root}"
+
+ # fetch first to ensure if we modify ci_repo_lock.sh, we still use the old version to checkout.
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
+
nix build
cd "${root}/bbdev"
nix develop -c true
@@ -118,8 +121,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Nix build
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index 40bb560d..ab1a1ee5 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -44,10 +44,10 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
- prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ prepare "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
nix build
cd "${root}/bbdev"
nix develop -c true
@@ -96,8 +96,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: DC area
@@ -163,8 +164,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Chip UVM
@@ -217,8 +219,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: FPGA buildbitstream
@@ -259,36 +262,37 @@ jobs:
matrix:
include:
- chip: toy
- run_fpga_check: true
+ run_fpga_elf: true
run_fpga_pk: true
- chip: pebble
- run_fpga_check: true
+ run_fpga_elf: true
run_fpga_pk: true
- chip: goban
- run_fpga_check: true
+ run_fpga_elf: true
run_fpga_pk: false
- chip: poly
- run_fpga_check: true
+ run_fpga_elf: true
run_fpga_pk: false
- chip: multi-rocket
- run_fpga_check: true
+ run_fpga_elf: true
run_fpga_pk: false
env:
BB_ROOT: ~/Code/buckyball
steps:
- name: Enter repo lock
- if: matrix.run_fpga_check
+ if: matrix.run_fpga_elf || matrix.run_fpga_pk
shell: zsh {0}
run: |
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: FPGA check
- if: matrix.run_fpga_check
+ if: matrix.run_fpga_elf || matrix.run_fpga_pk
shell: zsh {0}
run: |
set -euo pipefail
@@ -300,10 +304,13 @@ jobs:
printf '%s\n' "${bits[@]}" >&2
exit 1
fi
- nix develop -c bbdev compiler --build "--chip ${{ matrix.chip }}"
- nix develop -c bbdev workload --build "--chip ${{ matrix.chip }}"
- nix develop -c bbdev workload --tohex "--chip ${{ matrix.chip }}"
- nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test elf-tests"
+
+ if [[ "${{ matrix.run_fpga_elf }}" == "true" ]]; then
+ nix develop -c bbdev compiler --build "--chip ${{ matrix.chip }}"
+ nix develop -c bbdev workload --build "--chip ${{ matrix.chip }}"
+ nix develop -c bbdev workload --tohex "--chip ${{ matrix.chip }}"
+ nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test elf-tests"
+ fi
if [[ "${{ matrix.run_fpga_pk }}" == "true" ]]; then
nix develop -c bbdev kernel --build "--chip ${{ matrix.chip }}"
@@ -311,7 +318,7 @@ jobs:
fi
- name: Exit repo lock
- if: always() && matrix.run_fpga_check
+ if: always() && (matrix.run_fpga_elf || matrix.run_fpga_pk)
shell: zsh {0}
run: |
set -euo pipefail
@@ -331,10 +338,10 @@ jobs:
model: lenet
- chip: pebble
model: mobilenet
- - chip: pebble
- model: resnet
- - chip: pebble
- model: yolo
+ # - chip: pebble
+ # model: resnet
+ # - chip: pebble
+ # model: yolo
env:
BB_ROOT: ~/Code/buckyball
steps:
@@ -344,8 +351,9 @@ jobs:
set -euo pipefail
root="${BB_ROOT/#\~/$HOME}"
source "${root}/.github/scripts/setproxy.sh"
- git -C "${root}" fetch --force --prune --no-recurse-submodules origin "${CHECKOUT_SHA}"
- git -C "${root}" show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
+ cd "${root}"
+ git fetch --force --prune origin "${CHECKOUT_SHA}"
+ git show "${CHECKOUT_SHA}:.github/scripts/ci_repo_lock.sh" | bash -s -- \
enter "${CHECKOUT_SHA}" "${root}" "${CHECKOUT_REF}"
- name: Model build
diff --git a/arch/build.sc b/arch/build.sc
index 89710311..4f01ca4b 100644
--- a/arch/build.sc
+++ b/arch/build.sc
@@ -11,12 +11,13 @@ object protoJava extends JavaModule {
os.pwd / os.up / "bbdev" / "api" / "steps" / "config" / "scripts" / "proto"
}
+ def protoSources = T.sources {
+ Seq(PathRef(protoDir() / "chip.proto"))
+ }
+
def generatedSources = T {
val dir = protoDir()
- val proto = dir / "chip.proto"
- if (!os.exists(proto)) {
- throw new Exception(s"missing chip.proto: $proto")
- }
+ val proto = protoSources().head.path
os.proc("protoc", s"-I$dir", s"--java_out=${T.dest}", proto).call()
Seq(PathRef(T.dest))
}
@@ -53,14 +54,9 @@ object bank extends FrameworkModule {
override def moduleDeps = Seq(axis)
}
-object cache extends FrameworkModule {
- override def moduleRoot = frameworkRoot / "mem-core" / "cache"
- override def moduleDeps = Seq(chi)
-}
-
object coherence extends FrameworkModule {
override def moduleRoot = frameworkRoot / "mem-core" / "coherence"
- override def moduleDeps = Seq(chi, cache)
+ override def moduleDeps = Seq(chi)
}
object rvv extends FrameworkModule {
@@ -75,7 +71,7 @@ object seed extends FrameworkModule {
object root_chip extends FrameworkModule {
override def moduleRoot = frameworkRoot / "root" / "root-chip"
- override def moduleDeps = Seq(axis, chi, bank, coherence, cache)
+ override def moduleDeps = Seq(axis, chi, bank, coherence)
}
object root_core extends FrameworkModule {
@@ -109,7 +105,6 @@ object buckyball extends SbtModule { m =>
chi,
bank,
coherence,
- cache,
rvv,
seed,
root_chip,
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_checker.svh b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_checker.svh
index ba85d6fe..a11f577c 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_checker.svh
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_checker.svh
@@ -1,5 +1,5 @@
-class checker extends uvm_component;
- `uvm_component_utils(checker)
+class arbiter_checker extends uvm_component;
+ `uvm_component_utils(arbiter_checker)
virtual arbiter_if vif;
chandle model;
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_driver.svh b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_driver.svh
index 87692aad..9b824014 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_driver.svh
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_driver.svh
@@ -18,8 +18,8 @@ class driver extends uvm_component;
task run_phase(uvm_phase phase);
bit [31:0] data0[3] = '{32'h00000000, 32'hffffffff, 32'haaaaaaaa};
bit [31:0] data1[3] = '{32'hffffffff, 32'h00000000, 32'h55555555};
- bit [ 3:0] keep0[3] = '{4'h1, 4'hf, 4'h5};
- bit [ 3:0] keep1[3] = '{4'hf, 4'h1, 4'ha};
+ bit [3:0] keep0[3] = '{4'h1, 4'hf, 4'h5};
+ bit [3:0] keep1[3] = '{4'hf, 4'h1, 4'ha};
int unsigned index0 = 0;
int unsigned index1 = 0;
int unsigned cycle = 0;
@@ -36,13 +36,13 @@ class driver extends uvm_component;
while (index0 < 3 || index1 < 3) begin
vif.in_valid[0] <= index0 < 3;
vif.in_valid[1] <= index1 < 3;
- vif.in_data[0] <= data0[index0 < 3 ? index0 : 2];
- vif.in_data[1] <= data1[index1 < 3 ? index1 : 2];
- vif.in_keep[0] <= keep0[index0 < 3 ? index0 : 2];
- vif.in_keep[1] <= keep1[index1 < 3 ? index1 : 2];
- vif.in_last[0] <= index0 == 2;
- vif.in_last[1] <= index1 == 2;
- vif.out_ready <= cycle % 3 != 0;
+ vif.in_data[0] <= data0[index0<3?index0 : 2];
+ vif.in_data[1] <= data1[index1<3?index1 : 2];
+ vif.in_keep[0] <= keep0[index0<3?index0 : 2];
+ vif.in_keep[1] <= keep1[index1<3?index1 : 2];
+ vif.in_last[0] <= index0 == 2;
+ vif.in_last[1] <= index1 == 2;
+ vif.out_ready <= cycle % 3 != 0;
@(posedge vif.clock);
if (vif.in_valid[0] && vif.in_ready[0]) index0++;
if (vif.in_valid[1] && vif.in_ready[1]) index1++;
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_interface.sv b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_interface.sv
index 4c05081b..45f3ad70 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_interface.sv
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_interface.sv
@@ -1,9 +1,11 @@
-interface arbiter_if(input logic clock);
+interface arbiter_if (
+ input logic clock
+);
logic reset;
logic [ 1:0] in_valid;
logic [ 1:0] in_ready;
- logic [31:0] in_data[2];
- logic [ 3:0] in_keep[2];
+ logic [31:0] in_data [2];
+ logic [ 3:0] in_keep [2];
logic [ 1:0] in_last;
logic out_valid;
logic out_ready;
@@ -13,7 +15,9 @@ interface arbiter_if(input logic clock);
assert property (@(posedge clock) disable iff (reset) $onehot0(in_ready));
assert property (@(posedge clock) disable iff (reset)
- out_valid && !out_ready |=> out_valid && $stable({out_data, out_keep, out_last}));
+ out_valid && !out_ready |=> out_valid && $stable(
+ {out_data, out_keep, out_last}
+ ));
cover property (@(posedge clock) disable iff (reset) &in_valid);
cover property (@(posedge clock) disable iff (reset) in_valid[0] && in_ready[0]);
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_tb.sv b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_tb.sv
index b827a686..9d851613 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_tb.sv
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_tb.sv
@@ -6,27 +6,27 @@ module arbiter_tb;
logic reset = 1'b0;
always #5 clock = ~clock;
- arbiter_if source_if(clock);
+ arbiter_if source_if (clock);
assign source_if.reset = reset;
PacketArbiter dut (
- .clock(clock),
- .reset(reset),
- .io_in_0_ready(source_if.in_ready[0]),
- .io_in_0_valid(source_if.in_valid[0]),
- .io_in_0_bits_tdata(source_if.in_data[0]),
- .io_in_0_bits_tkeep(source_if.in_keep[0]),
- .io_in_0_bits_tlast(source_if.in_last[0]),
- .io_in_1_ready(source_if.in_ready[1]),
- .io_in_1_valid(source_if.in_valid[1]),
- .io_in_1_bits_tdata(source_if.in_data[1]),
- .io_in_1_bits_tkeep(source_if.in_keep[1]),
- .io_in_1_bits_tlast(source_if.in_last[1]),
- .io_out_ready(source_if.out_ready),
- .io_out_valid(source_if.out_valid),
- .io_out_bits_tdata(source_if.out_data),
- .io_out_bits_tkeep(source_if.out_keep),
- .io_out_bits_tlast(source_if.out_last)
+ .clock(clock),
+ .reset(reset),
+ .io_in_0_ready(source_if.in_ready[0]),
+ .io_in_0_valid(source_if.in_valid[0]),
+ .io_in_0_bits_tdata(source_if.in_data[0]),
+ .io_in_0_bits_tkeep(source_if.in_keep[0]),
+ .io_in_0_bits_tlast(source_if.in_last[0]),
+ .io_in_1_ready(source_if.in_ready[1]),
+ .io_in_1_valid(source_if.in_valid[1]),
+ .io_in_1_bits_tdata(source_if.in_data[1]),
+ .io_in_1_bits_tkeep(source_if.in_keep[1]),
+ .io_in_1_bits_tlast(source_if.in_last[1]),
+ .io_out_ready(source_if.out_ready),
+ .io_out_valid(source_if.out_valid),
+ .io_out_bits_tdata(source_if.out_data),
+ .io_out_bits_tkeep(source_if.out_keep),
+ .io_out_bits_tlast(source_if.out_last)
);
initial begin
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_test.svh b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_test.svh
index 89db5b42..76f8ec6a 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_test.svh
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/arbiter_test.svh
@@ -2,7 +2,7 @@ class env extends uvm_env;
`uvm_component_utils(env)
driver source;
- checker monitor;
+ arbiter_checker monitor;
function new(string name, uvm_component parent);
super.new(name, parent);
@@ -10,8 +10,8 @@ class env extends uvm_env;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
- source = driver::type_id::create("source", this);
- monitor = checker::type_id::create("monitor", this);
+ source = driver::type_id::create("source", this);
+ monitor = arbiter_checker::type_id::create("monitor", this);
endfunction
endclass
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/interface.sv b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/interface.sv
index 2e75047f..b8f0e35a 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/interface.sv
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/interface.sv
@@ -1,4 +1,6 @@
-interface axis_if(input logic clock);
+interface axis_if (
+ input logic clock
+);
logic reset;
logic tvalid;
logic tready;
@@ -7,8 +9,9 @@ interface axis_if(input logic clock);
logic tlast;
property payload_stable_during_stall;
- @(posedge clock) disable iff (reset)
- tvalid && !tready |=> tvalid && $stable({tdata, tkeep, tlast});
+ @(posedge clock) disable iff (reset) tvalid && !tready |=> tvalid && $stable(
+ {tdata, tkeep, tlast}
+ );
endproperty
assert property (payload_stable_during_stall);
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/master_tb.sv b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/master_tb.sv
index 5fb2d0ae..746daee0 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/master_tb.sv
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/master_tb.sv
@@ -6,25 +6,25 @@ module master_tb;
logic reset = 1'b0;
always #5 clock = ~clock;
- axis_if source_if(clock);
- axis_if sink_if(clock);
+ axis_if source_if (clock);
+ axis_if sink_if (clock);
assign source_if.reset = reset;
assign sink_if.reset = reset;
Master dut (
- .clock(clock),
- .reset(reset),
- .io_in_ready(source_if.tready),
- .io_in_valid(source_if.tvalid),
- .io_in_bits_tdata(source_if.tdata),
- .io_in_bits_tkeep(source_if.tkeep),
- .io_in_bits_tlast(source_if.tlast),
- .io_axis_tvalid(sink_if.tvalid),
- .io_axis_tready(sink_if.tready),
- .io_axis_tdata(sink_if.tdata),
- .io_axis_tkeep(sink_if.tkeep),
- .io_axis_tlast(sink_if.tlast)
+ .clock(clock),
+ .reset(reset),
+ .io_in_ready(source_if.tready),
+ .io_in_valid(source_if.tvalid),
+ .io_in_bits_tdata(source_if.tdata),
+ .io_in_bits_tkeep(source_if.tkeep),
+ .io_in_bits_tlast(source_if.tlast),
+ .io_axis_tvalid(sink_if.tvalid),
+ .io_axis_tready(sink_if.tready),
+ .io_axis_tdata(sink_if.tdata),
+ .io_axis_tkeep(sink_if.tkeep),
+ .io_axis_tlast(sink_if.tlast)
);
initial begin
diff --git a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/slave_tb.sv b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/slave_tb.sv
index 33a90a37..aceba229 100644
--- a/arch/src/main/scala/framework/mem-core/axis/src/main/resources/slave_tb.sv
+++ b/arch/src/main/scala/framework/mem-core/axis/src/main/resources/slave_tb.sv
@@ -6,25 +6,25 @@ module slave_tb;
logic reset = 1'b0;
always #5 clock = ~clock;
- axis_if source_if(clock);
- axis_if sink_if(clock);
+ axis_if source_if (clock);
+ axis_if sink_if (clock);
assign source_if.reset = reset;
assign sink_if.reset = reset;
Slave dut (
- .clock(clock),
- .reset(reset),
- .io_axis_tvalid(source_if.tvalid),
- .io_axis_tready(source_if.tready),
- .io_axis_tdata(source_if.tdata),
- .io_axis_tkeep(source_if.tkeep),
- .io_axis_tlast(source_if.tlast),
- .io_out_ready(sink_if.tready),
- .io_out_valid(sink_if.tvalid),
- .io_out_bits_tdata(sink_if.tdata),
- .io_out_bits_tkeep(sink_if.tkeep),
- .io_out_bits_tlast(sink_if.tlast)
+ .clock(clock),
+ .reset(reset),
+ .io_axis_tvalid(source_if.tvalid),
+ .io_axis_tready(source_if.tready),
+ .io_axis_tdata(source_if.tdata),
+ .io_axis_tkeep(source_if.tkeep),
+ .io_axis_tlast(source_if.tlast),
+ .io_out_ready(sink_if.tready),
+ .io_out_valid(sink_if.tvalid),
+ .io_out_bits_tdata(sink_if.tdata),
+ .io_out_bits_tkeep(sink_if.tkeep),
+ .io_out_bits_tlast(sink_if.tlast)
);
initial begin
diff --git a/arch/src/main/scala/framework/mem-core/cache/build.sc b/arch/src/main/scala/framework/mem-core/cache/build.sc
deleted file mode 100644
index e512a5ce..00000000
--- a/arch/src/main/scala/framework/mem-core/cache/build.sc
+++ /dev/null
@@ -1,21 +0,0 @@
-import mill._
-import mill.scalalib._
-
-trait ChiselModule extends SbtModule {
- def moduleRoot: os.Path
-
- override def millSourcePath = moduleRoot
- override def scalaVersion = "2.13.16"
- override def ivyDeps = Agg(ivy"org.chipsalliance::chisel:6.7.0")
- override def scalacPluginIvyDeps = Agg(ivy"org.chipsalliance:::chisel-plugin:6.7.0")
- override def scalacOptions = Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Ymacro-annotations")
-}
-
-object chi extends ChiselModule {
- override def moduleRoot = os.pwd / os.up / "chi"
-}
-
-object cache extends ChiselModule {
- override def moduleRoot = os.pwd
- override def moduleDeps = Seq(chi)
-}
diff --git a/arch/src/main/scala/framework/mem-core/cache/src/csrc/README.md b/arch/src/main/scala/framework/mem-core/cache/src/csrc/README.md
deleted file mode 100644
index e69de29b..00000000
diff --git a/arch/src/main/scala/framework/mem-core/cache/src/main/resources/README.md b/arch/src/main/scala/framework/mem-core/cache/src/main/resources/README.md
deleted file mode 100644
index e69de29b..00000000
diff --git a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/Emit.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/Emit.scala
index 25292e34..53b5b7fc 100644
--- a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/Emit.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/Emit.scala
@@ -1,5 +1,7 @@
package memcore.bus.chi
+import memcore.bus.chi.snf.SramEndpoint
+
object Emit extends App {
val p = Params()
require((new RequestFlit(p)).flitWidth == 137)
diff --git a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/ChiHome.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/hnf/ChiHome.scala
similarity index 99%
rename from arch/src/main/scala/framework/mem-core/coherence/src/main/scala/ChiHome.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/hnf/ChiHome.scala
index 504fe2bc..1483d9e2 100644
--- a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/ChiHome.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/hnf/ChiHome.scala
@@ -1,8 +1,9 @@
-package memcore.memory.coherence
+package memcore.bus.chi.hnf
import chisel3._
import chisel3.util._
import memcore.bus.chi._
+import memcore.bus.chi.snf.{LineRequest, LineResponse}
// A finite-address, precise-directory Home. One serialized transaction per Home;
// CompAck closes a read grant before another request can observe its directory state.
diff --git a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/BankedChiCache.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/BankedChiCache.scala
similarity index 99%
rename from arch/src/main/scala/framework/mem-core/cache/src/main/scala/BankedChiCache.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/BankedChiCache.scala
index cf18cdbc..52a9ab56 100644
--- a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/BankedChiCache.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/BankedChiCache.scala
@@ -1,4 +1,4 @@
-package memcore.memory.cache
+package memcore.bus.chi.rnf
import chisel3._
import chisel3.util._
diff --git a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/CachePort.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/CachePort.scala
similarity index 96%
rename from arch/src/main/scala/framework/mem-core/cache/src/main/scala/CachePort.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/CachePort.scala
index f30681c1..1efe2286 100644
--- a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/CachePort.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/CachePort.scala
@@ -1,4 +1,4 @@
-package memcore.memory.cache
+package memcore.bus.chi.rnf
import chisel3._
import memcore.bus.chi.Params
diff --git a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/ChiCache.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/ChiCache.scala
similarity index 99%
rename from arch/src/main/scala/framework/mem-core/cache/src/main/scala/ChiCache.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/ChiCache.scala
index bcf49abd..c96bb7b4 100644
--- a/arch/src/main/scala/framework/mem-core/cache/src/main/scala/ChiCache.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rnf/ChiCache.scala
@@ -1,4 +1,4 @@
-package memcore.memory.cache
+package memcore.bus.chi.rnf
import chisel3._
import chisel3.util._
diff --git a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/NpuRegion.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rni/NpuRegion.scala
similarity index 99%
rename from arch/src/main/scala/framework/mem-core/coherence/src/main/scala/NpuRegion.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/rni/NpuRegion.scala
index ba3cb402..38174b71 100644
--- a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/NpuRegion.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/rni/NpuRegion.scala
@@ -1,4 +1,4 @@
-package memcore.memory.coherence
+package memcore.bus.chi.rni
import chisel3._
import chisel3.util._
diff --git a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/MemoryNode.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/MemoryNode.scala
similarity index 99%
rename from arch/src/main/scala/framework/mem-core/chi/src/main/scala/MemoryNode.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/MemoryNode.scala
index 17e8528e..ba965640 100644
--- a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/MemoryNode.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/MemoryNode.scala
@@ -1,8 +1,9 @@
-package memcore.bus.chi
+package memcore.bus.chi.snf
import chisel3._
import chisel3.util._
import chisel3.experimental.hierarchy.{instantiable, public}
+import memcore.bus.chi._
class LineRequest(p: Params) extends Bundle {
val id = UInt(p.txnIdBits.W)
diff --git a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/SramEndpoint.scala b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/SramEndpoint.scala
similarity index 98%
rename from arch/src/main/scala/framework/mem-core/chi/src/main/scala/SramEndpoint.scala
rename to arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/SramEndpoint.scala
index c5857554..98a103d7 100644
--- a/arch/src/main/scala/framework/mem-core/chi/src/main/scala/SramEndpoint.scala
+++ b/arch/src/main/scala/framework/mem-core/chi/src/main/scala/snf/SramEndpoint.scala
@@ -1,8 +1,9 @@
-package memcore.bus.chi
+package memcore.bus.chi.snf
import chisel3._
import chisel3.util._
import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate}
+import memcore.bus.chi._
class SnPort(p: Params) extends Bundle {
val rxReq = Flipped(new Channel((new RequestFlit(p)).flitWidth))
diff --git a/arch/src/main/scala/framework/mem-core/coherence/build.sc b/arch/src/main/scala/framework/mem-core/coherence/build.sc
index 1ef19e7b..856e64cc 100644
--- a/arch/src/main/scala/framework/mem-core/coherence/build.sc
+++ b/arch/src/main/scala/framework/mem-core/coherence/build.sc
@@ -15,12 +15,7 @@ object chi extends ChiselModule {
override def moduleRoot = os.pwd / os.up / "chi"
}
-object cache extends ChiselModule {
- override def moduleRoot = os.pwd / os.up / "cache"
- override def moduleDeps = Seq(chi)
-}
-
object coherence extends ChiselModule {
override def moduleRoot = os.pwd
- override def moduleDeps = Seq(chi, cache)
+ override def moduleDeps = Seq(chi)
}
diff --git a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/CoherentSystem.scala b/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/CoherentSystem.scala
index a02872a1..3b576c44 100644
--- a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/CoherentSystem.scala
+++ b/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/CoherentSystem.scala
@@ -4,7 +4,10 @@ import chisel3._
import chisel3.util._
import chisel3.experimental.hierarchy.{Instance, Instantiate}
import memcore.bus.chi._
-import memcore.memory.cache._
+import memcore.bus.chi.hnf.ChiHome
+import memcore.bus.chi.rnf.{BankedChiCache, CacheAccess, CacheResult}
+import memcore.bus.chi.rni.{NpuBeat, NpuCommand, NpuRegionAgent, RegionDirectory, RegionEntry}
+import memcore.bus.chi.snf.{LineRequest, LineResponse, LineSram}
// Standalone multicore cache + Home + memory. Every protocol direction crosses
// a real CHI credit channel; the crossbar routes flits by destination NodeID.
diff --git a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/RootPageTableWalker.scala b/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/RootPageTableWalker.scala
index a5e99171..d3ba6145 100644
--- a/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/RootPageTableWalker.scala
+++ b/arch/src/main/scala/framework/mem-core/coherence/src/main/scala/RootPageTableWalker.scala
@@ -4,7 +4,7 @@ import chisel3._
import chisel3.util._
import memcore.bus.chi.Params
-import memcore.memory.cache.{CacheAccess, CacheAtomic, CacheResult}
+import memcore.bus.chi.rnf.{CacheAccess, CacheAtomic, CacheResult}
/** Virtual-memory request used by the ROOT-native DTLB/ITLB path. */
class RootTranslationRequest extends Bundle {
diff --git a/arch/src/main/scala/framework/root/root-chip/build.sc b/arch/src/main/scala/framework/root/root-chip/build.sc
index 3ae7a6e2..9f7ab155 100644
--- a/arch/src/main/scala/framework/root/root-chip/build.sc
+++ b/arch/src/main/scala/framework/root/root-chip/build.sc
@@ -27,17 +27,12 @@ object bank extends ChiselModule {
override def moduleDeps = Seq(axis)
}
-object cache extends ChiselModule {
- override def moduleRoot = memCoreRoot / "cache"
- override def moduleDeps = Seq(chi)
-}
-
object coherence extends ChiselModule {
override def moduleRoot = memCoreRoot / "coherence"
- override def moduleDeps = Seq(chi, cache)
+ override def moduleDeps = Seq(chi)
}
object root_chip extends ChiselModule {
override def moduleRoot = os.pwd
- override def moduleDeps = Seq(axis, chi, bank, coherence, cache)
+ override def moduleDeps = Seq(axis, chi, bank, coherence)
}
diff --git a/arch/src/main/scala/framework/root/root-chip/src/main/scala/chip/mesh/CoherentMeshSystem.scala b/arch/src/main/scala/framework/root/root-chip/src/main/scala/chip/mesh/CoherentMeshSystem.scala
index ad5eaa50..28fdf57c 100644
--- a/arch/src/main/scala/framework/root/root-chip/src/main/scala/chip/mesh/CoherentMeshSystem.scala
+++ b/arch/src/main/scala/framework/root/root-chip/src/main/scala/chip/mesh/CoherentMeshSystem.scala
@@ -4,7 +4,10 @@ import chisel3._
import chisel3.util._
import chisel3.experimental.hierarchy.{Instance, Instantiate}
import memcore.bus.chi._
-import memcore.memory.cache._
+import memcore.bus.chi.hnf.ChiHome
+import memcore.bus.chi.rnf.{BankedChiCache, CacheAccess, CacheResult}
+import memcore.bus.chi.rni.{NpuBeat, NpuCommand, NpuRegionAgent, RegionDirectory, RegionEntry}
+import memcore.bus.chi.snf.{LineRequest, LineResponse, LineSram}
import memcore.memory.coherence._
/**
diff --git a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
index cca96cef..a2d500b3 100644
--- a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
+++ b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
@@ -4,7 +4,7 @@ import buckyball.config.{
BoomCoreConfig,
Chip,
CoreInstance,
- CoreParamConfig,
+ CpuConfig,
FrontendConfig,
GpDomainConfig,
MemDomainConfig,
@@ -131,17 +131,19 @@ object ChipLoader {
nCores: Int,
repo: Path
): TileCore = {
- val kind = core.getKind
+ require(core.hasCpu, s"core ${core.getPkg}: missing cpu config")
+ val cpu = core.getCpu
+ val kind = cpu.getKind
kind match {
case "rocket" => parseRocketCoreSlot(core, shared, virtualBankCount, memBallChannelNum, nCores, repo)
case "boom" =>
if (core.getBalldomain.getBallNum > 0) {
throw new RuntimeException(s"core ${core.getPkg}: kind=boom forbids balldomain")
}
- if (!core.hasBoomCore) {
- throw new RuntimeException(s"core ${core.getPkg}: kind=boom missing boom_core")
+ if (!cpu.hasBoom) {
+ throw new RuntimeException(s"core ${core.getPkg}: kind=boom missing cpu.boom")
}
- BoomTileCore(parseBoomCore(core.getBoomCore))
+ BoomTileCore(parseBoomCore(cpu.getBoom))
case other =>
throw new RuntimeException(s"core ${core.getPkg}: unsupported kind '$other'")
}
@@ -155,17 +157,18 @@ object ChipLoader {
nCores: Int,
repo: Path
): RocketTileCore = {
- if (!core.hasRocketCore) {
- throw new RuntimeException(s"core ${core.getPkg}: kind=rocket missing rocket_core")
+ val cpu = core.getCpu
+ if (!cpu.hasRocket) {
+ throw new RuntimeException(s"core ${core.getPkg}: kind=rocket missing cpu.rocket")
}
- val rocket = parseRocketCore(core.getRocketCore)
+ val rocket = parseRocketCore(cpu.getRocket)
val domain = core.getBalldomain
if (domain.getBallNum == 0) {
return RocketTileCore(rocket, None)
}
require(core.hasFrontend, s"core ${core.getPkg} missing frontend config")
require(core.hasGpDomain, s"core ${core.getPkg} missing gpdomain config")
- require(core.hasCore, s"core ${core.getPkg} missing core config")
+ require(cpu.getCoreDataBytes > 0, s"core ${core.getPkg} missing cpu interface config")
val frontend = core.getFrontend
require(
virtualBankCount <= (1 << frontend.getBankIdLen),
@@ -190,7 +193,7 @@ object ChipLoader {
ballDomain = parseBallDomain(core, repo),
frontend = parseFrontend(core.getFrontend),
gpDomain = parseGpDomain(core.getGpDomain),
- core = parseCoreParam(core.getCore),
+ core = parseCoreParam(cpu),
memDomain = parseMemDomain(core.getMem, shared, virtualBankCount),
rocketCore = rocket,
top = TopConfig(memBallChannelNum = memBallChannelNum, nCores = nCores)
@@ -277,7 +280,7 @@ object ChipLoader {
laneScale = gp.getLaneScale
)
- private def parseCoreParam(core: CoreParamConfig): CoreParam =
+ private def parseCoreParam(core: CpuConfig): CoreParam =
CoreParam(
coreDataBytes = core.getCoreDataBytes,
xLen = core.getXLen,
diff --git a/bbdev b/bbdev
index 4f40306b..7dfc7dad 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit 4f40306b6fa8a98b5369bcadfd218bd152fac7b7
+Subproject commit 7dfc7dadf98c128fd854c11d4d402e7f489ad178
diff --git a/examples/balls/gemmini/verify/casegen/Cargo.lock b/examples/balls/gemmini/verify/casegen/Cargo.lock
new file mode 100644
index 00000000..7e0748b4
--- /dev/null
+++ b/examples/balls/gemmini/verify/casegen/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "gemmini-casegen"
+version = "0.1.0"
diff --git a/examples/balls/gemmini/verify/casegen/Cargo.toml b/examples/balls/gemmini/verify/casegen/Cargo.toml
new file mode 100644
index 00000000..6e83ff22
--- /dev/null
+++ b/examples/balls/gemmini/verify/casegen/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "gemmini-casegen"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib"]
diff --git a/examples/balls/gemmini/verify/casegen/src/lib.rs b/examples/balls/gemmini/verify/casegen/src/lib.rs
new file mode 100644
index 00000000..d027d29e
--- /dev/null
+++ b/examples/balls/gemmini/verify/casegen/src/lib.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub extern "C" fn gemmini_casegen_present() -> u32 {
+ 1
+}
diff --git a/examples/balls/gemmini/verify/filelists/gemmini_ball.f b/examples/balls/gemmini/verify/filelists/gemmini_ball.f
new file mode 100644
index 00000000..c4b12100
--- /dev/null
+++ b/examples/balls/gemmini/verify/filelists/gemmini_ball.f
@@ -0,0 +1,29 @@
++incdir+@UVM@/src/ball
++incdir+src
++incdir+src/pkg
++incdir+src/tests
++incdir+@RTL@
+
+@UVM@/src/ball/bb_blink_if.sv
+@RTL@/PE.sv
+@RTL@/AlwaysOutTransposer.sv
+@RTL@/MacUnit.sv
+@RTL@/PE_256.sv
+@RTL@/Tile.sv
+@RTL@/Mesh.sv
+@RTL@/TagQueue.sv
+@RTL@/ram_6x16.sv
+@RTL@/Queue6_TagWithIdAndTotalRows.sv
+@RTL@/MeshWithDelays.sv
+@RTL@/ram_data_16x128.sv
+@RTL@/Queue16_SramReadResp.sv
+@RTL@/GemminiExCtrl.sv
+@RTL@/LoopMatmulUnroller.sv
+@RTL@/LoopConvAddrGen.sv
+@RTL@/LoopConvUnroller.sv
+@RTL@/LoopCmdEncoder.sv
+@RTL@/Arbiter2_LoopCmd.sv
+@RTL@/GemminiBall.sv
+
+src/pkg/gemmini_pkg.sv
+src/tb_top.sv
diff --git a/examples/balls/gemmini/verify/src/common/gemmini_defs.svh b/examples/balls/gemmini/verify/src/common/gemmini_defs.svh
new file mode 100644
index 00000000..c2e9a59d
--- /dev/null
+++ b/examples/balls/gemmini/verify/src/common/gemmini_defs.svh
@@ -0,0 +1,3 @@
+`ifndef GEMMINI_LOOP_WS_CONFIG_BOUNDS_FUNCT7
+`error "GEMMINI_LOOP_WS_CONFIG_BOUNDS_FUNCT7 must be provided by the selected Core ballISA"
+`endif
diff --git a/examples/balls/gemmini/verify/src/pkg/gemmini_pkg.sv b/examples/balls/gemmini/verify/src/pkg/gemmini_pkg.sv
new file mode 100644
index 00000000..a74a62ef
--- /dev/null
+++ b/examples/balls/gemmini/verify/src/pkg/gemmini_pkg.sv
@@ -0,0 +1,7 @@
+package gemmini_pkg;
+ import uvm_pkg::*;
+ `include "uvm_macros.svh"
+
+ `include "common/gemmini_defs.svh"
+ `include "tests/gemmini_test.svh"
+endpackage
diff --git a/examples/balls/gemmini/verify/src/tb_top.sv b/examples/balls/gemmini/verify/src/tb_top.sv
new file mode 100644
index 00000000..be620460
--- /dev/null
+++ b/examples/balls/gemmini/verify/src/tb_top.sv
@@ -0,0 +1,81 @@
+module tb_top;
+ import uvm_pkg::*;
+ import gemmini_pkg::*;
+
+ bb_blink_if #(`BB_IN_BW, `BB_OUT_BW) intf ();
+
+ GemminiBall dut (
+ .clock(intf.clock),
+ .reset(intf.reset),
+ .io_channelReady(1'b1),
+ .io_cmdReq_ready(intf.cmd_req_ready),
+ .io_cmdReq_valid(intf.cmd_req_valid),
+ .io_cmdReq_bits_cmd_bid(intf.cmd_req_bits_cmd_bid),
+ .io_cmdReq_bits_cmd_funct7(intf.cmd_req_bits_cmd_funct7),
+ .io_cmdReq_bits_cmd_iter(intf.cmd_req_bits_cmd_iter),
+ .io_cmdReq_bits_cmd_op1_en(intf.cmd_req_bits_cmd_op1_en),
+ .io_cmdReq_bits_cmd_op2_en(intf.cmd_req_bits_cmd_op2_en),
+ .io_cmdReq_bits_cmd_wr_spad_en(intf.cmd_req_bits_cmd_wr_spad_en),
+ .io_cmdReq_bits_cmd_op1_from_spad(intf.cmd_req_bits_cmd_op1_from_spad),
+ .io_cmdReq_bits_cmd_op2_from_spad(intf.cmd_req_bits_cmd_op2_from_spad),
+ .io_cmdReq_bits_cmd_special(intf.cmd_req_bits_cmd_special),
+ .io_cmdReq_bits_cmd_op1_bank(intf.cmd_req_bits_cmd_op1_bank),
+ .io_cmdReq_bits_cmd_op2_bank(intf.cmd_req_bits_cmd_op2_bank),
+ .io_cmdReq_bits_cmd_wr_bank(intf.cmd_req_bits_cmd_wr_bank),
+ .io_cmdReq_bits_cmd_op1_col(intf.cmd_req_bits_cmd_op1_col),
+ .io_cmdReq_bits_cmd_op2_col(intf.cmd_req_bits_cmd_op2_col),
+ .io_cmdReq_bits_cmd_wr_col(intf.cmd_req_bits_cmd_wr_col),
+ .io_cmdReq_bits_cmd_meta_bank(intf.cmd_req_bits_cmd_meta_bank),
+ .io_cmdReq_bits_cmd_rs1(intf.cmd_req_bits_cmd_rs1),
+ .io_cmdReq_bits_cmd_rs2(intf.cmd_req_bits_cmd_rs2),
+ .io_cmdReq_bits_rob_id(intf.cmd_req_bits_rob_id),
+ .io_cmdReq_bits_is_sub(intf.cmd_req_bits_is_sub),
+ .io_cmdReq_bits_sub_rob_id(intf.cmd_req_bits_sub_rob_id),
+ .io_cmdResp_ready(intf.cmd_resp_ready),
+ .io_cmdResp_valid(intf.cmd_resp_valid),
+ .io_cmdResp_bits_rob_id(intf.cmd_resp_bits_rob_id),
+ .io_cmdResp_bits_is_sub(intf.cmd_resp_bits_is_sub),
+ .io_cmdResp_bits_sub_rob_id(intf.cmd_resp_bits_sub_rob_id),
+ .io_bankRead_0_io_req_ready(intf.bank_read_req_ready[0]),
+ .io_bankRead_0_io_req_valid(intf.bank_read_req_valid[0]),
+ .io_bankRead_0_io_resp_ready(intf.bank_read_resp_ready[0]),
+ .io_bankRead_0_io_resp_valid(intf.bank_read_resp_valid[0]),
+ .io_bankRead_0_io_resp_bits_data(intf.bank_read_resp_data[0]),
+ .io_bankRead_1_io_req_ready(intf.bank_read_req_ready[1]),
+ .io_bankRead_1_io_req_valid(intf.bank_read_req_valid[1]),
+ .io_bankRead_1_io_resp_ready(intf.bank_read_resp_ready[1]),
+ .io_bankRead_1_io_resp_valid(intf.bank_read_resp_valid[1]),
+ .io_bankRead_1_io_resp_bits_data(intf.bank_read_resp_data[1]),
+ .io_bankWrite_0_io_req_ready(intf.bank_write_req_ready[0]),
+ .io_bankWrite_0_io_req_valid(intf.bank_write_req_valid[0]),
+ .io_bankWrite_0_io_resp_ready(intf.bank_write_resp_ready[0]),
+ .io_bankWrite_0_io_resp_valid(intf.bank_write_resp_valid[0]),
+ .io_bankWrite_0_io_resp_bits_ok(intf.bank_write_resp_ok[0]),
+ .io_bankWrite_1_io_req_ready(intf.bank_write_req_ready[1]),
+ .io_bankWrite_1_io_req_valid(intf.bank_write_req_valid[1]),
+ .io_bankWrite_1_io_resp_ready(intf.bank_write_resp_ready[1]),
+ .io_bankWrite_1_io_resp_valid(intf.bank_write_resp_valid[1]),
+ .io_bankWrite_1_io_resp_bits_ok(intf.bank_write_resp_ok[1]),
+ .io_bankWrite_2_io_req_ready(intf.bank_write_req_ready[2]),
+ .io_bankWrite_2_io_req_valid(intf.bank_write_req_valid[2]),
+ .io_bankWrite_2_io_resp_ready(intf.bank_write_resp_ready[2]),
+ .io_bankWrite_2_io_resp_valid(intf.bank_write_resp_valid[2]),
+ .io_bankWrite_2_io_resp_bits_ok(intf.bank_write_resp_ok[2]),
+ .io_bankWrite_3_io_req_ready(intf.bank_write_req_ready[3]),
+ .io_bankWrite_3_io_req_valid(intf.bank_write_req_valid[3]),
+ .io_bankWrite_3_io_resp_ready(intf.bank_write_resp_ready[3]),
+ .io_bankWrite_3_io_resp_valid(intf.bank_write_resp_valid[3]),
+ .io_bankWrite_3_io_resp_bits_ok(intf.bank_write_resp_ok[3]),
+ .io_subRobReq_ready(intf.sub_rob_req_ready)
+ );
+
+ initial begin
+ intf.clock = 1'b0;
+ forever #5 intf.clock = ~intf.clock;
+ end
+
+ initial begin
+ uvm_config_db#(virtual bb_blink_if #(`BB_IN_BW, `BB_OUT_BW))::set(null, "*", "vif", intf);
+ run_test("gemmini_ball_test");
+ end
+endmodule
diff --git a/examples/balls/gemmini/verify/src/tests/gemmini_test.svh b/examples/balls/gemmini/verify/src/tests/gemmini_test.svh
new file mode 100644
index 00000000..f986e8e0
--- /dev/null
+++ b/examples/balls/gemmini/verify/src/tests/gemmini_test.svh
@@ -0,0 +1,98 @@
+class gemmini_ball_test extends uvm_test;
+ `uvm_component_utils(gemmini_ball_test)
+
+ typedef virtual bb_blink_if #(`BB_IN_BW, `BB_OUT_BW) vif_t;
+ vif_t vif;
+
+ function new(string name, uvm_component parent);
+ super.new(name, parent);
+ endfunction
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ if (!uvm_config_db#(vif_t)::get(this, "", "vif", vif))
+ `uvm_fatal("NOVIF", "bb_blink_if not found")
+ endfunction
+
+ task run_phase(uvm_phase phase);
+ int cycles;
+ int unsigned bid;
+ phase.raise_objection(this);
+ apply_reset();
+
+ @(negedge vif.clock);
+ if (!$value$plusargs("BID=%d", bid)) `uvm_fatal("BID", "+BID is required")
+ vif.cmd_req_bits_cmd_bid = bid[4:0];
+ vif.cmd_req_bits_cmd_funct7 = `GEMMINI_LOOP_WS_CONFIG_BOUNDS_FUNCT7;
+ vif.cmd_req_bits_cmd_iter = '0;
+ vif.cmd_req_bits_cmd_op1_en = 1'b0;
+ vif.cmd_req_bits_cmd_op2_en = 1'b0;
+ vif.cmd_req_bits_cmd_wr_spad_en = 1'b0;
+ vif.cmd_req_bits_cmd_op1_from_spad = 1'b0;
+ vif.cmd_req_bits_cmd_op2_from_spad = 1'b0;
+ vif.cmd_req_bits_cmd_special = 64'h0003_0002_0001;
+ vif.cmd_req_bits_cmd_op1_bank = '0;
+ vif.cmd_req_bits_cmd_op2_bank = '0;
+ vif.cmd_req_bits_cmd_wr_bank = '0;
+ vif.cmd_req_bits_cmd_op1_col = '0;
+ vif.cmd_req_bits_cmd_op2_col = '0;
+ vif.cmd_req_bits_cmd_wr_col = '0;
+ vif.cmd_req_bits_cmd_meta_bank = '0;
+ vif.cmd_req_bits_cmd_rs1 = '0;
+ vif.cmd_req_bits_cmd_rs2 = '0;
+ vif.cmd_req_bits_rob_id = 4'h9;
+ vif.cmd_req_bits_is_sub = 1'b1;
+ vif.cmd_req_bits_sub_rob_id = 8'h5a;
+ vif.cmd_req_valid = 1'b1;
+
+ cycles = 0;
+ do begin
+ @(posedge vif.clock);
+ cycles++;
+ if (cycles > 20) `uvm_fatal("TIMEOUT", "Gemmini config command was not accepted")
+ end while (!vif.cmd_req_ready);
+ @(negedge vif.clock);
+ vif.cmd_req_valid = 1'b0;
+
+ if (!vif.cmd_resp_valid) `uvm_fatal("RESP", "Gemmini config response was not observed")
+ if (vif.cmd_resp_bits_rob_id !== 4'h9 || vif.cmd_resp_bits_is_sub !== 1'b1 ||
+ vif.cmd_resp_bits_sub_rob_id !== 8'h5a)
+ `uvm_fatal("RESP", $sformatf(
+ "metadata mismatch: rob=%0h is_sub=%0b sub_rob=%0h",
+ vif.cmd_resp_bits_rob_id,
+ vif.cmd_resp_bits_is_sub,
+ vif.cmd_resp_bits_sub_rob_id
+ ))
+ for (int i = 0; i < `BB_IN_BW; i++) begin
+ if (vif.bank_read_req_valid[i])
+ `uvm_fatal("BANK", "Gemmini config command unexpectedly read a bank")
+ end
+ for (int i = 0; i < `BB_OUT_BW; i++) begin
+ if (vif.bank_write_req_valid[i])
+ `uvm_fatal("BANK", "Gemmini config command unexpectedly wrote a bank")
+ end
+
+ `uvm_info("GEMMINI", "loop-ws config command passed", UVM_LOW)
+ phase.drop_objection(this);
+ endtask
+
+ task apply_reset();
+ vif.cmd_req_valid = 1'b0;
+ vif.cmd_resp_ready = 1'b1;
+ vif.sub_rob_req_ready = 1'b1;
+ for (int i = 0; i < `BB_IN_BW; i++) begin
+ vif.bank_read_req_ready[i] = 1'b1;
+ vif.bank_read_resp_valid[i] = 1'b0;
+ vif.bank_read_resp_data[i] = '0;
+ end
+ for (int i = 0; i < `BB_OUT_BW; i++) begin
+ vif.bank_write_req_ready[i] = 1'b1;
+ vif.bank_write_resp_valid[i] = 1'b0;
+ vif.bank_write_resp_ok[i] = 1'b1;
+ end
+ vif.reset = 1'b1;
+ repeat (5) @(posedge vif.clock);
+ vif.reset = 1'b0;
+ repeat (2) @(posedge vif.clock);
+ endtask
+endclass
diff --git a/examples/chips/goban/configs/chip.toml b/examples/chips/goban/configs/chip.toml
index c019a8fd..4ec7a7a5 100644
--- a/examples/chips/goban/configs/chip.toml
+++ b/examples/chips/goban/configs/chip.toml
@@ -4,3 +4,7 @@ include = "designs/goban.toml"
[sims]
verilator = "sims.verilator.BuckyballGoban4CoreVerilatorConfig"
p2e = "sims.p2e.BuckyballGoban4CoreLinuxP2EConfig"
+
+[uvm]
+balls = ["smatmul", "toint8", "int2fp", "transpose"]
+ips = []
diff --git a/examples/chips/multi-rocket/configs/chip.toml b/examples/chips/multi-rocket/configs/chip.toml
index 505b0694..39d68a9a 100644
--- a/examples/chips/multi-rocket/configs/chip.toml
+++ b/examples/chips/multi-rocket/configs/chip.toml
@@ -4,3 +4,7 @@ include = "designs/multi-rocket.toml"
[sims]
verilator = "sims.verilator.MultiRocket32CoreVerilatorConfig"
p2e = "sims.p2e.MultiRocket32CoreLinuxP2EConfig"
+
+[uvm]
+balls = []
+ips = ["axis"]
diff --git a/examples/chips/pebble/configs/chip.toml b/examples/chips/pebble/configs/chip.toml
index 8a2a4ead..e1281687 100644
--- a/examples/chips/pebble/configs/chip.toml
+++ b/examples/chips/pebble/configs/chip.toml
@@ -6,3 +6,7 @@ verilator = "sims.verilator.BuckyballPebbleVerilatorConfig"
p2e = "sims.p2e.P2EPebbleLinuxConfig"
tapeout = "sims.tapeout.BuckyballPebbleTapeoutConfig"
firesim = "sims.firesim.FireSimBuckyballPebbleConfig"
+
+[uvm]
+balls = ["transpose", "smatmul", "im2col", "toint8", "int2fp", "lut", "maxpool", "int8add", "int8mul", "matadd"]
+ips = []
diff --git a/examples/chips/poly/configs/chip.toml b/examples/chips/poly/configs/chip.toml
index 1e38dff3..9f4a4282 100644
--- a/examples/chips/poly/configs/chip.toml
+++ b/examples/chips/poly/configs/chip.toml
@@ -4,3 +4,7 @@ include = "designs/poly.toml"
[sims]
verilator = "sims.verilator.BuckyballPolyVerilatorConfig"
p2e = "sims.p2e.BuckyballPolyLinuxP2EConfig"
+
+[uvm]
+balls = ["smatmul", "toint8", "int2fp", "transpose"]
+ips = []
diff --git a/examples/chips/toy/configs/chip.toml b/examples/chips/toy/configs/chip.toml
index c2508823..7fd79032 100644
--- a/examples/chips/toy/configs/chip.toml
+++ b/examples/chips/toy/configs/chip.toml
@@ -5,3 +5,7 @@ include = "designs/toy.toml"
verilator = "sims.verilator.BuckyballToyVerilatorConfig"
p2e = "sims.p2e.P2EToyLinuxConfig"
firesim = "sims.firesim.FireSimBuckyballToyConfig"
+
+[uvm]
+balls = ["gemmini"]
+ips = ["axis"]
diff --git a/examples/cores/boom/configs/boomCore.toml b/examples/cores/boom/configs/cpu/boom/boomCore.toml
similarity index 100%
rename from examples/cores/boom/configs/boomCore.toml
rename to examples/cores/boom/configs/cpu/boom/boomCore.toml
diff --git a/examples/cores/boom/configs/cpu/default.toml b/examples/cores/boom/configs/cpu/default.toml
new file mode 100644
index 00000000..6e81612a
--- /dev/null
+++ b/examples/cores/boom/configs/cpu/default.toml
@@ -0,0 +1,2 @@
+kind = "boom"
+config = "./boom/boomCore.toml"
diff --git a/examples/cores/boom/configs/default.toml b/examples/cores/boom/configs/default.toml
index 90a11178..c691e6a4 100644
--- a/examples/cores/boom/configs/default.toml
+++ b/examples/cores/boom/configs/default.toml
@@ -1,6 +1,5 @@
# Boom-only core configuration
-kind = "boom"
memdomain = "memdomains/default.toml"
balldomain = "balldomains/default.toml"
-boomCore = "boomCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/pebble/configs/core/default.toml b/examples/cores/decode/configs/cpu/default.toml
similarity index 51%
rename from examples/cores/pebble/configs/core/default.toml
rename to examples/cores/decode/configs/cpu/default.toml
index ac2a168b..af32891c 100644
--- a/examples/cores/pebble/configs/core/default.toml
+++ b/examples/cores/decode/configs/cpu/default.toml
@@ -1,3 +1,5 @@
+kind = "rocket"
+config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
coreDataBytes = 64
xLen = 64
vaddrBits = 39
diff --git a/examples/cores/decode/configs/default.toml b/examples/cores/decode/configs/default.toml
index fc7c2171..53eaa2fd 100644
--- a/examples/cores/decode/configs/default.toml
+++ b/examples/cores/decode/configs/default.toml
@@ -1,9 +1,7 @@
# Decode Core Configuration (default)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/prefill/configs/core/default.toml b/examples/cores/goban/configs/cpu/default.toml
similarity index 51%
rename from examples/cores/prefill/configs/core/default.toml
rename to examples/cores/goban/configs/cpu/default.toml
index ac2a168b..af32891c 100644
--- a/examples/cores/prefill/configs/core/default.toml
+++ b/examples/cores/goban/configs/cpu/default.toml
@@ -1,3 +1,5 @@
+kind = "rocket"
+config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
coreDataBytes = 64
xLen = 64
vaddrBits = 39
diff --git a/examples/cores/goban/configs/default.toml b/examples/cores/goban/configs/default.toml
index 29a2941f..9b86a2ce 100644
--- a/examples/cores/goban/configs/default.toml
+++ b/examples/cores/goban/configs/default.toml
@@ -1,9 +1,7 @@
# Goban Core Configuration (default)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/goban/configs/core/default.toml b/examples/cores/pebble/configs/cpu/default.toml
similarity index 61%
rename from examples/cores/goban/configs/core/default.toml
rename to examples/cores/pebble/configs/cpu/default.toml
index ac2a168b..2420ad1e 100644
--- a/examples/cores/goban/configs/core/default.toml
+++ b/examples/cores/pebble/configs/cpu/default.toml
@@ -1,3 +1,5 @@
+kind = "rocket"
+config = "./rocket/rocketCore.toml"
coreDataBytes = 64
xLen = 64
vaddrBits = 39
diff --git a/examples/cores/pebble/configs/cpu/rocket/rocketCore.toml b/examples/cores/pebble/configs/cpu/rocket/rocketCore.toml
new file mode 100644
index 00000000..c84e83e9
--- /dev/null
+++ b/examples/cores/pebble/configs/cpu/rocket/rocketCore.toml
@@ -0,0 +1,32 @@
+xLen = 64
+pgLevels = 3
+useVM = true
+useZba = true
+useZbb = true
+useZbs = true
+haveCFlush = false
+
+[mulDiv]
+enable = true
+mulUnroll = 8
+mulEarlyOut = true
+divEarlyOut = true
+
+[fpu]
+enable = true
+minFLen = 16
+fLen = 64
+
+[dcache]
+nSets = 32
+nWays = 4
+nMSHRs = 0
+
+[icache]
+nSets = 64
+nWays = 8
+
+[btb]
+enable = true
+nEntries = 28
+nRAS = 6
diff --git a/examples/cores/pebble/configs/default.toml b/examples/cores/pebble/configs/default.toml
index 8f6d405c..07f7d433 100644
--- a/examples/cores/pebble/configs/default.toml
+++ b/examples/cores/pebble/configs/default.toml
@@ -1,9 +1,7 @@
# Pebble Core Configuration (default)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/decode/configs/core/default.toml b/examples/cores/prefill/configs/cpu/default.toml
similarity index 51%
rename from examples/cores/decode/configs/core/default.toml
rename to examples/cores/prefill/configs/cpu/default.toml
index ac2a168b..af32891c 100644
--- a/examples/cores/decode/configs/core/default.toml
+++ b/examples/cores/prefill/configs/cpu/default.toml
@@ -1,3 +1,5 @@
+kind = "rocket"
+config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
coreDataBytes = 64
xLen = 64
vaddrBits = 39
diff --git a/examples/cores/prefill/configs/default.toml b/examples/cores/prefill/configs/default.toml
index ece1c2e7..2f58e742 100644
--- a/examples/cores/prefill/configs/default.toml
+++ b/examples/cores/prefill/configs/default.toml
@@ -1,9 +1,7 @@
# Prefill Core Configuration (default)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/rocket/configs/cpu/default.toml b/examples/cores/rocket/configs/cpu/default.toml
new file mode 100644
index 00000000..4d5aca16
--- /dev/null
+++ b/examples/cores/rocket/configs/cpu/default.toml
@@ -0,0 +1,2 @@
+kind = "rocket"
+config = "./rocket/rocketCore.toml"
diff --git a/examples/cores/rocket/configs/rocketCore.toml b/examples/cores/rocket/configs/cpu/rocket/rocketCore.toml
similarity index 100%
rename from examples/cores/rocket/configs/rocketCore.toml
rename to examples/cores/rocket/configs/cpu/rocket/rocketCore.toml
diff --git a/examples/cores/rocket/configs/default.toml b/examples/cores/rocket/configs/default.toml
index e4939c5f..b59e347c 100644
--- a/examples/cores/rocket/configs/default.toml
+++ b/examples/cores/rocket/configs/default.toml
@@ -1,6 +1,5 @@
# Rocket-only core configuration
-kind = "rocket"
memdomain = "memdomains/default.toml"
balldomain = "balldomains/default.toml"
-rocketCore = "rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/toy/configs/core/default.toml b/examples/cores/toy/configs/core/default.toml
deleted file mode 100644
index ac2a168b..00000000
--- a/examples/cores/toy/configs/core/default.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
diff --git a/examples/cores/toy/configs/cpu/default.toml b/examples/cores/toy/configs/cpu/default.toml
new file mode 100644
index 00000000..af32891c
--- /dev/null
+++ b/examples/cores/toy/configs/cpu/default.toml
@@ -0,0 +1,8 @@
+kind = "rocket"
+config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+nPMPs = 8
diff --git a/examples/cores/toy/configs/default.toml b/examples/cores/toy/configs/default.toml
index 8d024f15..071e6987 100644
--- a/examples/cores/toy/configs/default.toml
+++ b/examples/cores/toy/configs/default.toml
@@ -1,9 +1,7 @@
# Toy Core Configuration (default)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/default.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
diff --git a/examples/cores/toy/configs/demo.toml b/examples/cores/toy/configs/demo.toml
index c3b9a707..8c17b28f 100644
--- a/examples/cores/toy/configs/demo.toml
+++ b/examples/cores/toy/configs/demo.toml
@@ -1,9 +1,7 @@
# Toy Core Configuration (demo frontend)
-kind = "rocket"
balldomain = "balldomains/default.toml"
memdomain = "memdomains/default.toml"
frontend = "frontends/demo.toml"
gpdomain = "gpdomains/default.toml"
-core = "core/default.toml"
-rocketCore = "../../rocket/configs/rocketCore.toml"
+cpu = "cpu/default.toml"
From 261a1da18d4a88e2644cb00c558270c05a8bffb3 Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Mon, 21 Sep 2026 15:14:44 +0800
Subject: [PATCH 28/36] [tools/difftest] refactor bankdiff to a decoupled
feature
---
.github/workflows/check.yaml | 6 +-
.github/workflows/regression.yml | 6 +-
arch/src/csrc/include/monitor/trace.h | 11 +-
arch/src/csrc/src/monitor/trace/itrace.cc | 79 +++----
arch/src/csrc/src/monitor/trace/mtrace.cc | 25 --
.../balldomain/rs/reservationStation.scala | 1 +
.../main/scala/framework/dpi/DpiGuard.scala | 3 +
.../scala/framework/frontend/Frontend.scala | 20 +-
.../scala/framework/frontend/boot/Boot.scala | 10 +-
.../frontend/decoder/GobalDecoder.scala | 14 +-
.../frontend/globalrs/GlobalROB.scala | 223 +++++++++++++-----
.../frontend/globalrs/GlobalScheduler.scala | 64 ++---
.../frontend/globalrs/ITraceDPI.scala | 53 ++---
.../sequencer/decoder/DomainDecoder.scala | 2 +-
.../scala/framework/memdomain/MemDomain.scala | 32 ++-
.../framework/memdomain/backend/MTrace.scala | 74 +-----
.../memdomain/backend/MemBackend.scala | 56 ++++-
.../memdomain/backend/MemBackendTypes.scala | 3 +-
.../memdomain/backend/accpipe/AccPipe.scala | 4 +-
.../backend/banks/btrace/BTraceDPI.scala | 64 +++++
.../backend/banks/btrace/BTraceTypes.scala | 13 +
.../privatepath/PrivateMemBackend.scala | 55 +++++
.../memdomain/backend/shared/SharedMem.scala | 16 +-
.../backend/shared/SharedMemBackend.scala | 59 ++++-
.../memdomain/configs/MemDomainParam.scala | 2 +
.../memdomain/frontend/MemFrontend.scala | 2 +-
.../frontend/cmd/decoder/DomainDecoder.scala | 12 +-
.../memdomain/frontend/mem/MemConfiger.scala | 4 +-
.../frontend/mem/dma/StreamReader.scala | 2 +-
.../frontend/mem/dma/StreamWriter.scala | 2 +-
.../memdomain/frontend/mem/tlb/BBTLBIO.scala | 18 +-
.../memdomain/frontend/mem/tlb/TLB.scala | 10 +-
.../frontend/mem/tlb/TLBCluster.scala | 12 +-
.../memdomain/midend/MemMidend.scala | 24 +-
.../system/configloader/ChipLoader.scala | 65 +++--
.../accelerator/BuckyballAccelerator.scala | 25 +-
.../configs/CpuParam.scala} | 15 +-
.../scala/framework/system/tile/BBTile.scala | 23 +-
.../scala/framework/system/tile/Configs.scala | 33 +--
.../scala/framework/top/GlobalConfig.scala | 15 +-
.../framework/top/configs/SimParam.scala | 17 ++
.../framework/top/configs/TopConfig.scala | 14 --
arch/src/main/scala/sims/hash/BankHash.scala | 75 ++++++
.../main/scala/sims/p2e/TargetConfigs.scala | 13 +-
.../scala/sims/verilator/BBSimHarness.scala | 4 +-
.../scala/sims/verilator/TargetConfig.scala | 10 +-
bb-tests/workloads/lib/bbhw/isa/33_mvin.c | 4 +-
bb-tests/workloads/lib/bbhw/isa/34_mvin_2d.c | 4 +-
bbdev | 2 +-
bebop | 2 +-
.../Transforms/LegalizeForLLVMExportBase.cpp | 14 +-
.../Transforms/LegalizeForLLVMExportBase.h | 2 +
.../arch/src/main/scala/LoopCmdEncoder.scala | 2 +-
.../gemmini/emu/src/80_gemmini_loop_ws.rs | 8 +-
.../emu/src/96_gemmini_loop_conv_ws.rs | 8 +-
.../balls/gemmini/emu/src/loop_micro_ops.rs | 2 +-
.../im2col/arch/src/main/scala/Im2col.scala | 1 +
.../regression/batch/p2e/workloads-pk.toml | 2 +-
58 files changed, 853 insertions(+), 488 deletions(-)
create mode 100644 arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceDPI.scala
create mode 100644 arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
rename arch/src/main/scala/framework/system/{core/configs/CoreParam.scala => cpu/configs/CpuParam.scala} (62%)
create mode 100644 arch/src/main/scala/framework/top/configs/SimParam.scala
delete mode 100644 arch/src/main/scala/framework/top/configs/TopConfig.scala
create mode 100644 arch/src/main/scala/sims/hash/BankHash.scala
diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml
index 496468c0..fc38b038 100644
--- a/.github/workflows/check.yaml
+++ b/.github/workflows/check.yaml
@@ -170,9 +170,9 @@ jobs:
root="${BB_ROOT/#\~/$HOME}"
cd "${root}"
nix develop -c bbdev bebop-verilator --clean '--chip ${{ matrix.chip }}'
- nix develop -c bbdev bebop-verilator --verilog '--chip ${{ matrix.chip }}'
- nix develop -c bbdev bebop-verilator --build '--jobs 16 --chip ${{ matrix.chip }}'
- nix develop -c bbdev bebop-verilator --batch '--chip ${{ matrix.chip }} --test elf-tests --clean-before'
+ nix develop -c bbdev bebop-verilator --verilog '--chip ${{ matrix.chip }} --diff'
+ nix develop -c bbdev bebop-verilator --build '--jobs 16 --chip ${{ matrix.chip }} --diff'
+ nix develop -c bbdev bebop-verilator --batch '--chip ${{ matrix.chip }} --test elf-tests --diff --clean-before'
- name: rushB batch
if: matrix.enable_rushb && matrix.run_bemu_elf_tests && matrix.run_bemu_pk_tests && matrix.run_verilator_batch_tests
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index ab1a1ee5..bf6239d1 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -234,7 +234,7 @@ jobs:
for build_dir in "${root}"/bebop/build/"${{ matrix.chip }}"-*(N); do
rm -rf "${build_dir}"
done
- nix develop -c bbdev bebop-p2e --verilog '--chip ${{ matrix.chip }}'
+ nix develop -c bbdev bebop-p2e --verilog '--chip ${{ matrix.chip }} --diff'
nix develop -c bbdev bebop-p2e --buildbitstream '--chip ${{ matrix.chip }}'
bits=("${root}"/bebop/build/"${{ matrix.chip }}"-*/fpgaCompDir/bitstream.bit(N))
if (( ${#bits} != 1 )); then
@@ -309,12 +309,12 @@ jobs:
nix develop -c bbdev compiler --build "--chip ${{ matrix.chip }}"
nix develop -c bbdev workload --build "--chip ${{ matrix.chip }}"
nix develop -c bbdev workload --tohex "--chip ${{ matrix.chip }}"
- nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test elf-tests"
+ nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test elf-tests --diff"
fi
if [[ "${{ matrix.run_fpga_pk }}" == "true" ]]; then
nix develop -c bbdev kernel --build "--chip ${{ matrix.chip }}"
- nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test pk-tests"
+ nix develop -c bbdev bebop-p2e --batch "--chip ${{ matrix.chip }} --bitstream ${bits[1]} --test pk-tests --diff"
fi
- name: Exit repo lock
diff --git a/arch/src/csrc/include/monitor/trace.h b/arch/src/csrc/include/monitor/trace.h
index 055b6ab1..dab0b5f1 100644
--- a/arch/src/csrc/include/monitor/trace.h
+++ b/arch/src/csrc/include/monitor/trace.h
@@ -13,10 +13,13 @@ void dpi_bdb_set_clk(unsigned long long c);
// DPI-C function for instruction trace (itrace)
// Called from GlobalROB when instructions are allocated/issued/completed
-void dpi_itrace(unsigned char is_issue, // 2 = alloc, 1 = issue, 0 = complete
- unsigned int rob_id, unsigned int domain_id, unsigned int funct,
- unsigned long long pc, unsigned long long rs1,
- unsigned long long rs2, unsigned char bank_enable);
+void dpi_itrace(unsigned int is_issue, // 2 = alloc, 1 = issue, 0 = complete
+ unsigned int hart_id_lo, unsigned int hart_id_hi,
+ unsigned int rob_id, unsigned int inst_id_lo,
+ unsigned int inst_id_hi, unsigned int domain_id,
+ unsigned int funct, unsigned int pc_lo, unsigned int pc_hi,
+ unsigned int rs1_lo, unsigned int rs1_hi, unsigned int rs2_lo,
+ unsigned int rs2_hi);
// DPI-C function for memory trace (mtrace)
// Called from MemBackend when read/write requests are made
diff --git a/arch/src/csrc/src/monitor/trace/itrace.cc b/arch/src/csrc/src/monitor/trace/itrace.cc
index 4262d322..34f78a3b 100644
--- a/arch/src/csrc/src/monitor/trace/itrace.cc
+++ b/arch/src/csrc/src/monitor/trace/itrace.cc
@@ -18,26 +18,6 @@ static void init_itrace() {
}
}
-// bank_enable encoding (funct7[6:4]):
-// 000 = none, 001 = 1rd, 010 = 1wr, 011 = 1rd+1wr, 100 = 2rd+1wr
-// 101/110/111 = none (extended opcode space)
-static const char *bank_enable_str(unsigned char enable) {
- switch (enable) {
- case 0:
- return "---";
- case 1:
- return "R--";
- case 2:
- return "--W";
- case 3:
- return "R-W";
- case 4:
- return "RRW";
- default:
- return "---"; // 5,6,7 = no bank access (extended)
- }
-}
-
static void u64_hex(char *buf, size_t n, unsigned long long v) {
int ret = snprintf(buf, n, "0x%016llx", v);
if (ret < 0 || (size_t)ret >= n) {
@@ -48,16 +28,25 @@ static void u64_hex(char *buf, size_t n, unsigned long long v) {
// DPI-C function for instruction trace (itrace)
// Called when an instruction is allocated/issued/completed in GlobalROB
extern "C" void
-dpi_itrace(unsigned char is_issue, // 2 = alloc, 1 = issue, 0 = complete
- unsigned int rob_id, unsigned int domain_id, unsigned int funct,
- unsigned long long pc, unsigned long long rs1,
- unsigned long long rs2, unsigned char bank_enable) {
+dpi_itrace(unsigned int is_issue, // 2 = alloc, 1 = issue, 0 = complete
+ unsigned int hart_id_lo, unsigned int hart_id_hi,
+ unsigned int rob_id, unsigned int inst_id_lo,
+ unsigned int inst_id_hi, unsigned int domain_id, unsigned int funct,
+ unsigned int pc_lo, unsigned int pc_hi, unsigned int rs1_lo,
+ unsigned int rs1_hi, unsigned int rs2_lo, unsigned int rs2_hi) {
if (!bdb_trace_on(BDB_TR_ITRACE)) {
return;
}
init_itrace();
if (itrace_fp) {
+ unsigned long long hart_id =
+ ((unsigned long long)hart_id_hi << 32) | hart_id_lo;
+ unsigned long long inst_id =
+ ((unsigned long long)inst_id_hi << 32) | inst_id_lo;
+ unsigned long long pc = ((unsigned long long)pc_hi << 32) | pc_lo;
+ unsigned long long rs1 = ((unsigned long long)rs1_hi << 32) | rs1_lo;
+ unsigned long long rs2 = ((unsigned long long)rs2_hi << 32) | rs2_lo;
char pc_hex[19];
char rs1_hex[19];
char rs2_hex[19];
@@ -65,29 +54,31 @@ dpi_itrace(unsigned char is_issue, // 2 = alloc, 1 = issue, 0 = complete
u64_hex(rs1_hex, sizeof(rs1_hex), rs1);
u64_hex(rs2_hex, sizeof(rs2_hex), rs2);
if (is_issue == 2) {
- fprintf(
- itrace_fp,
- "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"alloc\",\"rob_id\":%u,"
- "\"domain_id\":%u,\"funct\":\"0x%02x\",\"bank_enable\":%u,"
- "\"bank\":\"%s\",\"pc\":\"%s\",\"rs1\":\"%s\",\"rs2\":\"%s\"}\n",
- (unsigned long long)bdb_rtl_clk, rob_id, domain_id, funct,
- bank_enable, bank_enable_str(bank_enable), pc_hex, rs1_hex, rs2_hex);
+ fprintf(itrace_fp,
+ "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"alloc\",\"hart_"
+ "id\":%llu,"
+ "\"rob_id\":%u,\"inst_id\":%llu,\"domain_id\":%u,\"funct\":\"0x%"
+ "02x\","
+ "\"pc\":\"%s\",\"rs1\":\"%s\",\"rs2\":\"%s\"}\n",
+ (unsigned long long)bdb_rtl_clk, hart_id, rob_id, inst_id,
+ domain_id, funct, pc_hex, rs1_hex, rs2_hex);
} else if (is_issue == 1) {
+ fprintf(itrace_fp,
+ "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"issue\",\"hart_"
+ "id\":%llu,"
+ "\"rob_id\":%u,\"inst_id\":%llu,\"domain_id\":%u,\"funct\":\"0x%"
+ "02x\","
+ "\"pc\":\"%s\",\"rs1\":\"%s\",\"rs2\":\"%s\"}\n",
+ (unsigned long long)bdb_rtl_clk, hart_id, rob_id, inst_id,
+ domain_id, funct, pc_hex, rs1_hex, rs2_hex);
+ } else {
fprintf(
itrace_fp,
- "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"issue\",\"rob_id\":%u,"
- "\"domain_id\":%u,\"funct\":\"0x%02x\",\"bank_enable\":%u,"
- "\"bank\":\"%s\",\"pc\":\"%s\",\"rs1\":\"%s\",\"rs2\":\"%s\"}\n",
- (unsigned long long)bdb_rtl_clk, rob_id, domain_id, funct,
- bank_enable, bank_enable_str(bank_enable), pc_hex, rs1_hex, rs2_hex);
- } else {
- fprintf(itrace_fp,
- "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"complete\",\"rob_"
- "id\":%u,"
- "\"domain_id\":%u,\"funct\":\"0x%02x\",\"bank_enable\":%u,"
- "\"bank\":\"%s\",\"pc\":\"%s\"}\n",
- (unsigned long long)bdb_rtl_clk, rob_id, domain_id, funct,
- bank_enable, bank_enable_str(bank_enable), pc_hex);
+ "{\"type\":\"itrace\",\"clk\":%llu,\"event\":\"complete\","
+ "\"hart_id\":%llu,\"rob_id\":%u,\"inst_id\":%llu,\"domain_id\":%u,"
+ "\"funct\":\"0x%02x\",\"pc\":\"%s\"}\n",
+ (unsigned long long)bdb_rtl_clk, hart_id, rob_id, inst_id, domain_id,
+ funct, pc_hex);
}
fflush(itrace_fp);
}
diff --git a/arch/src/csrc/src/monitor/trace/mtrace.cc b/arch/src/csrc/src/monitor/trace/mtrace.cc
index 2c405881..319d3bb5 100644
--- a/arch/src/csrc/src/monitor/trace/mtrace.cc
+++ b/arch/src/csrc/src/monitor/trace/mtrace.cc
@@ -63,28 +63,3 @@ extern "C" void dpi_mtrace(unsigned char is_write, // 1 = write, 0 = read
fflush(mtrace_fp);
}
}
-
-// DPI-C function for memory trace issue (mtrace_issue)
-// Called when MemMidend issues memory operations
-extern "C" void dpi_mtrace_issue(unsigned int hart_id_lo,
- unsigned int hart_id_hi,
- unsigned char is_shared, unsigned int rob_id,
- unsigned int vbank_id, unsigned int group_id) {
- if (!bdb_trace_on(BDB_TR_MTRACE)) {
- return;
- }
- init_mtrace();
-
- unsigned long long hart_id =
- ((unsigned long long)hart_id_hi << 32) | hart_id_lo;
-
- if (mtrace_fp) {
- fprintf(mtrace_fp,
- "{\"type\":\"mtrace_issue\",\"clk\":%llu,\"event\":\"issue\","
- "\"hart_id\":%llu,\"is_shared\":%u,\"rob_id\":%u,\"vbank_id\":%u,"
- "\"group_id\":%u}\n",
- (unsigned long long)bdb_rtl_clk, hart_id, is_shared, rob_id,
- vbank_id, group_id);
- fflush(mtrace_fp);
- }
-}
diff --git a/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala b/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
index f66acff3..5557170b 100644
--- a/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
+++ b/arch/src/main/scala/framework/balldomain/rs/reservationStation.scala
@@ -131,4 +131,5 @@ class BallReservationStation(val b: GlobalConfig) extends Module {
complete_o.valid := completeArb.io.out.valid
complete_o.bits := completeArb.io.out.bits
completeArb.io.out.ready := complete_o.ready
+
}
diff --git a/arch/src/main/scala/framework/dpi/DpiGuard.scala b/arch/src/main/scala/framework/dpi/DpiGuard.scala
index 1df92506..f85a18c3 100644
--- a/arch/src/main/scala/framework/dpi/DpiGuard.scala
+++ b/arch/src/main/scala/framework/dpi/DpiGuard.scala
@@ -19,6 +19,9 @@ object DpiGuard {
def wrapMTrace(body: String): String =
wrapTraceKind("BUCKYBALL_DISABLE_MTRACE_DPI", body)
+ def wrapBTrace(body: String): String =
+ wrapTraceKind("BUCKYBALL_DISABLE_BTRACE_DPI", body)
+
def wrapPMCTrace(body: String): String =
wrapTraceKind("BUCKYBALL_DISABLE_PMCTRACE_DPI", body)
}
diff --git a/arch/src/main/scala/framework/frontend/Frontend.scala b/arch/src/main/scala/framework/frontend/Frontend.scala
index 2d669abb..bcc0915f 100644
--- a/arch/src/main/scala/framework/frontend/Frontend.scala
+++ b/arch/src/main/scala/framework/frontend/Frontend.scala
@@ -9,6 +9,8 @@ import framework.frontend.globalrs.{GlobalSchedComplete, GlobalSchedIssue, Globa
import framework.top.GlobalConfig
import framework.system.core.rocket.{RoCCCommandBB, RoCCResponseBB}
import framework.balldomain.blink.SubRobRow
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
+import framework.memdomain.backend.shared.SharedMemLayout
/**
* Frontend Module
@@ -17,12 +19,15 @@ import framework.balldomain.blink.SubRobRow
@instantiable
class Frontend(val b: GlobalConfig) extends Module {
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
+
@public
val io = IO(new Bundle {
+ val hartid = Input(UInt(b.cpu.xLen.W))
// RoCC command input
val cmd = Flipped(Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.core.xLen)
+ val cmd = new RoCCCommandBB(b.cpu.xLen)
}))
// Issue to domains
@@ -36,9 +41,17 @@ class Frontend(val b: GlobalConfig) extends Module {
// Ball -> SubROB request passthrough
val ball_subrob_req_i = Flipped(Vec(b.ballDomain.ballNum, Decoupled(new SubRobRow(b))))
+ val inst_ids = Output(Vec(b.frontend.rob_entries, UInt(64.W)))
+
+ val bank_hashes =
+ if (b.sim.diffTest) {
+ Some(Input(Vec(b.memDomain.bankNum + sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
// RoCC response
- val resp = Decoupled(new RoCCResponseBB(b.core.xLen))
+ val resp = Decoupled(new RoCCResponseBB(b.cpu.xLen))
val busy = Output(Bool())
// Propagates the Global ROB retirement pulse to the host bridge.
val retired = Output(Bool())
@@ -62,10 +75,13 @@ class Frontend(val b: GlobalConfig) extends Module {
io.cmd.ready := !boot.io.active && gDecoder.io.id_i.ready
scheduler.io.decode_cmd_i <> gDecoder.io.id_o
+ scheduler.io.hart_id := io.hartid
+ scheduler.io.bank_hashes.foreach(_ := io.bank_hashes.get)
io.ball_issue_o <> scheduler.io.ball_issue_o
io.mem_issue_o <> scheduler.io.mem_issue_o
io.gp_issue_o <> scheduler.io.gp_issue_o
+ io.inst_ids := scheduler.io.inst_ids
scheduler.io.ball_complete_i <> io.ball_complete_i
scheduler.io.mem_complete_i <> io.mem_complete_i
diff --git a/arch/src/main/scala/framework/frontend/boot/Boot.scala b/arch/src/main/scala/framework/frontend/boot/Boot.scala
index 695f6786..5ddf2957 100644
--- a/arch/src/main/scala/framework/frontend/boot/Boot.scala
+++ b/arch/src/main/scala/framework/frontend/boot/Boot.scala
@@ -15,7 +15,7 @@ class BootRom(val b: GlobalConfig) extends Module {
val io = IO(new Bundle {
val cmd = Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.core.xLen)
+ val cmd = new RoCCCommandBB(b.cpu.xLen)
})
val schedulerIdle = Input(Bool())
@@ -31,8 +31,8 @@ class BootRom(val b: GlobalConfig) extends Module {
Seq.empty[BuckyballCommand]
private val bootFuncts = VecInit(bootRecords.map(r => r.funct.U(7.W)))
- private val bootRs1Data = VecInit(bootRecords.map(r => r.rs1.U(b.core.xLen.W)))
- private val bootRs2Data = VecInit(bootRecords.map(r => r.rs2.U(b.core.xLen.W)))
+ val bootRs1Data = VecInit(bootRecords.map(r => r.rs1.U(b.cpu.xLen.W)))
+ val bootRs2Data = VecInit(bootRecords.map(r => r.rs2.U(b.cpu.xLen.W)))
private val bootPcWidth = math.max(1, log2Ceil(bootRecords.length + 1))
private val active = RegInit(true.B)
@@ -42,8 +42,8 @@ class BootRom(val b: GlobalConfig) extends Module {
private val atEnd = pc === bootRecords.length.U(bootPcWidth.W)
- private val current = Wire(new RoCCCommandBB(b.core.xLen))
- current := 0.U.asTypeOf(new RoCCCommandBB(b.core.xLen))
+ val current = Wire(new RoCCCommandBB(b.cpu.xLen))
+ current := 0.U.asTypeOf(new RoCCCommandBB(b.cpu.xLen))
current.funct := Mux(atEnd, 0.U, bootFuncts(pc))
current.funct3 := BuckyballCommand.Custom3Funct3.U
current.opcode := BuckyballCommand.Custom3Opcode.U
diff --git a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
index e645ecf6..fa5d0f79 100644
--- a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
+++ b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
@@ -16,13 +16,13 @@ import framework.frontend.scoreboard.BankAccessInfo
import framework.system.core.rocket.RoCCCommandBB
class BuckyballRawCmd(val b: GlobalConfig) extends Bundle {
- val cmd = new RoCCCommandBB(b.core.xLen)
+ val cmd = new RoCCCommandBB(b.cpu.xLen)
}
class PostGDCmd(val b: GlobalConfig) extends Bundle {
val domain_id = UInt(4.W)
val ball_bid = UInt(5.W)
- val cmd = new RoCCCommandBB(b.core.xLen)
+ val cmd = new RoCCCommandBB(b.cpu.xLen)
val bankAccess = new BankAccessInfo(b.frontend.bank_id_len)
val op1_col = UInt(b.memDomain.groupCountWidth.W)
val op2_col = UInt(b.memDomain.groupCountWidth.W)
@@ -40,7 +40,7 @@ class GlobalDecoder(val b: GlobalConfig) extends Module {
val io = IO(new Bundle {
val id_i = Flipped(Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.core.xLen)
+ val cmd = new RoCCCommandBB(b.cpu.xLen)
}))
val id_o = Decoupled(new PostGDCmd(b))
@@ -86,7 +86,7 @@ class GlobalDecoder(val b: GlobalConfig) extends Module {
// Bank access info extraction — enable flags from funct7[6:4]
//
// Unified rs1 layout (defined in isa.h):
- // rs1[9:0] = bank_0 (rd_bank_0 or wr_bank for MVIN/MSET)
+ // rs1[9:0] = bank_0 (rd_bank_0 or MSET config bank)
// rs1[19:10] = bank_1 (rd_bank_1, dual-operand only)
// rs1[29:20] = bank_2 (wr_bank for Ball instructions)
// rs1[63:30] = iter (34-bit)
@@ -105,7 +105,7 @@ class GlobalDecoder(val b: GlobalConfig) extends Module {
// Decode enable from funct7[6:4]
val hasRd0 = enableBits === 1.U || enableBits === 3.U || enableBits === 4.U
val hasRd1 = enableBits === 4.U
- val hasWr = enableBits === 2.U || enableBits === 3.U || enableBits === 4.U
+ val hasWr = (enableBits === 2.U || enableBits === 3.U || enableBits === 4.U) && func7 =/= MVIN_MMIO_BITPAT
val ballBid = WireDefault(0.U(5.W))
b.ballDomain.ballISA.foreach { entry =>
@@ -119,9 +119,7 @@ class GlobalDecoder(val b: GlobalConfig) extends Module {
bankAccess.rd_bank_1_valid := hasRd1
bankAccess.rd_bank_1_id := rs1(bankIdLen + 9, 10)
bankAccess.wr_bank_valid := hasWr
- // For Mem instructions (MVIN/MSET), wr_bank is bank_0 (rs1[9:0])
- // For Ball instructions, wr_bank is bank_2 (rs1[29:20])
- bankAccess.wr_bank_id := Mux(is_mem_inst, rs1(bankIdLen - 1, 0), rs1(bankIdLen + 19, 20))
+ bankAccess.wr_bank_id := Mux(func7 === MSET_BITPAT, rs1(bankIdLen - 1, 0), rs1(bankIdLen + 19, 20))
private def legalBank(raw: UInt): Bool =
raw <= b.frontend.vbank_id_upper_bound.U ||
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index 688438a7..380dddce 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -9,13 +9,16 @@ import framework.frontend.decoder.{DomainId, PostGDCmd}
import framework.frontend.scoreboard.{BankAccessInfo, BankAliasTable, BankScoreboard}
import framework.memdomain.frontend.cmd.decoder.DISA.MSET_BITPAT
import framework.memdomain.backend.shared.SharedMemLayout
+import framework.memdomain.backend.banks.btrace.{BTraceDPI, PhysicalBankHash}
@instantiable
class GlobalROB(val b: GlobalConfig) extends Module {
- val robDepth = b.frontend.rob_entries
- val idWidth = log2Up(robDepth)
- val scoreBankNum = b.memDomain.virtualBankCount + robDepth
+ val robDepth = b.frontend.rob_entries
+ val idWidth = log2Up(robDepth)
+ val scoreBankNum = b.memDomain.virtualBankCount + robDepth
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
+ val physicalBankCount = b.memDomain.bankNum + sharedHashCount
require(
b.frontend.vbank_id_upper_bound < b.memDomain.virtualBankCount,
@@ -24,6 +27,7 @@ class GlobalROB(val b: GlobalConfig) extends Module {
@public
val io = IO(new Bundle {
+ val hart_id = Input(UInt(b.cpu.xLen.W))
val alloc = Flipped(new DecoupledIO(new PostGDCmd(b)))
val issue = new DecoupledIO(new GlobalRobEntry(b))
val complete = Flipped(new DecoupledIO(UInt(idWidth.W)))
@@ -36,6 +40,15 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val entry_complete = Output(Vec(robDepth, Bool()))
val subRobActive = Input(Bool())
+ val inst_ids = Output(Vec(robDepth, UInt(64.W)))
+
+ val bank_hashes =
+ if (b.sim.diffTest) {
+ Some(Input(Vec(physicalBankCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
})
// ---------------------------------------------------------------------------
@@ -60,19 +73,18 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val itraceComp = Module(new ITraceDPI)
for (t <- Seq(itraceAlloc, itraceIssue, itraceComp)) {
- t.io.clock := clock
- t.io.reset := reset.asBool
- t.io.is_issue := 0.U
- t.io.rob_id := 0.U
- t.io.domain_id := 0.U
- t.io.funct := 0.U
- t.io.pc := 0.U
- t.io.rs1_idx := 0.U
- t.io.rs2_idx := 0.U
- t.io.rs1_data := 0.U
- t.io.rs2_data := 0.U
- t.io.bank_enable := 0.U
- t.io.enable := false.B
+ t.io.clock := clock
+ t.io.reset := reset.asBool
+ t.io.is_issue := 0.U
+ t.io.hart_id := io.hart_id
+ t.io.rob_id := 0.U
+ t.io.inst_id := 0.U
+ t.io.domain_id := 0.U
+ t.io.funct := 0.U
+ t.io.pc := 0.U
+ t.io.rs1_data := 0.U
+ t.io.rs2_data := 0.U
+ t.io.enable := false.B
}
// ---------------------------------------------------------------------------
@@ -82,6 +94,17 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val robValid = RegInit(VecInit(Seq.fill(robDepth)(false.B)))
val robIssued = RegInit(VecInit(Seq.fill(robDepth)(false.B)))
val robComplete = RegInit(VecInit(Seq.fill(robDepth)(false.B)))
+ val instIds = RegInit(VecInit(Seq.fill(robDepth)(0.U(64.W))))
+ val nextInstId = RegInit(1.U(64.W))
+
+ val statusHashes =
+ if (b.sim.diffTest) {
+ Some(RegInit(VecInit(Seq.fill(robDepth)(VecInit(Seq.fill(3)(0.U(32.W)))))))
+ } else {
+ None
+ }
+
+ io.inst_ids := instIds
val headPtr = RegInit(0.U(idWidth.W))
val tailPtr = RegInit(0.U(idWidth.W))
@@ -160,7 +183,7 @@ class GlobalROB(val b: GlobalConfig) extends Module {
for (i <- 0 until robDepth) {
val ptr = robIdx(wrapPtr(headPtr + i.U))
commitScan(i) := commitKeep(i) && robValid(ptr) && robComplete(ptr)
- commitKeep(i + 1) := commitScan(i)
+ commitKeep(i + 1) := (if (b.sim.diffTest) false.B else commitScan(i))
}
val hasCommit = commitScan.asUInt.orR
val tailAlias = Wire(UInt(b.frontend.bank_id_len.W))
@@ -207,8 +230,8 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val olderUseMask = entryRawReads(older) | entryRawWrites(older)
val rawConflict = ((allocReadMask & entryRawWrites(older)) |
(allocWriteMask & olderUseMask)).orR
- val configConflict = (allocIsConfig || entryIsConfig(older)) &&
- ((allocReadMask | allocWriteMask) & olderUseMask).orR
+ val configConflict = (allocIsConfig && entryIsConfig(older)) ||
+ ((allocIsConfig || entryIsConfig(older)) && ((allocReadMask | allocWriteMask) & olderUseMask).orR)
val sameBall = allocIsBall &&
robEntries(older).cmd.domain_id === DomainId.BALL &&
robEntries(older).cmd.ball_bid === io.alloc.bits.ball_bid
@@ -219,33 +242,111 @@ class GlobalROB(val b: GlobalConfig) extends Module {
(robValid(older) && configConflict)
}
val allocDependencies = allocDependencyBits.asUInt
+ val allocUsesInstId = io.alloc.bits.cmd.pc =/= 0.U
when(io.alloc.fire) {
- itraceAlloc.io.is_issue := 2.U
- itraceAlloc.io.rob_id := tailPtr
- itraceAlloc.io.domain_id := io.alloc.bits.domain_id
- itraceAlloc.io.funct := io.alloc.bits.cmd.funct
- itraceAlloc.io.pc := io.alloc.bits.cmd.pc
- itraceAlloc.io.rs1_idx := io.alloc.bits.cmd.rs1
- itraceAlloc.io.rs2_idx := io.alloc.bits.cmd.rs2
- itraceAlloc.io.rs1_data := io.alloc.bits.cmd.rs1Data
- itraceAlloc.io.rs2_data := io.alloc.bits.cmd.rs2Data
- itraceAlloc.io.bank_enable := io.alloc.bits.cmd.funct(6, 4)
- itraceAlloc.io.enable := true.B
+ itraceAlloc.io.is_issue := 2.U
+ itraceAlloc.io.rob_id := tailPtr
+ itraceAlloc.io.inst_id := Mux(allocUsesInstId, nextInstId, 0.U)
+ itraceAlloc.io.domain_id := io.alloc.bits.domain_id
+ itraceAlloc.io.funct := io.alloc.bits.cmd.funct
+ itraceAlloc.io.pc := io.alloc.bits.cmd.pc
+ itraceAlloc.io.rs1_data := io.alloc.bits.cmd.rs1Data
+ itraceAlloc.io.rs2_data := io.alloc.bits.cmd.rs2Data
+ itraceAlloc.io.enable := true.B
robEntries(tailPtr).cmd := io.alloc.bits
robEntries(tailPtr).renamedBankAccess := bat.io.alloc_renamed
robEntries(tailPtr).rob_id := tailPtr
+ instIds(tailPtr) := Mux(allocUsesInstId, nextInstId, 0.U)
robValid(tailPtr) := true.B
robIssued(tailPtr) := false.B
robComplete(tailPtr) := false.B
+ statusHashes.foreach { hashes =>
+ for (slot <- 0 until 3) {
+ hashes(tailPtr)(slot) := 0.U
+ }
+ }
tailPtr := nextPtr(tailPtr)
+ when(allocUsesInstId) {
+ nextInstId := nextInstId + 1.U
+ }
}
// ---------------------------------------------------------------------------
// Complete: mark entry as completed, release scoreboard resources
// ---------------------------------------------------------------------------
- io.complete.ready := true.B
+ if (b.sim.diffTest) {
+ val collecting = RegInit(false.B)
+ val collectCid = Reg(UInt(idWidth.W))
+ val collectSlot = Reg(UInt(2.W))
+ val collectGroup = Reg(UInt(32.W))
+ val currentHash = Reg(UInt(32.W))
+ val hashReady = RegInit(false.B)
+ val hashCid = Reg(UInt(idWidth.W))
+
+ val incomingAccess = robEntries(io.complete.bits).cmd.bankAccess
+ val incomingNeedsHash = instIds(io.complete.bits) =/= 0.U && !isMappingConfig(robEntries(io.complete.bits)) &&
+ (incomingAccess.rd_bank_0_valid || incomingAccess.rd_bank_1_valid || incomingAccess.wr_bank_valid)
+ io.complete.ready := !incomingNeedsHash || (hashReady && hashCid === io.complete.bits)
+
+ when(!collecting && !hashReady && io.complete.valid && incomingNeedsHash) {
+ collecting := true.B
+ collectCid := io.complete.bits
+ collectSlot := Mux(incomingAccess.rd_bank_0_valid, 0.U, Mux(incomingAccess.rd_bank_1_valid, 1.U, 2.U))
+ collectGroup := 0.U
+ currentHash := 0.U
+ }
+
+ val access = robEntries(collectCid).cmd.bankAccess
+ val vbank = MuxLookup(collectSlot, access.wr_bank_id)(Seq(
+ 0.U -> access.rd_bank_0_id,
+ 1.U -> access.rd_bank_1_id,
+ 2.U -> access.wr_bank_id
+ ))
+ val hasNextSlot = MuxLookup(collectSlot, false.B)(Seq(
+ 0.U -> (access.rd_bank_1_valid || access.wr_bank_valid),
+ 1.U -> access.wr_bank_valid
+ ))
+ val nextSlot = Mux(collectSlot === 0.U && access.rd_bank_1_valid, 1.U, 2.U)
+ val matches = VecInit(io.bank_hashes.get.map { state =>
+ state.valid && state.hartId === io.hart_id && state.vbankId === vbank && state.groupId === collectGroup
+ })
+ val nextMatches = VecInit(io.bank_hashes.get.map { state =>
+ state.valid && state.hartId === io.hart_id && state.vbankId === vbank && state.groupId === collectGroup + 1.U
+ })
+ val physical = Mux1H(matches, io.bank_hashes.get)
+ def rotateLeft(value: UInt, amount: Int): UInt = Cat(value(31 - amount, 0), value(31, 32 - amount))
+
+ val mapping = rotateLeft(physical.groupId, 7) ^ rotateLeft(physical.pbankId, 17)
+ val mixed = physical.statusHash ^ mapping ^ "h9e3779b9".U
+ val nextHash = rotateLeft(currentHash, 5) ^ mixed ^ rotateLeft(mixed, 13)
+
+ when(collecting) {
+ assert(PopCount(matches) === 1.U, "BTrace requires exactly one physical bank per vbank group")
+ when(nextMatches.asUInt.orR) {
+ currentHash := nextHash
+ collectGroup := collectGroup + 1.U
+ }.otherwise {
+ statusHashes.get(collectCid)(collectSlot) := nextHash
+ when(hasNextSlot) {
+ collectSlot := nextSlot
+ collectGroup := 0.U
+ currentHash := 0.U
+ }.otherwise {
+ collecting := false.B
+ hashReady := true.B
+ hashCid := collectCid
+ }
+ }
+ }
+
+ when(io.complete.fire) {
+ hashReady := false.B
+ }
+ } else {
+ io.complete.ready := true.B
+ }
scoreboard.complete.valid := false.B
scoreboard.complete.bits := 0.U.asTypeOf(scoreboard.complete.bits)
@@ -259,17 +360,15 @@ class GlobalROB(val b: GlobalConfig) extends Module {
scoreboard.complete.valid := true.B
scoreboard.complete.bits := robEntries(cid).renamedBankAccess
- itraceComp.io.is_issue := 0.U
- itraceComp.io.rob_id := cid
- itraceComp.io.domain_id := robEntries(cid).cmd.domain_id
- itraceComp.io.funct := robEntries(cid).cmd.cmd.funct
- itraceComp.io.pc := robEntries(cid).cmd.cmd.pc
- itraceComp.io.rs1_idx := robEntries(cid).cmd.cmd.rs1
- itraceComp.io.rs2_idx := robEntries(cid).cmd.cmd.rs2
- itraceComp.io.rs1_data := robEntries(cid).cmd.cmd.rs1Data
- itraceComp.io.rs2_data := robEntries(cid).cmd.cmd.rs2Data
- itraceComp.io.bank_enable := robEntries(cid).cmd.cmd.funct(6, 4)
- itraceComp.io.enable := true.B
+ itraceComp.io.is_issue := 0.U
+ itraceComp.io.rob_id := cid
+ itraceComp.io.inst_id := instIds(cid)
+ itraceComp.io.domain_id := robEntries(cid).cmd.domain_id
+ itraceComp.io.funct := robEntries(cid).cmd.cmd.funct
+ itraceComp.io.pc := robEntries(cid).cmd.cmd.pc
+ itraceComp.io.rs1_data := robEntries(cid).cmd.cmd.rs1Data
+ itraceComp.io.rs2_data := robEntries(cid).cmd.cmd.rs2Data
+ itraceComp.io.enable := true.B
}
val completedBitMask = Mux(
@@ -366,17 +465,15 @@ class GlobalROB(val b: GlobalConfig) extends Module {
scoreboard.issue.valid := true.B
scoreboard.issue.bits := robEntries(actualIssuePtr).renamedBankAccess
- itraceIssue.io.is_issue := 1.U
- itraceIssue.io.rob_id := robEntries(actualIssuePtr).rob_id
- itraceIssue.io.domain_id := robEntries(actualIssuePtr).cmd.domain_id
- itraceIssue.io.funct := robEntries(actualIssuePtr).cmd.cmd.funct
- itraceIssue.io.pc := robEntries(actualIssuePtr).cmd.cmd.pc
- itraceIssue.io.rs1_idx := robEntries(actualIssuePtr).cmd.cmd.rs1
- itraceIssue.io.rs2_idx := robEntries(actualIssuePtr).cmd.cmd.rs2
- itraceIssue.io.rs1_data := robEntries(actualIssuePtr).cmd.cmd.rs1Data
- itraceIssue.io.rs2_data := robEntries(actualIssuePtr).cmd.cmd.rs2Data
- itraceIssue.io.bank_enable := robEntries(actualIssuePtr).cmd.cmd.funct(6, 4)
- itraceIssue.io.enable := true.B
+ itraceIssue.io.is_issue := 1.U
+ itraceIssue.io.rob_id := robEntries(actualIssuePtr).rob_id
+ itraceIssue.io.inst_id := instIds(actualIssuePtr)
+ itraceIssue.io.domain_id := robEntries(actualIssuePtr).cmd.domain_id
+ itraceIssue.io.funct := robEntries(actualIssuePtr).cmd.cmd.funct
+ itraceIssue.io.pc := robEntries(actualIssuePtr).cmd.cmd.pc
+ itraceIssue.io.rs1_data := robEntries(actualIssuePtr).cmd.cmd.rs1Data
+ itraceIssue.io.rs2_data := robEntries(actualIssuePtr).cmd.cmd.rs2Data
+ itraceIssue.io.enable := true.B
}
// Preserve the original update ordering when issue and complete coincide:
@@ -428,6 +525,25 @@ class GlobalROB(val b: GlobalConfig) extends Module {
}
}
+ if (b.sim.diffTest) {
+ val commitIndex = PriorityEncoder(commitMask.asUInt)
+ val commitAccess = robEntries(commitIndex).cmd.bankAccess
+ val invalidVbank = "hffffffff".U(32.W)
+ val btrace = Module(new BTraceDPI)
+ btrace.io.clock := clock
+ btrace.io.reset := reset.asBool
+ btrace.io.instId := instIds(commitIndex)
+ btrace.io.hartId := io.hart_id
+ btrace.io.r0Vbank := Mux(commitAccess.rd_bank_0_valid, commitAccess.rd_bank_0_id, invalidVbank)
+ btrace.io.r0Hash := Mux(commitAccess.rd_bank_0_valid, statusHashes.get(commitIndex)(0), 0.U)
+ btrace.io.r1Vbank := Mux(commitAccess.rd_bank_1_valid, commitAccess.rd_bank_1_id, invalidVbank)
+ btrace.io.r1Hash := Mux(commitAccess.rd_bank_1_valid, statusHashes.get(commitIndex)(1), 0.U)
+ btrace.io.w0Vbank := Mux(commitAccess.wr_bank_valid, commitAccess.wr_bank_id, invalidVbank)
+ btrace.io.w0Hash := Mux(commitAccess.wr_bank_valid, statusHashes.get(commitIndex)(2), 0.U)
+ btrace.io.fire := hasCommit && instIds(commitIndex) =/= 0.U && !isMappingConfig(robEntries(commitIndex)) &&
+ (commitAccess.rd_bank_0_valid || commitAccess.rd_bank_1_valid || commitAccess.wr_bank_valid)
+ }
+
// Maintain dependency masks at the same architectural events that gate the
// issue scan. A dependency involving a config entry (on either side) clears
// only at commit; all other dependencies clear at complete. This is the
@@ -459,4 +575,5 @@ class GlobalROB(val b: GlobalConfig) extends Module {
io.issued_count := issuedCount
io.entry_valid := robValid
io.entry_complete := robComplete
+
}
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
index b30a377f..8b2ae85f 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
@@ -10,6 +10,8 @@ import framework.frontend.decoder.GISA._
import framework.frontend.scoreboard.BankAccessInfo
import framework.system.core.rocket.RoCCResponseBB
import framework.balldomain.blink.SubRobRow
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
+import framework.memdomain.backend.shared.SharedMemLayout
class GlobalRobEntry(val b: GlobalConfig) extends Bundle {
val cmd = new PostGDCmd(b)
@@ -31,8 +33,11 @@ class GlobalSchedComplete(b: GlobalConfig) extends Bundle {
@instantiable
class GlobalScheduler(val b: GlobalConfig) extends Module {
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
+
@public
val io = IO(new Bundle {
+ val hart_id = Input(UInt(b.cpu.xLen.W))
val decode_cmd_i = Flipped(new DecoupledIO(new PostGDCmd(b)))
val ball_issue_o = Decoupled(new GlobalSchedIssue(b))
val mem_issue_o = Decoupled(new GlobalSchedIssue(b))
@@ -41,9 +46,17 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
val mem_complete_i = Flipped(Decoupled(new GlobalSchedComplete(b)))
val gp_complete_i = Flipped(Decoupled(new GlobalSchedComplete(b)))
val ball_subrob_req_i = Flipped(Vec(b.ballDomain.ballNum, Decoupled(new SubRobRow(b))))
+ val inst_ids = Output(Vec(b.frontend.rob_entries, UInt(64.W)))
+
+ val bank_hashes =
+ if (b.sim.diffTest) {
+ Some(Input(Vec(b.memDomain.bankNum + sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
val scheduler_rocc_o = new Bundle {
- val resp = new DecoupledIO(new RoCCResponseBB(b.core.xLen))
+ val resp = new DecoupledIO(new RoCCResponseBB(b.cpu.xLen))
val busy = Output(Bool())
}
@@ -56,6 +69,9 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
})
val rob: Instance[GlobalROB] = Instantiate(new GlobalROB(b))
+ rob.io.hart_id := io.hart_id
+ rob.io.bank_hashes.foreach(_ := io.bank_hashes.get)
+ io.inst_ids := rob.io.inst_ids
val isFenceCmd = io.decode_cmd_i.valid && io.decode_cmd_i.bits.isFence
val fenceActive = RegInit(false.B)
@@ -102,7 +118,9 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
mainIssueEntry.is_sub := false.B
mainIssueEntry.sub_rob_id := 0.U
- val completeArb = Module(new Arbiter(new GlobalSchedComplete(b), 3))
+ val completeArb = Module(new Arbiter(new GlobalSchedComplete(b), 3))
+ val completeQueue = Module(new Queue(UInt(log2Up(b.frontend.rob_entries).W), b.frontend.rob_entries))
+ rob.io.complete <> completeQueue.io.deq
completeArb.io.in(0).valid := io.ball_complete_i.valid
completeArb.io.in(0).bits := io.ball_complete_i.bits
io.ball_complete_i.ready := completeArb.io.in(0).ready
@@ -171,29 +189,22 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
)
rob.io.subRobActive := subRobIssueValid
- subRob.io.subComplete.valid := completeArb.io.out.valid && completeBits.is_sub
- subRob.io.subComplete.bits := completeBits.sub_rob_id
- subRob.io.masterComplete.ready := true.B
+ subRob.io.subComplete.valid := completeArb.io.out.valid && completeBits.is_sub
+ subRob.io.subComplete.bits := completeBits.sub_rob_id
val normalComplete = completeArb.io.out.valid && !completeBits.is_sub
- if (b.frontend.rs_out_of_order_response) {
- rob.io.complete.valid := normalComplete || subRob.io.masterComplete.valid
- rob.io.complete.bits := Mux(subRob.io.masterComplete.valid, subRob.io.masterComplete.bits, completeBits.rob_id)
- } else {
- val isHeadComplete = Mux(
- subRob.io.masterComplete.valid,
- subRob.io.masterComplete.bits === rob.io.head_ptr,
- completeBits.rob_id === rob.io.head_ptr
- )
- rob.io.complete.valid := (normalComplete || subRob.io.masterComplete.valid) && isHeadComplete
- rob.io.complete.bits := Mux(subRob.io.masterComplete.valid, subRob.io.masterComplete.bits, completeBits.rob_id)
- }
- completeArb.io.out.ready := Mux(
+ val masterComplete = subRob.io.masterComplete.valid
+ val completeRobId = Mux(masterComplete, subRob.io.masterComplete.bits, completeBits.rob_id)
+
+ completeQueue.io.enq.valid := masterComplete || normalComplete
+ completeQueue.io.enq.bits := completeRobId
+ subRob.io.masterComplete.ready := masterComplete && completeQueue.io.enq.ready
+ completeArb.io.out.ready := Mux(
completeBits.is_sub,
subRob.io.subComplete.ready,
- rob.io.complete.ready
+ !masterComplete && completeQueue.io.enq.ready
)
- io.idle := rob.io.empty && !fenceActive && !barrierWaitROB && !barrierWaitRelease && !subRob.io.occupied
+ io.idle := rob.io.empty && !fenceActive && !barrierWaitROB && !barrierWaitRelease && !subRob.io.occupied
} else {
for (i <- 0 until b.ballDomain.ballNum) {
io.ball_subrob_req_i(i).ready := false.B
@@ -214,14 +225,10 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
when(completeArb.io.out.valid) {
assert(!completeBits.is_sub, "SubROB completion observed when frontend.sub_rob_enable=false")
}
- if (b.frontend.rs_out_of_order_response) {
- rob.io.complete.valid := completeArb.io.out.valid
- } else {
- rob.io.complete.valid := completeArb.io.out.valid && completeBits.rob_id === rob.io.head_ptr
- }
- rob.io.complete.bits := completeBits.rob_id
- completeArb.io.out.ready := rob.io.complete.ready
- io.idle := rob.io.empty && !fenceActive && !barrierWaitROB && !barrierWaitRelease
+ completeQueue.io.enq.valid := completeArb.io.out.valid
+ completeQueue.io.enq.bits := completeBits.rob_id
+ completeArb.io.out.ready := completeQueue.io.enq.ready
+ io.idle := rob.io.empty && !fenceActive && !barrierWaitROB && !barrierWaitRelease
}
io.scheduler_rocc_o.resp.valid := false.B
@@ -229,4 +236,5 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
io.scheduler_rocc_o.resp.bits.data := 0.U
io.scheduler_rocc_o.busy := rob.io.full || fenceActive || barrierWaitROB || barrierWaitRelease
io.retired := rob.io.complete.fire && rob.io.entry_valid(rob.io.complete.bits)
+
}
diff --git a/arch/src/main/scala/framework/frontend/globalrs/ITraceDPI.scala b/arch/src/main/scala/framework/frontend/globalrs/ITraceDPI.scala
index fec614ce..08126e6c 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/ITraceDPI.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/ITraceDPI.scala
@@ -7,19 +7,18 @@ import framework.dpi.DpiGuard
class ITraceDPI extends BlackBox with HasBlackBoxInline {
val io = IO(new Bundle {
- val clock = Input(Clock())
- val reset = Input(Bool())
- val is_issue = Input(UInt(8.W))
- val rob_id = Input(UInt(32.W))
- val domain_id = Input(UInt(32.W))
- val funct = Input(UInt(32.W))
- val pc = Input(UInt(64.W))
- val rs1_idx = Input(UInt(64.W))
- val rs2_idx = Input(UInt(64.W))
- val rs1_data = Input(UInt(64.W))
- val rs2_data = Input(UInt(64.W))
- val bank_enable = Input(UInt(8.W))
- val enable = Input(Bool())
+ val clock = Input(Clock())
+ val reset = Input(Bool())
+ val is_issue = Input(UInt(8.W))
+ val hart_id = Input(UInt(64.W))
+ val rob_id = Input(UInt(32.W))
+ val inst_id = Input(UInt(64.W))
+ val domain_id = Input(UInt(32.W))
+ val funct = Input(UInt(32.W))
+ val pc = Input(UInt(64.W))
+ val rs1_data = Input(UInt(64.W))
+ val rs2_data = Input(UInt(64.W))
+ val enable = Input(Bool())
})
setInline(
@@ -29,45 +28,42 @@ class ITraceDPI extends BlackBox with HasBlackBoxInline {
| input clock,
| input reset,
| input [7:0] is_issue,
+ | input [63:0] hart_id,
| input [31:0] rob_id,
+ | input [63:0] inst_id,
| input [31:0] domain_id,
| input [31:0] funct,
| input [63:0] pc,
- | input [63:0] rs1_idx,
- | input [63:0] rs2_idx,
| input [63:0] rs1_data,
| input [63:0] rs2_data,
- | input [7:0] bank_enable,
| input enable
|);
|""".stripMargin + DpiGuard.wrapITrace("""
| import "DPI-C" context function void dpi_itrace(
| input int unsigned is_issue,
+ | input int unsigned hart_id_lo,
+ | input int unsigned hart_id_hi,
| input int unsigned rob_id,
+ | input int unsigned inst_id_lo,
+ | input int unsigned inst_id_hi,
| input int unsigned domain_id,
| input int unsigned funct,
| input int unsigned pc_lo,
| input int unsigned pc_hi,
- | input int unsigned rs1_idx_lo,
- | input int unsigned rs1_idx_hi,
- | input int unsigned rs2_idx_lo,
- | input int unsigned rs2_idx_hi,
| input int unsigned rs1_data_lo,
| input int unsigned rs1_data_hi,
| input int unsigned rs2_data_lo,
- | input int unsigned rs2_data_hi,
- | input int unsigned bank_enable
+ | input int unsigned rs2_data_hi
| );
| reg [7:0] is_issue_reg;
+ | reg [63:0] hart_id_reg;
| reg [31:0] rob_id_reg;
+ | reg [63:0] inst_id_reg;
| reg [31:0] domain_id_reg;
| reg [31:0] funct_reg;
| reg [63:0] pc_reg;
- | reg [63:0] rs1_idx_reg;
- | reg [63:0] rs2_idx_reg;
| reg [63:0] rs1_data_reg;
| reg [63:0] rs2_data_reg;
- | reg [7:0] bank_enable_reg;
| reg valid_reg;
|
| always @(posedge clock) begin
@@ -75,21 +71,20 @@ class ITraceDPI extends BlackBox with HasBlackBoxInline {
| valid_reg <= 1'b0;
| end else begin
| if (valid_reg) begin
- | dpi_itrace(is_issue_reg, rob_id_reg, domain_id_reg, funct_reg, pc_reg[31:0], pc_reg[63:32], rs1_idx_reg[31:0], rs1_idx_reg[63:32], rs2_idx_reg[31:0], rs2_idx_reg[63:32], rs1_data_reg[31:0], rs1_data_reg[63:32], rs2_data_reg[31:0], rs2_data_reg[63:32], bank_enable_reg);
+ | dpi_itrace(is_issue_reg, hart_id_reg[31:0], hart_id_reg[63:32], rob_id_reg, inst_id_reg[31:0], inst_id_reg[63:32], domain_id_reg, funct_reg, pc_reg[31:0], pc_reg[63:32], rs1_data_reg[31:0], rs1_data_reg[63:32], rs2_data_reg[31:0], rs2_data_reg[63:32]);
| end
|
| valid_reg <= enable;
| if (enable) begin
| is_issue_reg <= is_issue;
+ | hart_id_reg <= hart_id;
| rob_id_reg <= rob_id;
+ | inst_id_reg <= inst_id;
| domain_id_reg <= domain_id;
| funct_reg <= funct;
| pc_reg <= pc;
- | rs1_idx_reg <= rs1_idx;
- | rs2_idx_reg <= rs2_idx;
| rs1_data_reg <= rs1_data;
| rs2_data_reg <= rs2_data;
- | bank_enable_reg <= bank_enable;
| end
| end
| end
diff --git a/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala b/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
index 15847d82..39603da0 100644
--- a/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
+++ b/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
@@ -30,7 +30,7 @@ object DomainDecoderParameter {
* Domain Decoder IO
*/
class DomainDecoderIO(b: GlobalConfig) extends Bundle {
- val inst_i = Input(new RoCCCommandBB(b.core.xLen))
+ val inst_i = Input(new RoCCCommandBB(b.cpu.xLen))
val decoded_o = Decoder.bundle(DomainDecoderParameter.decoderParam).cloneType
}
diff --git a/arch/src/main/scala/framework/memdomain/MemDomain.scala b/arch/src/main/scala/framework/memdomain/MemDomain.scala
index 52191b13..5c492424 100644
--- a/arch/src/main/scala/framework/memdomain/MemDomain.scala
+++ b/arch/src/main/scala/framework/memdomain/MemDomain.scala
@@ -17,13 +17,15 @@ import framework.memdomain.frontend.mem.{MemConfigerIO}
import framework.memdomain.frontend.mem.tlb.{BBTLBExceptionIO, BBTLBPTWIO}
import framework.memdomain.midend.MemMidend
import framework.memdomain.backend.MemBackend
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
@instantiable
class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
- val totalMmioRead = b.ballDomain.ballIdMappings.map(_.mmioReadBW).sum
- val totalMmioWrite = b.ballDomain.ballIdMappings.map(_.mmioWriteBW).sum
- val totalBallRead = b.ballDomain.ballIdMappings.map(_.inBW).sum
- val totalBallWrite = b.ballDomain.ballIdMappings.map(_.outBW).sum
+ val totalMmioRead = b.ballDomain.ballIdMappings.map(_.mmioReadBW).sum
+ val totalMmioWrite = b.ballDomain.ballIdMappings.map(_.mmioWriteBW).sum
+ val totalBallRead = b.ballDomain.ballIdMappings.map(_.inBW).sum
+ val totalBallWrite = b.ballDomain.ballIdMappings.map(_.outBW).sum
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
@public
val io = IO(new Bundle {
@@ -31,6 +33,7 @@ class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val global_issue_i = Flipped(Decoupled(new GlobalSchedIssue(b)))
val global_complete_o = Decoupled(new GlobalSchedComplete(b))
val busy = Output(Bool())
+ val inst_ids = Input(Vec(b.frontend.rob_entries, UInt(64.W)))
// Inside Channel
val ballChannelActive = Input(Vec(b.ballDomain.ballNum, Bool()))
@@ -48,7 +51,7 @@ class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val tlbExp = Vec(1, new BBTLBExceptionIO)
val tl_reader = new TLBundle(edge.bundle)
val tl_writer = new TLBundle(edge.bundle)
- val hartid = Input(UInt(b.core.xLen.W))
+ val hartid = Input(UInt(b.cpu.xLen.W))
// Shared memory path
val shared_mem_req = Vec(SharedMemLayout.channelPerHart(b), new MemRequestIO(b))
@@ -56,17 +59,36 @@ class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val shared_query_valid = Output(Bool())
val shared_query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val shared_query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
+
+ val bank_hashes =
+ if (b.sim.diffTest) {
+ Some(Output(Vec(b.memDomain.bankNum + sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
+ val shared_bank_hashes =
+ if (b.sim.diffTest && b.memDomain.sharedEnable) {
+ Some(Input(Vec(sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
})
val frontend: Instance[MemFrontend] = Instantiate(new MemFrontend(b)(edge))
val midend: Instance[MemMidend] = Instantiate(new MemMidend(b))
val backend: Instance[MemBackend] = Instantiate(new MemBackend(b))
+ io.bank_hashes.foreach(_ := backend.io.bank_hashes.get)
+ backend.io.shared_bank_hashes.foreach(_ := io.shared_bank_hashes.get)
+
// Connect query interface from frontend to backend
backend.io.query_vbank_id := frontend.io.query_vbank_id
backend.io.query_is_shared := frontend.io.query_is_shared
frontend.io.query_group_count := backend.io.query_group_count
frontend.io.hartid := io.hartid
+ midend.io.inst_ids := io.inst_ids
// Shared query: backend delegates shared query to external SharedMemBackend
backend.io.shared_query_group_count := io.shared_query_group_count
diff --git a/arch/src/main/scala/framework/memdomain/backend/MTrace.scala b/arch/src/main/scala/framework/memdomain/backend/MTrace.scala
index 3414f821..f8c55153 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MTrace.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MTrace.scala
@@ -14,6 +14,7 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
val channel = Input(UInt(32.W))
val hart_id = Input(UInt(64.W))
val rob_id = Input(UInt(32.W))
+ val inst_id = Input(UInt(64.W))
val vbank_id = Input(UInt(32.W))
val pbank_id = Input(UInt(32.W))
val group_id = Input(UInt(32.W))
@@ -35,6 +36,7 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
| input [31:0] channel,
| input [63:0] hart_id,
| input [31:0] rob_id,
+ | input [63:0] inst_id,
| input [31:0] vbank_id,
| input [31:0] pbank_id,
| input [31:0] group_id,
@@ -52,6 +54,8 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
| input int unsigned hart_id_lo,
| input int unsigned hart_id_hi,
| input int unsigned rob_id,
+ | input int unsigned inst_id_lo,
+ | input int unsigned inst_id_hi,
| input int unsigned vbank_id,
| input int unsigned pbank_id,
| input int unsigned group_id,
@@ -67,6 +71,7 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
| reg [31:0] channel_reg;
| reg [63:0] hart_id_reg;
| reg [31:0] rob_id_reg;
+ | reg [63:0] inst_id_reg;
| reg [31:0] vbank_id_reg;
| reg [31:0] pbank_id_reg;
| reg [31:0] group_id_reg;
@@ -81,7 +86,7 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
| valid_reg <= 1'b0;
| end else begin
| if (valid_reg) begin
- | dpi_mtrace(is_write_reg, is_shared_reg, channel_reg, hart_id_reg[31:0], hart_id_reg[63:32], rob_id_reg, vbank_id_reg, pbank_id_reg, group_id_reg, addr_reg, write_mask_reg, data_lo_reg[31:0], data_lo_reg[63:32], data_hi_reg[31:0], data_hi_reg[63:32]);
+ | dpi_mtrace(is_write_reg, is_shared_reg, channel_reg, hart_id_reg[31:0], hart_id_reg[63:32], rob_id_reg, inst_id_reg[31:0], inst_id_reg[63:32], vbank_id_reg, pbank_id_reg, group_id_reg, addr_reg, write_mask_reg, data_lo_reg[31:0], data_lo_reg[63:32], data_hi_reg[31:0], data_hi_reg[63:32]);
| end
|
| valid_reg <= enable;
@@ -91,6 +96,7 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
| channel_reg <= channel;
| hart_id_reg <= hart_id;
| rob_id_reg <= rob_id;
+ | inst_id_reg <= inst_id;
| vbank_id_reg <= vbank_id;
| pbank_id_reg <= pbank_id;
| group_id_reg <= group_id;
@@ -107,69 +113,3 @@ class MTraceDPI extends BlackBox with HasBlackBoxInline {
""".stripMargin
)
}
-
-class MTraceIssueDPI extends BlackBox with HasBlackBoxInline {
-
- val io = IO(new Bundle {
- val clock = Input(Clock())
- val reset = Input(Bool())
- val hart_id = Input(UInt(64.W))
- val is_shared = Input(UInt(8.W))
- val rob_id = Input(UInt(32.W))
- val vbank_id = Input(UInt(32.W))
- val group_id = Input(UInt(32.W))
- val enable = Input(Bool())
- })
-
- setInline(
- "MTraceIssueDPI.v",
- """
- |module MTraceIssueDPI(
- | input clock,
- | input reset,
- | input [63:0] hart_id,
- | input [7:0] is_shared,
- | input [31:0] rob_id,
- | input [31:0] vbank_id,
- | input [31:0] group_id,
- | input enable
- |);
- |""".stripMargin + DpiGuard.wrapMTrace("""
- | import "DPI-C" context function void dpi_mtrace_issue(
- | input int unsigned hart_id_lo,
- | input int unsigned hart_id_hi,
- | input int unsigned is_shared,
- | input int unsigned rob_id,
- | input int unsigned vbank_id,
- | input int unsigned group_id
- | );
- | reg [63:0] hart_id_reg;
- | reg [7:0] is_shared_reg;
- | reg [31:0] rob_id_reg;
- | reg [31:0] vbank_id_reg;
- | reg [31:0] group_id_reg;
- | reg valid_reg;
- |
- | always @(posedge clock) begin
- | if (reset) begin
- | valid_reg <= 1'b0;
- | end else begin
- | if (valid_reg) begin
- | dpi_mtrace_issue(hart_id_reg[31:0], hart_id_reg[63:32], is_shared_reg, rob_id_reg, vbank_id_reg, group_id_reg);
- | end
- | valid_reg <= enable;
- | if (enable) begin
- | hart_id_reg <= hart_id;
- | is_shared_reg <= is_shared;
- | rob_id_reg <= rob_id;
- | vbank_id_reg <= vbank_id;
- | group_id_reg <= group_id;
- | end
- | end
- | end
- |""".stripMargin) +
- """
- |endmodule
- """.stripMargin
- )
-}
diff --git a/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
index da712a68..52816381 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MemBackend.scala
@@ -7,10 +7,13 @@ import framework.memdomain.frontend.mem.MemConfigerIO
import framework.top.GlobalConfig
import framework.memdomain.backend.privatepath.PrivateMemBackend
import framework.memdomain.backend.shared.SharedMemLayout
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
@instantiable
class MemBackend(val b: GlobalConfig) extends Module {
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
+
@public
val io = IO(new Bundle {
val mem_req = Vec(b.memDomain.bankChannel, Flipped(new MemRequestIO(b)))
@@ -30,12 +33,36 @@ class MemBackend(val b: GlobalConfig) extends Module {
val query_vbank_id = Input(UInt(b.memDomain.vbankIdWidth.W))
val query_is_shared = Input(Bool())
val query_group_count = Output(UInt(b.memDomain.groupCountWidth.W))
+
+ val bank_hashes =
+ if (b.sim.diffTest) {
+ Some(Output(Vec(b.memDomain.bankNum + sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
+ val shared_bank_hashes =
+ if (b.sim.diffTest && b.memDomain.sharedEnable) {
+ Some(Input(Vec(SharedMemLayout.totalBank(b), new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
})
// Keep the private backend datapath unchanged and isolate it in a dedicated module.
val privateBackend: Instance[PrivateMemBackend] = Instantiate(new PrivateMemBackend(b))
private val sharedChannelPerHart = SharedMemLayout.channelPerHart(b)
+ io.bank_hashes.foreach { states =>
+ for (i <- 0 until b.memDomain.bankNum) {
+ states(i) := privateBackend.io.bank_hashes.get(i)
+ }
+ for (i <- 0 until sharedHashCount) {
+ states(b.memDomain.bankNum + i) := io.shared_bank_hashes.get(i)
+ }
+ }
+
// Route config to the selected backend only.
val cfgToShared = io.config.bits.is_shared
privateBackend.io.config.valid := io.config.valid && !cfgToShared
@@ -79,6 +106,7 @@ class MemBackend(val b: GlobalConfig) extends Module {
io.shared_mem_req(i).is_shared := false.B
io.shared_mem_req(i).hart_id := 0.U
io.shared_mem_req(i).rob_id := 0.U
+ io.shared_mem_req(i).inst_id := 0.U
io.shared_mem_req(i).read.req.valid := false.B
io.shared_mem_req(i).read.req.bits := DontCare
@@ -126,6 +154,7 @@ class MemBackend(val b: GlobalConfig) extends Module {
privateBackend.io.mem_req(i).is_shared := useSharedReq
privateBackend.io.mem_req(i).hart_id := io.mem_req(i).hart_id
privateBackend.io.mem_req(i).rob_id := io.mem_req(i).rob_id
+ privateBackend.io.mem_req(i).inst_id := io.mem_req(i).inst_id
// Read request route
privateBackend.io.mem_req(i).read.req.valid := io.mem_req(i).read.req.valid && !useSharedReq
@@ -145,6 +174,7 @@ class MemBackend(val b: GlobalConfig) extends Module {
io.shared_mem_req(i).is_shared := useSharedReq
io.shared_mem_req(i).hart_id := io.mem_req(i).hart_id
io.shared_mem_req(i).rob_id := io.mem_req(i).rob_id
+ io.shared_mem_req(i).inst_id := io.mem_req(i).inst_id
io.shared_mem_req(i).read.req.valid := io.mem_req(i).read.req.valid && useSharedReq
io.shared_mem_req(i).read.req.bits := io.mem_req(i).read.req.bits
@@ -206,6 +236,7 @@ class MemBackend(val b: GlobalConfig) extends Module {
io.shared_mem_req(i).is_shared := false.B
io.shared_mem_req(i).hart_id := 0.U
io.shared_mem_req(i).rob_id := 0.U
+ io.shared_mem_req(i).inst_id := 0.U
io.shared_mem_req(i).read.req.valid := false.B
io.shared_mem_req(i).read.req.bits := DontCare
io.shared_mem_req(i).read.resp.ready := false.B
@@ -215,19 +246,18 @@ class MemBackend(val b: GlobalConfig) extends Module {
}
for (i <- 0 until b.memDomain.bankChannel) {
- privateBackend.io.mem_req(i).bank_id := io.mem_req(i).bank_id
- privateBackend.io.mem_req(i).group_id := io.mem_req(i).group_id
- privateBackend.io.mem_req(i).is_shared := false.B
- privateBackend.io.mem_req(i).hart_id := io.mem_req(i).hart_id
- privateBackend.io.mem_req(i).rob_id := io.mem_req(i).rob_id
-
- privateBackend.io.mem_req(i).read.req.valid := io.mem_req(i).read.req.valid
- privateBackend.io.mem_req(i).read.req.bits := io.mem_req(i).read.req.bits
- privateBackend.io.mem_req(i).read.resp.ready := io.mem_req(i).read.resp.ready
- io.mem_req(i).read.req.ready := privateBackend.io.mem_req(i).read.req.ready
- io.mem_req(i).read.resp.valid := privateBackend.io.mem_req(i).read.resp.valid
- io.mem_req(i).read.resp.bits := privateBackend.io.mem_req(i).read.resp.bits
-
+ privateBackend.io.mem_req(i).bank_id := io.mem_req(i).bank_id
+ privateBackend.io.mem_req(i).group_id := io.mem_req(i).group_id
+ privateBackend.io.mem_req(i).is_shared := false.B
+ privateBackend.io.mem_req(i).hart_id := io.mem_req(i).hart_id
+ privateBackend.io.mem_req(i).rob_id := io.mem_req(i).rob_id
+ privateBackend.io.mem_req(i).inst_id := io.mem_req(i).inst_id
+ privateBackend.io.mem_req(i).read.req.valid := io.mem_req(i).read.req.valid
+ privateBackend.io.mem_req(i).read.req.bits := io.mem_req(i).read.req.bits
+ privateBackend.io.mem_req(i).read.resp.ready := io.mem_req(i).read.resp.ready
+ io.mem_req(i).read.req.ready := privateBackend.io.mem_req(i).read.req.ready
+ io.mem_req(i).read.resp.valid := privateBackend.io.mem_req(i).read.resp.valid
+ io.mem_req(i).read.resp.bits := privateBackend.io.mem_req(i).read.resp.bits
privateBackend.io.mem_req(i).write.req.valid := io.mem_req(i).write.req.valid
privateBackend.io.mem_req(i).write.req.bits := io.mem_req(i).write.req.bits
privateBackend.io.mem_req(i).write.resp.ready := io.mem_req(i).write.resp.ready
diff --git a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
index 0eaac0cd..8bd8859d 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
@@ -11,6 +11,7 @@ class MemRequestIO(b: GlobalConfig) extends Bundle {
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val is_shared = Output(Bool())
- val hart_id = Output(UInt(b.core.xLen.W))
+ val hart_id = Output(UInt(b.cpu.xLen.W))
val rob_id = Output(UInt(log2Up(b.frontend.rob_entries).W))
+ val inst_id = Output(UInt(64.W))
}
diff --git a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
index 48313f3c..1d6204df 100644
--- a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
@@ -22,7 +22,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
val busy = Output(Bool())
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val hart_id = Output(UInt(b.core.xLen.W))
+ val hart_id = Output(UInt(b.cpu.xLen.W))
})
// Each group has its own physical bank, so no address shifting is needed.
@@ -36,7 +36,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
//Bank_id output
val bank_id_reg = RegInit(0.U(b.memDomain.vbankIdWidth.W))
io.bank_id := bank_id_reg
- val hart_id_reg = RegInit(0.U(b.core.xLen.W))
+ val hart_id_reg = RegInit(0.U(b.cpu.xLen.W))
io.hart_id := hart_id_reg
val rd_hold = RegInit(false.B)
diff --git a/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceDPI.scala b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceDPI.scala
new file mode 100644
index 00000000..217b2a29
--- /dev/null
+++ b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceDPI.scala
@@ -0,0 +1,64 @@
+package framework.memdomain.backend.banks.btrace
+
+import chisel3._
+import chisel3.util._
+import framework.dpi.DpiGuard
+
+class BTraceDPI extends BlackBox with HasBlackBoxInline {
+
+ val io = IO(new Bundle {
+ val clock = Input(Clock())
+ val reset = Input(Bool())
+ val instId = Input(UInt(64.W))
+ val hartId = Input(UInt(64.W))
+ val r0Vbank = Input(UInt(32.W))
+ val r0Hash = Input(UInt(32.W))
+ val r1Vbank = Input(UInt(32.W))
+ val r1Hash = Input(UInt(32.W))
+ val w0Vbank = Input(UInt(32.W))
+ val w0Hash = Input(UInt(32.W))
+ val fire = Input(Bool())
+ })
+
+ setInline(
+ "BTraceDPI.v",
+ """
+ |module BTraceDPI(
+ | input clock,
+ | input reset,
+ | input [63:0] instId,
+ | input [63:0] hartId,
+ | input [31:0] r0Vbank,
+ | input [31:0] r0Hash,
+ | input [31:0] r1Vbank,
+ | input [31:0] r1Hash,
+ | input [31:0] w0Vbank,
+ | input [31:0] w0Hash,
+ | input fire
+ |);
+ |""".stripMargin + DpiGuard.wrapBTrace(
+ """
+ | import "DPI-C" context function void dpi_btrace(
+ | input int unsigned inst_id_lo,
+ | input int unsigned inst_id_hi,
+ | input int unsigned hart_id_lo,
+ | input int unsigned hart_id_hi,
+ | input int unsigned r0_vbank,
+ | input int unsigned r0_hash,
+ | input int unsigned r1_vbank,
+ | input int unsigned r1_hash,
+ | input int unsigned w0_vbank,
+ | input int unsigned w0_hash
+ | );
+ | always @(posedge clock) begin
+ | if (!reset && fire) begin
+ | dpi_btrace(instId[31:0], instId[63:32], hartId[31:0], hartId[63:32], r0Vbank, r0Hash, r1Vbank, r1Hash, w0Vbank, w0Hash);
+ | end
+ | end
+ |""".stripMargin
+ ) +
+ """
+ |endmodule
+ |""".stripMargin
+ )
+}
diff --git a/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
new file mode 100644
index 00000000..040fbd15
--- /dev/null
+++ b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
@@ -0,0 +1,13 @@
+package framework.memdomain.backend.banks.btrace
+
+import chisel3._
+import framework.top.GlobalConfig
+
+class PhysicalBankHash(val b: GlobalConfig) extends Bundle {
+ val valid = Bool()
+ val hartId = UInt(b.cpu.xLen.W)
+ val vbankId = UInt(b.memDomain.vbankIdWidth.W)
+ val pbankId = UInt(32.W)
+ val groupId = UInt(32.W)
+ val statusHash = UInt(32.W)
+}
diff --git a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
index 6ed56dcd..e43815f3 100644
--- a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
@@ -5,8 +5,10 @@ import chisel3.util._
import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate}
import framework.memdomain.frontend.mem.MemConfigerIO
import framework.memdomain.backend.{MTraceDPI, MemRequestIO}
+import sims.hash.BankHashMonitor
import framework.memdomain.backend.accpipe.AccPipe
import framework.memdomain.backend.banks.SramBank
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
import framework.top.GlobalConfig
@instantiable
@@ -20,11 +22,19 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// Query interface for frontend to get group count
val query_vbank_id = Input(UInt(b.memDomain.vbankIdWidth.W))
val query_group_count = Output(UInt(b.memDomain.groupCountWidth.W))
+ val bank_hashes = if (b.sim.diffTest) Some(Output(Vec(b.memDomain.bankNum, new PhysicalBankHash(b)))) else None
})
val banks: Seq[Instance[SramBank]] = Seq.fill(b.memDomain.bankNum)(Instantiate(new SramBank(b)))
val accPipes: Seq[Instance[AccPipe]] = Seq.fill(b.memDomain.bankChannel)(Instantiate(new AccPipe(b)))
+ val hashMonitors =
+ if (b.sim.diffTest) {
+ Some(Seq.fill(b.memDomain.bankNum)(Instantiate(new BankHashMonitor(b))))
+ } else {
+ None
+ }
+
// Per-channel memory trace DPI-C modules to avoid losing simultaneous events
val mtraces = Seq.fill(b.memDomain.bankChannel)(Module(new MTraceDPI))
for (mt <- mtraces) {
@@ -35,6 +45,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
mt.io.channel := 0.U
mt.io.hart_id := 0.U
mt.io.rob_id := 0.U
+ mt.io.inst_id := 0.U
mt.io.vbank_id := 0.U
mt.io.pbank_id := 0.U
mt.io.group_id := 0.U
@@ -50,6 +61,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// -----------------------------------------------------------------------------
class MappingTableEntry extends Bundle {
val valid = Bool()
+ val hart_id = UInt(b.cpu.xLen.W)
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
val group_id = UInt(b.memDomain.groupIdWidth.W)
@@ -85,6 +97,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
)
def addEntry(
+ hart_id: UInt,
vbank_id: UInt,
pbank_id: UInt,
is_multi: Bool,
@@ -92,6 +105,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
): Unit = {
val entry = mappingTable(pbank_id)
entry.valid := true.B
+ entry.hart_id := hart_id
entry.vbank_id := vbank_id
entry.is_multi := is_multi
entry.group_id := group_id
@@ -117,6 +131,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
accPipes(i).io.mem_req.is_shared := io.mem_req(i).is_shared
accPipes(i).io.mem_req.hart_id := io.mem_req(i).hart_id
accPipes(i).io.mem_req.rob_id := io.mem_req(i).rob_id
+ accPipes(i).io.mem_req.inst_id := io.mem_req(i).inst_id
// Bank-side defaults (only driven when a bank is actually connected)
accPipes(i).io.sramRead.req.ready := false.B
@@ -154,11 +169,18 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// Bank Alloc/Release
// -----------------------------------------------------------------------------
+ hashMonitors.foreach(_.foreach(_.io.bind := false.B))
+
when(io.config.fire) {
val vbank = io.config.bits.vbank_id
val vbankIdx = vbank(privateVbankIdWidth - 1, 0)
when(io.config.bits.alloc) {
val freePbank = PriorityEncoder(freePbankMask)
+ hashMonitors.foreach { hashes =>
+ for (i <- 0 until b.memDomain.bankNum) {
+ hashes(i).io.bind := freePbank === i.U
+ }
+ }
// Match bemu mset: realloc of the same vbank frees prior physical banks first.
// MemConfiger emits one fire per group; only group 0 drops the old mapping.
when(io.config.bits.group_id === 0.U) {
@@ -166,6 +188,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
singleRouteValid(vbankIdx) := false.B
}
addEntry(
+ io.config.bits.hart_id,
io.config.bits.vbank_id,
freePbank,
io.config.bits.is_multi,
@@ -208,6 +231,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
mtraces(ch).io.channel := ch.U
mtraces(ch).io.hart_id := io.mem_req(ch).hart_id
mtraces(ch).io.rob_id := io.mem_req(ch).rob_id
+ mtraces(ch).io.inst_id := io.mem_req(ch).inst_id
mtraces(ch).io.vbank_id := io.mem_req(ch).bank_id
mtraces(ch).io.pbank_id := pbankId
mtraces(ch).io.group_id := io.mem_req(ch).group_id
@@ -227,6 +251,10 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val channelReqAddr = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(log2Ceil(b.memDomain.bankEntries).W)))
val channelReqData = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.bankWidth.W)))
val channelReqMask = Seq.fill(b.memDomain.bankChannel)(Wire(Vec(b.memDomain.bankMaskLen, Bool())))
+ val channelHartId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.cpu.xLen.W)))
+ val channelInstId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(64.W)))
+ val channelVbankId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.vbankIdWidth.W)))
+ val channelGroupId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.groupIdWidth.W)))
for (i <- 0 until b.memDomain.bankChannel) {
val routePbankReg = RegInit(0.U(pbankIndexWidth.W))
@@ -268,6 +296,10 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
)
channelReqData(i) := accPipes(i).io.sramWrite.req.bits.data
channelReqMask(i) := accPipes(i).io.sramWrite.req.bits.mask
+ channelHartId(i) := io.mem_req(i).hart_id
+ channelInstId(i) := io.mem_req(i).inst_id
+ channelVbankId(i) := io.mem_req(i).bank_id
+ channelGroupId(i) := io.mem_req(i).group_id
// SramBank is a pure single-port SRAM: the selected operation is always
// accepted when its route is active. Using the held route directly avoids
@@ -330,6 +362,10 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val selectedReqMask = VecInit((0 until b.memDomain.bankMaskLen).map { k =>
oneHotOr(1, channelReqMask.map(_(k))).asBool
})
+ val selectedHartId = oneHotOr(b.cpu.xLen, channelHartId)
+ val selectedInstId = oneHotOr(64, channelInstId)
+ val selectedVbankId = oneHotOr(b.memDomain.vbankIdWidth, channelVbankId)
+ val selectedGroupId = oneHotOr(b.memDomain.groupIdWidth, channelGroupId)
banks(j).io.sramRead.req.valid := selectedReqValid && !selectedReqIsWrite
banks(j).io.sramRead.req.bits.addr := selectedReqAddr
@@ -338,6 +374,14 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
banks(j).io.sramWrite.req.bits.data := selectedReqData
banks(j).io.sramWrite.req.bits.mask := selectedReqMask
+ hashMonitors.foreach { hashes =>
+ val monitor = hashes(j)
+ monitor.io.write.valid := banks(j).io.sramWrite.req.fire
+ monitor.io.write.bits.addr := selectedReqAddr
+ monitor.io.write.bits.mask := selectedReqMask
+ monitor.io.write.bits.data := selectedReqData
+ }
+
// Only the channel holding this bank can consume its one-cycle response.
banks(j).io.sramRead.resp.ready := VecInit((0 until b.memDomain.bankChannel).map { i =>
activeRouteOHs(i)(j) && accPipes(i).io.sramRead.resp.ready
@@ -364,4 +408,15 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
accPipes(i).io.sramWrite.resp.valid := writeRespSel.orR
accPipes(i).io.sramWrite.resp.bits.ok := writeRespSel.orR
}
+
+ io.bank_hashes.foreach { states =>
+ for (i <- 0 until b.memDomain.bankNum) {
+ states(i).valid := mappingTable(i).valid
+ states(i).hartId := mappingTable(i).hart_id
+ states(i).vbankId := mappingTable(i).vbank_id
+ states(i).pbankId := i.U
+ states(i).groupId := mappingTable(i).group_id
+ states(i).statusHash := hashMonitors.get(i).io.statusHash
+ }
+ }
}
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
index a506bc6c..4647eaf4 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
@@ -22,22 +22,22 @@ object SharedMemLayout {
if (!b.memDomain.sharedEnable) {
return 0
}
- require(b.top.nCores > 0, s"nCores(${b.top.nCores}) must be > 0")
+ require(b.memDomain.nCores > 0, s"nCores(${b.memDomain.nCores}) must be > 0")
require(
b.memDomain.sharedInputChannels > 0,
s"sharedInputChannels(${b.memDomain.sharedInputChannels}) must be > 0"
)
require(
- b.memDomain.sharedInputChannels % b.top.nCores == 0,
- s"sharedInputChannels(${b.memDomain.sharedInputChannels}) must be divisible by nCores(${b.top.nCores})"
+ b.memDomain.sharedInputChannels % b.memDomain.nCores == 0,
+ s"sharedInputChannels(${b.memDomain.sharedInputChannels}) must be divisible by nCores(${b.memDomain.nCores})"
)
if (b.memDomain.sharedInputChannels > 32) {
require(
- b.memDomain.sharedInputChannels == b.top.nCores,
- s"sharedInputChannels(${b.memDomain.sharedInputChannels}) must equal nCores(${b.top.nCores}) when > 32"
+ b.memDomain.sharedInputChannels == b.memDomain.nCores,
+ s"sharedInputChannels(${b.memDomain.sharedInputChannels}) must equal nCores(${b.memDomain.nCores}) when > 32"
)
}
- val ch = b.memDomain.sharedInputChannels / b.top.nCores
+ val ch = b.memDomain.sharedInputChannels / b.memDomain.nCores
require(ch > 0, s"channelPerHart($ch) must be > 0")
ch
}
@@ -46,14 +46,14 @@ object SharedMemLayout {
}
class SharedMemReadReq(val b: GlobalConfig) extends Bundle {
- val hartid = UInt(b.core.xLen.W)
+ val hartid = UInt(b.cpu.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
}
class SharedMemWriteReq(val b: GlobalConfig) extends Bundle {
- val hartid = UInt(b.core.xLen.W)
+ val hartid = UInt(b.cpu.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
index ccf085b1..5b7cb859 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
@@ -4,14 +4,16 @@ import chisel3._
import chisel3.util._
import chisel3.experimental.hierarchy.{instantiable, public, Instance, Instantiate}
import framework.memdomain.backend.{MTraceDPI, MemRequestIO}
+import sims.hash.BankHashMonitor
import framework.memdomain.backend.accpipe.AccPipe
import framework.memdomain.backend.banks.SramBank
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
import framework.memdomain.frontend.mem.MemConfigerIO
import framework.top.GlobalConfig
@instantiable
class SharedMemBackend(val b: GlobalConfig) extends Module {
- private val nCores = b.top.nCores
+ val nCores = b.memDomain.nCores
private val totalBanks = SharedMemLayout.totalBank(b)
private val totalChannel = SharedMemLayout.totalChannel(b)
@@ -22,14 +24,22 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
// Query interface for frontend to get group count
val query_valid = Input(Vec(nCores, Bool()))
- val query_hart_id = Input(Vec(nCores, UInt(b.core.xLen.W)))
+ val query_hart_id = Input(Vec(nCores, UInt(b.cpu.xLen.W)))
val query_vbank_id = Input(Vec(nCores, UInt(b.memDomain.vbankIdWidth.W)))
val query_group_count = Output(Vec(nCores, UInt(b.memDomain.groupCountWidth.W)))
+ val bank_hashes = if (b.sim.diffTest) Some(Output(Vec(totalBanks, new PhysicalBankHash(b)))) else None
})
val banks: Seq[Instance[SramBank]] = Seq.fill(totalBanks)(Instantiate(new SramBank(b)))
val accPipes: Seq[Instance[AccPipe]] = Seq.fill(totalChannel)(Instantiate(new AccPipe(b)))
+ val hashMonitors =
+ if (b.sim.diffTest) {
+ Some(Seq.fill(totalBanks)(Instantiate(new BankHashMonitor(b))))
+ } else {
+ None
+ }
+
// Per-channel memory trace DPI-C modules to avoid losing simultaneous events
val mtraces = Seq.fill(totalChannel)(Module(new MTraceDPI))
for (mt <- mtraces) {
@@ -40,6 +50,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
mt.io.channel := 0.U
mt.io.hart_id := 0.U
mt.io.rob_id := 0.U
+ mt.io.inst_id := 0.U
mt.io.vbank_id := 0.U
mt.io.pbank_id := 0.U
mt.io.group_id := 0.U
@@ -55,7 +66,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
// -----------------------------------------------------------------------------
class MappingTableEntry extends Bundle {
val valid = Bool()
- val hart_id = UInt(b.core.xLen.W)
+ val hart_id = UInt(b.cpu.xLen.W)
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
val group_id = UInt(b.memDomain.groupIdWidth.W)
@@ -123,6 +134,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
accPipes(i).io.mem_req.is_shared := io.mem_req(i).is_shared
accPipes(i).io.mem_req.hart_id := io.mem_req(i).hart_id
accPipes(i).io.mem_req.rob_id := io.mem_req(i).rob_id
+ accPipes(i).io.mem_req.inst_id := io.mem_req(i).inst_id
// Bank-side defaults (only driven when a bank is actually connected)
accPipes(i).io.sramRead.req.ready := false.B
@@ -164,12 +176,19 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
// Bank Alloc/Release
// -----------------------------------------------------------------------------
+ hashMonitors.foreach(_.foreach(_.io.bind := false.B))
+
when(io.config.fire) {
when(io.config.bits.alloc) {
when(io.config.bits.group_id === 0.U) {
clearVbank(io.config.bits.hart_id, io.config.bits.vbank_id)
}
val pbankId = PriorityEncoder(freePbankMask)
+ hashMonitors.foreach { hashes =>
+ for (i <- 0 until totalBanks) {
+ hashes(i).io.bind := pbankId === i.U
+ }
+ }
printf(
p"[SharedMemBackend][ALLOC] hart=${io.config.bits.hart_id} vbank=0x${Hexadecimal(io.config.bits.vbank_id)} " +
p"group=${io.config.bits.group_id} pbank=$pbankId is_multi=${io.config.bits.is_multi}\n"
@@ -233,6 +252,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
mtraces(ch).io.channel := ch.U
mtraces(ch).io.hart_id := io.mem_req(ch).hart_id
mtraces(ch).io.rob_id := io.mem_req(ch).rob_id
+ mtraces(ch).io.inst_id := io.mem_req(ch).inst_id
mtraces(ch).io.vbank_id := io.mem_req(ch).bank_id
mtraces(ch).io.pbank_id := pbankId
mtraces(ch).io.group_id := io.mem_req(ch).group_id
@@ -294,4 +314,37 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
}
}
}
+
+ hashMonitors.foreach { hashes =>
+ for (j <- 0 until totalBanks) {
+ val writeHits = VecInit((0 until totalChannel).map { i =>
+ val activeHart = Mux(accPipes(i).io.busy, accPipes(i).io.hart_id, io.mem_req(i).hart_id)
+ val activeBank = Mux(accPipes(i).io.busy, accPipes(i).io.bank_id, io.mem_req(i).bank_id)
+ val activeGroup = Mux(accPipes(i).io.busy, accPipes(i).io.group_id, io.mem_req(i).group_id)
+ mappingTable(j).valid &&
+ mappingTable(j).hart_id === activeHart &&
+ mappingTable(j).vbank_id === activeBank &&
+ (!mappingTable(j).is_multi || mappingTable(j).group_id === activeGroup) &&
+ accPipes(i).io.sramWrite.req.fire
+ })
+ val writeValid = writeHits.asUInt.orR
+ val monitor = hashes(j)
+
+ monitor.io.write.valid := writeValid
+ monitor.io.write.bits.addr := banks(j).io.sramWrite.req.bits.addr
+ monitor.io.write.bits.mask := banks(j).io.sramWrite.req.bits.mask
+ monitor.io.write.bits.data := banks(j).io.sramWrite.req.bits.data
+ }
+ }
+
+ io.bank_hashes.foreach { states =>
+ for (i <- 0 until totalBanks) {
+ states(i).valid := mappingTable(i).valid
+ states(i).hartId := mappingTable(i).hart_id
+ states(i).vbankId := mappingTable(i).vbank_id
+ states(i).pbankId := i.U
+ states(i).groupId := mappingTable(i).group_id
+ states(i).statusHash := hashMonitors.get(i).io.statusHash
+ }
+ }
}
diff --git a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
index 10571603..757794c0 100644
--- a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
+++ b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
@@ -19,6 +19,7 @@ case class MemDomainParam(
sharedEntries: Int,
sharedInputChannels: Int,
sharedDefaultGroupCount: Int,
+ nCores: Int,
tlb_size: Int,
dma_n_xacts: Int,
dma_burst_maxbytes: Int,
@@ -57,6 +58,7 @@ object MemDomainParam {
sharedEntries = 0,
sharedInputChannels = 0,
sharedDefaultGroupCount = 0,
+ nCores = 0,
tlb_size = 0,
dma_n_xacts = 0,
dma_burst_maxbytes = 0,
diff --git a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
index 0e950e28..2e86e289 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
@@ -60,7 +60,7 @@ class MemFrontend(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val query_is_shared = Output(Bool())
val query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
- val hartid = Input(UInt(b.core.xLen.W))
+ val hartid = Input(UInt(b.cpu.xLen.W))
// Busy signal
val busy = Output(Bool())
diff --git a/arch/src/main/scala/framework/memdomain/frontend/cmd/decoder/DomainDecoder.scala b/arch/src/main/scala/framework/memdomain/frontend/cmd/decoder/DomainDecoder.scala
index dcd6140c..336a7e22 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/cmd/decoder/DomainDecoder.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/cmd/decoder/DomainDecoder.scala
@@ -74,7 +74,8 @@ class MemDomainDecoder(val b: GlobalConfig) extends Module {
val rs2 = io.cmd_i.bits.cmd.rs2Data
// Unified encoding:
- // rs1[9:0] = bank_id (BANK0)
+ // rs1[9:0] = read/config bank (BANK0)
+ // rs1[29:20] = write bank (BANK2)
// rs1[63:30] = iter (34-bit)
// funct7[6:4] = enable (bank access flags, decoded by GlobalDecoder)
// rs2[38:0] = mem_addr (for MVIN/MVOUT, 39-bit)
@@ -85,8 +86,8 @@ class MemDomainDecoder(val b: GlobalConfig) extends Module {
val ls_default_decode = List(N, N, DADDR, DADDR, DSPECIAL, N)
val ls_decode_list = ListLookup(func7, ls_default_decode, Array(
MSET_BITPAT -> List(N, N, 0.U(memAddrLen.W), rs1(bankIdLen - 1, 0), rs2, Y),
- MVIN_BITPAT -> List(Y, N, rs2(memAddrLen - 1, 0), rs1(bankIdLen - 1, 0), rs2, Y),
- MVIN_2D_BITPAT -> List(Y, N, rs2(31, 0), rs1(bankIdLen - 1, 0), rs2, Y),
+ MVIN_BITPAT -> List(Y, N, rs2(memAddrLen - 1, 0), rs1(bankIdLen + 19, 20), rs2, Y),
+ MVIN_2D_BITPAT -> List(Y, N, rs2(31, 0), rs1(bankIdLen + 19, 20), rs2, Y),
MVOUT_BITPAT -> List(N, Y, rs2(memAddrLen - 1, 0), rs1(bankIdLen - 1, 0), rs2, Y),
MVIN_MMIO_BITPAT -> List(Y, N, rs2(memAddrLen - 1, 0), 0.U(bankIdLen.W), rs2, Y)
)
@@ -104,7 +105,7 @@ class MemDomainDecoder(val b: GlobalConfig) extends Module {
// -----------------------------------------------------------------------------
io.mem_decode_cmd_o.valid := io.cmd_i.valid && (io.cmd_i.bits.domain_id === DomainId.MEM)
- val raw_bank_id = rs1(9, 0)
+ val raw_bank_id = Mux(func7 === MVIN_BITPAT || func7 === MVIN_2D_BITPAT, rs1(29, 20), rs1(9, 0))
val shared_bank_id = b.memDomain.sharedEnable.B && raw_bank_id >= sharedBankIdBase.U
// format: off
// BB_BANK0 is encoded in rs1[9:0]. Keep the configured architectural ID;
@@ -136,6 +137,9 @@ class MemDomainDecoder(val b: GlobalConfig) extends Module {
assert(rs2(54, 49) + height * width <= b.memDomain.bankEntries.U, "MVIN_2D destination exceeds bank")
assert(rs2(63, 62) === 0.U, "MVIN_2D reserves rs2[63:62]")
}
+ when(io.cmd_i.fire && (func7 === MVIN_BITPAT || func7 === MVIN_2D_BITPAT)) {
+ assert(rs1(19, 0) === 0.U, "MVIN write-bank encoding reserves rs1[19:0]")
+ }
val ls_bank_id = ls_decode_list(LSDecodeFields.BANK_ID.id).asUInt
io.mem_decode_cmd_o.bits.bank_id := Mux(io.mem_decode_cmd_o.valid, ls_bank_id, 0.U(b.memDomain.vbankIdWidth.W))
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
index 1df707f3..c4b64e62 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
@@ -14,7 +14,7 @@ class MemConfigerIO(val b: GlobalConfig) extends Bundle {
val is_multi = Output(Bool())
val alloc = Output(Bool())
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
- val hart_id = Output(UInt(b.core.xLen.W))
+ val hart_id = Output(UInt(b.cpu.xLen.W))
}
@instantiable
@@ -26,7 +26,7 @@ class MemConfiger(val b: GlobalConfig) extends Module {
val cmdReq = Flipped(Decoupled(new MemRsIssue(b)))
val cmdResp = Decoupled(new MemRsComplete(b))
val config = Decoupled(new MemConfigerIO(b))
- val hartid = Input(UInt(b.core.xLen.W))
+ val hartid = Input(UInt(b.cpu.xLen.W))
val bankWrite = Flipped(new BankWrite(b))
})
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
index b657e8d1..cf1890b6 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
@@ -89,7 +89,7 @@ class StreamReader(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val bytesLeft = reqReg.len - bytesRequested
val groupsLeftInRow = reqReg.groups - groupIdx
val rowBytesLeft = groupsLeftInRow << lgBeat
- val pageBytesLeft = (1.U << b.core.pgIdxBits) - readVaddr(b.core.pgIdxBits - 1, 0)
+ val pageBytesLeft = (1.U << b.cpu.pgIdxBits) - readVaddr(b.cpu.pgIdxBits - 1, 0)
val maxBurstBytes = Seq(bytesLeft, rowBytesLeft, pageBytesLeft, burstMaxBytes.U).reduce((a, c) => Mux(a < c, a, c))
val burstCandidates = Iterator.iterate(beatBytes)(_ * 2).takeWhile(_ <= burstMaxBytes).toSeq
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
index b4af052a..6d7ad51d 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
@@ -23,7 +23,7 @@ class BBWriteResponse extends Bundle {
@instantiable
class StreamWriter(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
- val vaddrBits = b.core.vaddrBits
+ val vaddrBits = b.cpu.vaddrBits
val beatBits = b.memDomain.dma_buswidth
val dataWidth = b.memDomain.dma_buswidth
val beatBytes = beatBits / 8
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
index ec84cc19..824eb600 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
@@ -146,12 +146,12 @@ class BBPMP(val paddrBits: Int) extends Bundle {
// PTW IO
class BBTLBPTWIO(val b: GlobalConfig) extends Bundle {
- val vaddrBits = b.core.vaddrBits
- val paddrBits = b.core.paddrBits
- val pgIdxBits = b.core.pgIdxBits
- val xLen = b.core.xLen
- val pgLevels = b.rocketCore.pgLevels
- val nPMPs = b.core.nPMPs
+ val vaddrBits = b.cpu.vaddrBits
+ val paddrBits = b.cpu.paddrBits
+ val pgIdxBits = b.cpu.pgIdxBits
+ val xLen = b.cpu.xLen
+ val pgLevels = b.cpu.pgLevels
+ val nPMPs = b.cpu.nPMPs
val req = Decoupled(Valid(new BBTLBPTWReq(vaddrBits, pgIdxBits)))
val resp = Flipped(Valid(new BBTLBPTWResp(vaddrBits, paddrBits, pgIdxBits, pgLevels)))
@@ -167,7 +167,7 @@ class BBTLBPTWIO(val b: GlobalConfig) extends Bundle {
// TLB Client IO (used in TLBCluster)
class BBTLBIO(val b: GlobalConfig) extends Bundle {
- val lgMaxSize = log2Ceil(b.core.coreDataBytes)
- val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, b.core.vaddrBits, b.core.xLen)))
- val resp = Decoupled(new BBTLBResp(lgMaxSize, b.core.paddrBits, b.core.vaddrBits))
+ val lgMaxSize = log2Ceil(b.cpu.coreDataBytes)
+ val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, b.cpu.vaddrBits, b.cpu.xLen)))
+ val resp = Decoupled(new BBTLBResp(lgMaxSize, b.cpu.paddrBits, b.cpu.vaddrBits))
}
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
index d20708ae..e03a3707 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
@@ -10,16 +10,16 @@ import framework.top.GlobalConfig
@instantiable
class TLB(val b: GlobalConfig, val lgMaxSize: Int) extends Module {
val entries = b.memDomain.tlb_size
- val vaddrBits = b.core.vaddrBits
- val paddrBits = b.core.paddrBits
- val pgIdxBits = b.core.pgIdxBits
+ val vaddrBits = b.cpu.vaddrBits
+ val paddrBits = b.cpu.paddrBits
+ val pgIdxBits = b.cpu.pgIdxBits
val vpnBits = vaddrBits - pgIdxBits
val ppnBits = paddrBits - pgIdxBits
- val pgLevels = b.rocketCore.pgLevels
+ val pgLevels = b.cpu.pgLevels
@public
val io = IO(new Bundle {
- val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, vaddrBits, b.core.xLen)))
+ val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, vaddrBits, b.cpu.xLen)))
val resp = Decoupled(new BBTLBResp(lgMaxSize, paddrBits, vaddrBits))
val ptw = new BBTLBPTWIO(b)
val sfence = Flipped(Valid(Bool())) // Simplified flush signal
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
index 9ed9e71d..2731b8c6 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
@@ -11,11 +11,11 @@ class BBTLBCluster(val b: GlobalConfig)(implicit val edge: TLEdgeOut) extends Mo
val nClients = 2
val entries = b.memDomain.tlb_size
- val maxSize = b.core.coreDataBytes
- val lgMaxSize = log2Ceil(b.core.coreDataBytes)
- val vaddrBits = b.core.vaddrBits
- val paddrBits = b.core.paddrBits
- val pgIdxBits = b.core.pgIdxBits
+ val maxSize = b.cpu.coreDataBytes
+ val lgMaxSize = log2Ceil(b.cpu.coreDataBytes)
+ val vaddrBits = b.cpu.vaddrBits
+ val paddrBits = b.cpu.paddrBits
+ val pgIdxBits = b.cpu.pgIdxBits
@public
val io = IO(new Bundle {
@@ -33,7 +33,7 @@ class BBTLBCluster(val b: GlobalConfig)(implicit val edge: TLEdgeOut) extends Mo
// Connect PTW
io.ptw(0) <> tlb.io.ptw
- val tlbArb = Module(new RRArbiter(new BBTLBReq(lgMaxSize, vaddrBits, b.core.xLen), nClients))
+ val tlbArb = Module(new RRArbiter(new BBTLBReq(lgMaxSize, vaddrBits, b.cpu.xLen), nClients))
val tlbArbOut = tlbArb.io.out
val tlb_io = tlb.io
diff --git a/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala b/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
index 2fc76a7d..f7bb5374 100644
--- a/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
+++ b/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
@@ -5,7 +5,7 @@ import chisel3.util._
import framework.top.GlobalConfig
import framework.balldomain.blink.{BankRead, BankWrite}
import chisel3.experimental.hierarchy.{instantiable, public}
-import framework.memdomain.backend.{MTraceIssueDPI, MemRequestIO}
+import framework.memdomain.backend.MemRequestIO
// BankRead/BankWrite with is_shared flag, used for unified midend interface
class BankReadWithShared(val b: GlobalConfig) extends Bundle {
@@ -44,7 +44,8 @@ class MemMidend(val b: GlobalConfig) extends Module {
val ballChannelActive = Input(Vec(b.ballDomain.ballNum, Bool()))
val ballChannelReady = Output(Vec(b.ballDomain.ballNum, Bool()))
- val hartid = Input(UInt(b.core.xLen.W))
+ val hartid = Input(UInt(b.cpu.xLen.W))
+ val inst_ids = Input(Vec(b.frontend.rob_entries, UInt(64.W)))
// Output to backend (MemManager)
val mem_req = Vec(b.memDomain.bankChannel, new MemRequestIO(b))
@@ -169,6 +170,7 @@ class MemMidend(val b: GlobalConfig) extends Module {
io.mem_req(i).is_shared := false.B
io.mem_req(i).hart_id := io.hartid
io.mem_req(i).rob_id := 0.U
+ io.mem_req(i).inst_id := 0.U
val isRead = mappingTable(i).isRead
val rid = mappingTable(i).id
@@ -197,6 +199,7 @@ class MemMidend(val b: GlobalConfig) extends Module {
io.mem_req(i).group_id := rgroup_id
io.mem_req(i).is_shared := r_shared
io.mem_req(i).rob_id := rrob_id
+ io.mem_req(i).inst_id := io.inst_ids(rrob_id)
}
}.otherwise {
when(ballRouteOpen) {
@@ -205,27 +208,12 @@ class MemMidend(val b: GlobalConfig) extends Module {
io.mem_req(i).group_id := wgroup_id
io.mem_req(i).is_shared := w_shared
io.mem_req(i).rob_id := wrob_id
+ io.mem_req(i).inst_id := io.inst_ids(wrob_id)
}
}
}
}
- // Count the actual write beats accepted by each backend channel. This is the
- // generation-side event at the same granularity as the target SRAM `fire`
- // arrival event, while remaining upstream of the backend/physical-bank path.
- // A DPI instance per channel preserves simultaneous accepted beats.
- val writeIssueTraces = Seq.fill(b.memDomain.bankChannel)(Module(new MTraceIssueDPI))
- for (i <- 0 until b.memDomain.bankChannel) {
- writeIssueTraces(i).io.clock := clock
- writeIssueTraces(i).io.reset := reset.asBool
- writeIssueTraces(i).io.hart_id := io.mem_req(i).hart_id
- writeIssueTraces(i).io.is_shared := io.mem_req(i).is_shared.asUInt
- writeIssueTraces(i).io.rob_id := io.mem_req(i).rob_id
- writeIssueTraces(i).io.vbank_id := io.mem_req(i).bank_id
- writeIssueTraces(i).io.group_id := io.mem_req(i).group_id
- writeIssueTraces(i).io.enable := io.mem_req(i).write.req.fire
- }
-
// Mapping table release
for (i <- 0 until b.memDomain.bankChannel) {
val releaseCounter = RegInit(0.U(5.W))
diff --git a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
index a2d500b3..647b1b2e 100644
--- a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
+++ b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
@@ -17,12 +17,11 @@ import framework.balldomain.configs.{BallDomainParam, BallISAEntry, BallIdMappin
import framework.frontend.configs.FrontendParam
import framework.gpdomain.configs.GpDomainParam
import framework.memdomain.configs.MemDomainParam
-import framework.system.core.configs.CoreParam
+import framework.system.cpu.configs.CpuParam
import framework.system.core.boom.configs.{BoomCoreParam, BoomDCacheParam, BoomICacheParam}
import framework.system.core.rocket.configs._
import framework.system.tile.PrivateDCacheParams
import framework.top.GlobalConfig
-import framework.top.configs.TopConfig
import scala.jdk.CollectionConverters._
/** Load ExampleTopology from chip.pb. */
@@ -74,12 +73,9 @@ object ChipLoader {
}
private def parseTile(tile: TilePlacement, cores: Seq[CoreInstance], repo: Path): TileTopology = {
- val indices = tile.getCoreIndicesList.asScala.map(_.toInt).toSeq
- val nCores = indices.size
- val hasBuckyball = indices.exists(i => cores(i).getBalldomain.getBallNum > 0)
- val memBallChannelNum =
- if (hasBuckyball) tile.getMemBallChannelNum
- else 0
+ val indices = tile.getCoreIndicesList.asScala.map(_.toInt).toSeq
+ val nCores = indices.size
+ val hasBuckyball = indices.exists(i => cores(i).getBalldomain.getBallNum > 0)
val shared = tile.getSharedMem
val virtualBankCount = tile.getVirtualBankCount
@@ -118,24 +114,23 @@ object ChipLoader {
}
val tileCores = indices.map { idx =>
- parseCore(cores(idx), shared, virtualBankCount, memBallChannelNum, nCores, repo)
+ parseCore(cores(idx), shared, virtualBankCount, nCores, repo)
}
TileTopology(tileCores, privateDCache)
}
private def parseCore(
- core: CoreInstance,
- shared: SharedMemConfig,
- virtualBankCount: Int,
- memBallChannelNum: Int,
- nCores: Int,
- repo: Path
+ core: CoreInstance,
+ shared: SharedMemConfig,
+ virtualBankCount: Int,
+ nCores: Int,
+ repo: Path
): TileCore = {
require(core.hasCpu, s"core ${core.getPkg}: missing cpu config")
val cpu = core.getCpu
val kind = cpu.getKind
kind match {
- case "rocket" => parseRocketCoreSlot(core, shared, virtualBankCount, memBallChannelNum, nCores, repo)
+ case "rocket" => parseRocketCoreSlot(core, shared, virtualBankCount, nCores, repo)
case "boom" =>
if (core.getBalldomain.getBallNum > 0) {
throw new RuntimeException(s"core ${core.getPkg}: kind=boom forbids balldomain")
@@ -150,12 +145,11 @@ object ChipLoader {
}
private def parseRocketCoreSlot(
- core: CoreInstance,
- shared: SharedMemConfig,
- virtualBankCount: Int,
- memBallChannelNum: Int,
- nCores: Int,
- repo: Path
+ core: CoreInstance,
+ shared: SharedMemConfig,
+ virtualBankCount: Int,
+ nCores: Int,
+ repo: Path
): RocketTileCore = {
val cpu = core.getCpu
if (!cpu.hasRocket) {
@@ -193,10 +187,8 @@ object ChipLoader {
ballDomain = parseBallDomain(core, repo),
frontend = parseFrontend(core.getFrontend),
gpDomain = parseGpDomain(core.getGpDomain),
- core = parseCoreParam(cpu),
- memDomain = parseMemDomain(core.getMem, shared, virtualBankCount),
- rocketCore = rocket,
- top = TopConfig(memBallChannelNum = memBallChannelNum, nCores = nCores)
+ cpu = parseCpuParam(cpu, rocket.pgLevels),
+ memDomain = parseMemDomain(core.getMem, shared, virtualBankCount, nCores)
)
RocketTileCore(rocket, Some(buckyball))
}
@@ -224,7 +216,8 @@ object ChipLoader {
private def parseMemDomain(
mem: MemDomainConfig,
shared: SharedMemConfig,
- virtualBankCount: Int
+ virtualBankCount: Int,
+ nCores: Int
): MemDomainParam = {
val bank = mem.getBank
val dma = mem.getDma
@@ -241,6 +234,7 @@ object ChipLoader {
sharedEntries = shared.getEntries,
sharedInputChannels = shared.getInputChannels,
sharedDefaultGroupCount = shared.getDefaultGroupCount,
+ nCores = nCores,
tlb_size = tlb.getSize,
dma_n_xacts = dma.getNXacts,
dma_burst_maxbytes = dma.getBurstMaxBytes,
@@ -280,14 +274,15 @@ object ChipLoader {
laneScale = gp.getLaneScale
)
- private def parseCoreParam(core: CpuConfig): CoreParam =
- CoreParam(
- coreDataBytes = core.getCoreDataBytes,
- xLen = core.getXLen,
- vaddrBits = core.getVaddrBits,
- paddrBits = core.getPaddrBits,
- pgIdxBits = core.getPgIdxBits,
- nPMPs = core.getNPmps
+ def parseCpuParam(cpu: CpuConfig, pgLevels: Int): CpuParam =
+ CpuParam(
+ coreDataBytes = cpu.getCoreDataBytes,
+ xLen = cpu.getXLen,
+ vaddrBits = cpu.getVaddrBits,
+ paddrBits = cpu.getPaddrBits,
+ pgIdxBits = cpu.getPgIdxBits,
+ pgLevels = pgLevels,
+ nPMPs = cpu.getNPmps
)
private def parseRocketCore(rocket: RocketCoreConfig): RocketCoreParam = {
diff --git a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
index 15869068..420606d9 100644
--- a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
+++ b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
@@ -15,6 +15,7 @@ import framework.memdomain.backend.shared.SharedMemLayout
import framework.memdomain.frontend.mem.{MemConfigerIO}
import framework.memdomain.frontend.mem.tlb.{BBTLBExceptionIO, BBTLBPTWIO}
import framework.balldomain.BallDomain
+import framework.memdomain.backend.banks.btrace.PhysicalBankHash
/**
* Standalone Buckyball accelerator module.
@@ -28,18 +29,19 @@ import framework.balldomain.BallDomain
*/
@instantiable
class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
- val totalBallRead = b.ballDomain.ballIdMappings.map(_.inBW).sum
- val totalBallWrite = b.ballDomain.ballIdMappings.map(_.outBW).sum
+ val totalBallRead = b.ballDomain.ballIdMappings.map(_.inBW).sum
+ val totalBallWrite = b.ballDomain.ballIdMappings.map(_.outBW).sum
+ val sharedHashCount = if (b.memDomain.sharedEnable) SharedMemLayout.totalBank(b) else 0
@public
val io = IO(new Bundle {
// RoCC command/response (connected to Rocket core inside tile)
- val cmd = Flipped(Decoupled(new RoCCCommandBB(b.core.xLen)))
- val resp = Decoupled(new RoCCResponseBB(b.core.xLen))
+ val cmd = Flipped(Decoupled(new RoCCCommandBB(b.cpu.xLen)))
+ val resp = Decoupled(new RoCCResponseBB(b.cpu.xLen))
val busy = Output(Bool())
val retired = Output(Bool())
val interrupt = Output(Bool())
- val hartid = Input(UInt(b.core.xLen.W))
+ val hartid = Input(UInt(b.cpu.xLen.W))
// PTW interface (shared with Rocket core's PTW)
val ptw = Vec(1, new BBTLBPTWIO(b))
@@ -59,6 +61,13 @@ class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module
val shared_query_vbank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val shared_query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
+ val shared_bank_hashes =
+ if (b.sim.diffTest && b.memDomain.sharedEnable) {
+ Some(Input(Vec(sharedHashCount, new PhysicalBankHash(b))))
+ } else {
+ None
+ }
+
// Barrier interface — connected to tile-level BarrierUnit
val barrier_arrive = Output(Bool())
val barrier_release = Input(Bool())
@@ -69,6 +78,9 @@ class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module
val ballDomain: Instance[BallDomain] = Instantiate(new BallDomain(b))
val memDomain: Instance[MemDomain] = Instantiate(new MemDomain(b)(edge))
val gpDomain: Instance[GpDomain] = Instantiate(new GpDomain(b))
+ frontend.io.hartid := io.hartid
+ frontend.io.bank_hashes.foreach(_ := memDomain.io.bank_hashes.get)
+ memDomain.io.shared_bank_hashes.foreach(_ := io.shared_bank_hashes.get)
// --- Frontend <- cmd ---
frontend.io.cmd.valid := io.cmd.valid
@@ -90,7 +102,8 @@ class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module
// --- Frontend -> MemDomain ---
memDomain.io.global_issue_i <> frontend.io.mem_issue_o
frontend.io.mem_complete_i <> memDomain.io.global_complete_o
- memDomain.io.hartid := io.hartid
+ memDomain.io.hartid := io.hartid
+ memDomain.io.inst_ids := frontend.io.inst_ids
// --- Frontend -> GpDomain ---
gpDomain.io.global_issue_i <> frontend.io.gp_issue_o
diff --git a/arch/src/main/scala/framework/system/core/configs/CoreParam.scala b/arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala
similarity index 62%
rename from arch/src/main/scala/framework/system/core/configs/CoreParam.scala
rename to arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala
index 5f0e0a90..1609deef 100644
--- a/arch/src/main/scala/framework/system/core/configs/CoreParam.scala
+++ b/arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala
@@ -1,27 +1,26 @@
-package framework.system.core.configs
+package framework.system.cpu.configs
import upickle.default._
-/**
- * Core Parameter
- */
-case class CoreParam(
+case class CpuParam(
coreDataBytes: Int,
xLen: Int,
vaddrBits: Int,
paddrBits: Int,
pgIdxBits: Int,
+ pgLevels: Int,
nPMPs: Int) // Physical Memory Protection entries, typically 8 or 16
-object CoreParam {
- implicit val rw: ReadWriter[CoreParam] = macroRW
+object CpuParam {
+ implicit val rw: ReadWriter[CpuParam] = macroRW
- def apply(): CoreParam = CoreParam(
+ def apply(): CpuParam = CpuParam(
coreDataBytes = 0,
xLen = 0,
vaddrBits = 0,
paddrBits = 0,
pgIdxBits = 0,
+ pgLevels = 0,
nPMPs = 0
)
diff --git a/arch/src/main/scala/framework/system/tile/BBTile.scala b/arch/src/main/scala/framework/system/tile/BBTile.scala
index d42591bb..19cf3372 100644
--- a/arch/src/main/scala/framework/system/tile/BBTile.scala
+++ b/arch/src/main/scala/framework/system/tile/BBTile.scala
@@ -44,6 +44,7 @@ import framework.system.core.rocket.RocketBB
import framework.system.core.rocket.id.RVVRoCCDecode
import framework.system.core.accelerator.{BuckyballAccelerator, BuckyballRushBKey, RushBCommandBridge, RushBCoreId}
import framework.memdomain.backend.MemRequestIO
+import framework.top.configs.SimParamKey
import framework.memdomain.backend.shared.SharedMemBackend
import framework.memdomain.backend.shared.SharedMemLayout
import framework.memdomain.frontend.mem.MemConfigerIO
@@ -99,12 +100,15 @@ class BBTile private (
"core-0 must enable buckyball because RoCC cmd/resp is currently wired to core-0 only"
)
val cfg0 = bbSharedConfig.get
- require(cfg0.top.nCores == nCores, s"buckyball top.nCores (${cfg0.top.nCores}) must equal tile nCores ($nCores)")
+ require(
+ cfg0.memDomain.nCores == nCores,
+ s"buckyball memDomain.nCores (${cfg0.memDomain.nCores}) must equal tile nCores ($nCores)"
+ )
bbEnabledCoreIds.foreach { i =>
val cfg = bbPerCore(i).get
require(
- cfg.top.nCores == nCores,
- s"core-$i buckyball top.nCores (${cfg.top.nCores}) must equal tile nCores ($nCores)"
+ cfg.memDomain.nCores == nCores,
+ s"core-$i buckyball memDomain.nCores (${cfg.memDomain.nCores}) must equal tile nCores ($nCores)"
)
require(cfg.memDomain.bankChannel == cfg0.memDomain.bankChannel, s"core-$i bankChannel mismatch")
require(cfg.memDomain.dma_buswidth == cfg0.memDomain.dma_buswidth, s"core-$i dma_buswidth mismatch")
@@ -367,6 +371,7 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
val nCores = outer.nCores
val rushBEnabled = outer.p(BuckyballRushBKey)
+ val simParam = outer.p(SimParamKey)
def coreParamsForCore(coreIdx: Int): BBTileParams =
outer.bbParams.copy(core = outer.bbParams.rocketCoreForCore(coreIdx))
@@ -607,7 +612,7 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
}
if (outer.hasBuckyball) {
- val cfg0 = outer.bbSharedConfig.get
+ val cfg0 = outer.bbSharedConfig.get.copy(sim = simParam)
val sharedPerCore = SharedMemLayout.channelPerHart(cfg0)
// Instantiate accelerators for enabled cores only
@@ -615,7 +620,7 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
outer.bbPerCore(i).map { cfg =>
val (tl_reader, edge) = outer.bb_reader_nodes(i).get.out(0)
val (tl_writer, _) = outer.bb_writer_nodes(i).get.out(0)
- val acc = Module(new BuckyballAccelerator(cfg)(edge))
+ val acc = Module(new BuckyballAccelerator(cfg.copy(sim = simParam))(edge))
acc.io.hartid := hartIdForCore(i)
tl_reader <> acc.io.tl_reader
@@ -633,7 +638,7 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
if (rushBEnabled) {
val source = Module(new RushBCommandBridge(
RushBCoreId(outer.bbParams.tileId, i),
- accelerator.b.core.xLen
+ accelerator.b.cpu.xLen
))
source.io.retired := accelerator.io.retired
Some(source)
@@ -668,6 +673,12 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
// SharedMemBackend (tile-level singleton)
val sharedBackend = Module(new SharedMemBackend(cfg0))
+ if (cfg0.sim.diffTest) {
+ for (acc <- enabledAccelerators) {
+ acc.io.shared_bank_hashes.get := sharedBackend.io.bank_hashes.get
+ }
+ }
+
// Connect each accelerator's shared ports to the SharedMemBackend
for (i <- 0 until nCores) {
for (ch <- 0 until sharedPerCore) {
diff --git a/arch/src/main/scala/framework/system/tile/Configs.scala b/arch/src/main/scala/framework/system/tile/Configs.scala
index e87c7b27..c9adb2ec 100644
--- a/arch/src/main/scala/framework/system/tile/Configs.scala
+++ b/arch/src/main/scala/framework/system/tile/Configs.scala
@@ -24,35 +24,8 @@ object WithNBBTiles {
}
)
- /**
- * Resolve the per-tile rocketCore param from buckyballPerCore.
- *
- * Multi-core within a tile currently shares one RocketCoreParam (BBTileParams
- * has tile-level core/dcache/icache fields). All Some(_) entries must agree.
- * Falls back to RocketCoreParam() when nothing is defined.
- */
- def resolveRocketCore(
- buckyballPerCore: Seq[Option[GlobalConfig]],
- buckyballConfig: GlobalConfig
- ): RocketCoreParam = {
- val defined = buckyballPerCore.flatten.map(_.rocketCore)
- if (defined.isEmpty) {
- buckyballConfig.rocketCore
- } else {
- val head = defined.head
- require(
- defined.forall(_ == head),
- "All cores within a BBTile must currently share the same rocketCore config; " +
- "heterogeneous per-core Rocket params is not yet supported."
- )
- head
- }
- }
-
def resolveRocketCores(
nCoresPerTile: Int,
- buckyballPerCore: Seq[Option[GlobalConfig]],
- buckyballConfig: GlobalConfig,
rocketCorePerCore: Option[Seq[RocketCoreParam]]
): Seq[RocketCoreParam] = {
rocketCorePerCore match {
@@ -63,7 +36,7 @@ object WithNBBTiles {
)
cores
case None =>
- Seq.fill(nCoresPerTile)(resolveRocketCore(buckyballPerCore, buckyballConfig))
+ throw new RuntimeException("rocketCorePerCore must be specified")
}
}
@@ -93,8 +66,6 @@ class WithBBTile(
)
val rocketCores = WithNBBTiles.resolveRocketCores(
nCoresPerTile,
- resolvedBuckyballPerCore,
- buckyballConfig,
rocketCorePerCore
)
val rocketCore = rocketCores.head
@@ -145,8 +116,6 @@ class WithNBBTiles(
)
val rocketCores = WithNBBTiles.resolveRocketCores(
nCoresPerTile,
- resolvedBuckyballPerCore,
- buckyballConfig,
rocketCorePerCore
)
val rocketCore = rocketCores.head
diff --git a/arch/src/main/scala/framework/top/GlobalConfig.scala b/arch/src/main/scala/framework/top/GlobalConfig.scala
index 0bec473b..4fcfc150 100644
--- a/arch/src/main/scala/framework/top/GlobalConfig.scala
+++ b/arch/src/main/scala/framework/top/GlobalConfig.scala
@@ -6,18 +6,16 @@ import framework.memdomain.configs.MemDomainParam
import framework.frontend.configs.FrontendParam
import framework.gpdomain.configs.GpDomainParam
import framework.balldomain.configs.BallDomainParam
-import framework.system.core.configs.CoreParam
-import framework.system.core.rocket.configs.RocketCoreParam
-import framework.top.configs.TopConfig
+import framework.system.cpu.configs.CpuParam
+import framework.top.configs.SimParam
case class GlobalConfig(
memDomain: MemDomainParam,
frontend: FrontendParam,
gpDomain: GpDomainParam,
ballDomain: BallDomainParam,
- core: CoreParam,
- top: TopConfig,
- rocketCore: RocketCoreParam)
+ cpu: CpuParam,
+ sim: SimParam)
extends SerializableModuleParameter
object GlobalConfig {
@@ -29,9 +27,8 @@ object GlobalConfig {
frontend = FrontendParam(),
gpDomain = GpDomainParam(),
ballDomain = BallDomainParam(),
- core = CoreParam(),
- top = TopConfig(),
- rocketCore = RocketCoreParam()
+ cpu = CpuParam(),
+ sim = SimParam()
)
}
diff --git a/arch/src/main/scala/framework/top/configs/SimParam.scala b/arch/src/main/scala/framework/top/configs/SimParam.scala
new file mode 100644
index 00000000..27712cb7
--- /dev/null
+++ b/arch/src/main/scala/framework/top/configs/SimParam.scala
@@ -0,0 +1,17 @@
+package framework.top.configs
+
+import org.chipsalliance.cde.config.{Config, Field}
+import upickle.default._
+
+case class SimParam(diffTest: Boolean = false)
+
+object SimParam {
+ implicit val rw: ReadWriter[SimParam] = macroRW
+}
+
+case object SimParamKey extends Field[SimParam](SimParam())
+
+class WithSimParam(param: SimParam)
+ extends Config((site, here, up) => {
+ case SimParamKey => param
+ })
diff --git a/arch/src/main/scala/framework/top/configs/TopConfig.scala b/arch/src/main/scala/framework/top/configs/TopConfig.scala
deleted file mode 100644
index 909509d0..00000000
--- a/arch/src/main/scala/framework/top/configs/TopConfig.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package framework.top.configs
-
-import upickle.default._
-
-case class TopConfig(
- memBallChannelNum: Int,
- nCores: Int)
-
-object TopConfig {
- implicit val rw: ReadWriter[TopConfig] = macroRW
-
- /** Stub; real values come from ChipLoader (tile + derived nCores). */
- def apply(): TopConfig = TopConfig(memBallChannelNum = 0, nCores = 0)
-}
diff --git a/arch/src/main/scala/sims/hash/BankHash.scala b/arch/src/main/scala/sims/hash/BankHash.scala
new file mode 100644
index 00000000..901beb0b
--- /dev/null
+++ b/arch/src/main/scala/sims/hash/BankHash.scala
@@ -0,0 +1,75 @@
+package sims.hash
+
+import chisel3._
+import chisel3.experimental.hierarchy.{instantiable, public}
+import chisel3.util._
+import framework.top.GlobalConfig
+
+class BankHashWrite(val b: GlobalConfig) extends Bundle {
+ val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
+ val mask = Vec(b.memDomain.bankMaskLen, Bool())
+ val data = UInt(b.memDomain.bankWidth.W)
+}
+
+@instantiable
+class BankHashMonitor(val b: GlobalConfig) extends Module {
+ require(b.memDomain.bankWidth == 128, "bank hash requires 128-bit bank rows")
+ require(b.memDomain.bankMaskLen == 16, "bank hash requires byte write masks")
+
+ @public
+ val io = IO(new Bundle {
+ val bind = Input(Bool())
+ val write = Flipped(Valid(new BankHashWrite(b)))
+ val statusHash = Output(UInt(32.W))
+ })
+
+ val shadow = SyncReadMem(b.memDomain.bankEntries, UInt(128.W))
+ val validRows = RegInit(VecInit(Seq.fill(b.memDomain.bankEntries)(false.B)))
+ val generation = RegInit(0.U(8.W))
+ val statusHash = RegInit(0.U(32.W))
+
+ def rotateLeft(value: UInt, amount: Int): UInt =
+ Cat(value(31 - amount, 0), value(31, 32 - amount))
+
+ def rowHash(addr: UInt, row: UInt): UInt = {
+ val address = addr.pad(32)
+ val mixed = row(31, 0) ^ rotateLeft(row(63, 32), 7) ^ rotateLeft(row(95, 64), 13) ^
+ rotateLeft(row(127, 96), 21) ^ rotateLeft(address, 11)
+ Mux(row.orR, mixed, 0.U)
+ }
+
+ val readData = shadow.read(io.write.bits.addr, io.write.valid)
+ val writeValid = RegNext(io.write.valid, false.B)
+ val writeBits = RegEnable(io.write.bits, io.write.valid)
+ val writeGeneration = RegEnable(generation, io.write.valid)
+ val lastValid = RegInit(false.B)
+ val lastAddr = Reg(UInt(io.write.bits.addr.getWidth.W))
+ val lastData = Reg(UInt(128.W))
+ val lastGeneration = Reg(UInt(generation.getWidth.W))
+ val memoryOld = Mux(validRows(writeBits.addr), readData, 0.U)
+ val bypass = lastValid && lastGeneration === writeGeneration && lastAddr === writeBits.addr
+ val oldRow = Mux(bypass, lastData, memoryOld)
+ val oldBytes = oldRow.asTypeOf(Vec(16, UInt(8.W)))
+ val writeBytes = writeBits.data.asTypeOf(Vec(16, UInt(8.W)))
+ val newBytes = VecInit((0 until 16).map(i => Mux(writeBits.mask(i), writeBytes(i), oldBytes(i))))
+ val newRow = newBytes.asUInt
+ val nextHash = statusHash - rowHash(writeBits.addr, oldRow) + rowHash(writeBits.addr, newRow)
+ val commit = writeValid && writeGeneration === generation && !io.bind
+
+ io.statusHash := statusHash
+
+ when(io.bind) {
+ generation := generation + 1.U
+ statusHash := 0.U
+ lastValid := false.B
+ validRows.foreach(_ := false.B)
+ }.elsewhen(commit) {
+ shadow.write(writeBits.addr, newRow)
+ validRows(writeBits.addr) := true.B
+ statusHash := nextHash
+ lastValid := true.B
+ lastAddr := writeBits.addr
+ lastData := newRow
+ lastGeneration := writeGeneration
+ }
+}
diff --git a/arch/src/main/scala/sims/p2e/TargetConfigs.scala b/arch/src/main/scala/sims/p2e/TargetConfigs.scala
index c3adf051..89aca308 100644
--- a/arch/src/main/scala/sims/p2e/TargetConfigs.scala
+++ b/arch/src/main/scala/sims/p2e/TargetConfigs.scala
@@ -3,6 +3,7 @@ package sims.p2e
import chisel3._
import _root_.circt.stage.ChiselStage
import org.chipsalliance.cde.config.Config
+import framework.top.configs.{SimParam, WithSimParam}
import freechips.rocketchip.devices.tilelink.{BootROMLocated, BootROMParams}
import freechips.rocketchip.subsystem.{InSubsystem, WithCustomMemPort}
import sims.scu.WithSCU
@@ -49,7 +50,8 @@ class WithP2EDDR4MemPort
// =============================================================================
class P2EBaseConfig(maxHarts: Int = 64)
extends Config(
- new WithP2EHarness ++
+ new WithSimParam(SimParam()) ++
+ new WithP2EHarness ++
new WithSCU(maxHarts = maxHarts) ++
new WithP2EDDR4MemPort ++
new WithP2EBootROM
@@ -95,7 +97,7 @@ object Elaborate extends App {
val configClassName = args(0)
println(s"Elaborating P2EHarness with config: $configClassName")
- val config: Config =
+ val baseConfig: Config =
try {
val configClass = Class.forName(configClassName)
configClass.getDeclaredConstructor().newInstance().asInstanceOf[Config]
@@ -111,6 +113,11 @@ object Elaborate extends App {
val rawFirtoolOpts = args.drop(1)
+ val config: Config =
+ if (rawFirtoolOpts.contains("--difftest"))
+ new Config(new WithSimParam(SimParam(diffTest = true)).orElse(baseConfig))
+ else baseConfig
+
val outDir = rawFirtoolOpts.collectFirst {
case opt if opt.startsWith("-o=") => opt.stripPrefix("-o=")
}.getOrElse {
@@ -118,7 +125,7 @@ object Elaborate extends App {
}
val firtoolOpts = rawFirtoolOpts.filterNot { opt =>
- opt == "--split-verilog" || opt.startsWith("-o=")
+ opt == "--split-verilog" || opt == "--difftest" || opt.startsWith("-o=")
}
ChiselStage.emitSystemVerilogFile(
diff --git a/arch/src/main/scala/sims/verilator/BBSimHarness.scala b/arch/src/main/scala/sims/verilator/BBSimHarness.scala
index 2d64e866..de65b44d 100644
--- a/arch/src/main/scala/sims/verilator/BBSimHarness.scala
+++ b/arch/src/main/scala/sims/verilator/BBSimHarness.scala
@@ -6,6 +6,7 @@ import org.chipsalliance.cde.config.{Config, Parameters}
import chipyard.harness.{HarnessBinder, HasHarnessInstantiators}
import chipyard.iobinders.AXI4MemPort
+import framework.top.configs.{SimParam, WithSimParam}
import sims.scu.WithSCU
class WithBBSimMem
@@ -36,7 +37,8 @@ class WithBBSimMem
// =============================================================================
class BBSimConfig(maxHarts: Int = 64)
extends Config(
- new WithSCU(maxHarts = maxHarts) ++
+ new WithSimParam(SimParam()) ++
+ new WithSCU(maxHarts = maxHarts) ++
new WithBBSimMem ++
new chipyard.config.WithUniformBusFrequencies(1000.0) ++
new chipyard.harness.WithTieOffInterrupts ++
diff --git a/arch/src/main/scala/sims/verilator/TargetConfig.scala b/arch/src/main/scala/sims/verilator/TargetConfig.scala
index 61010e64..dc84f98a 100644
--- a/arch/src/main/scala/sims/verilator/TargetConfig.scala
+++ b/arch/src/main/scala/sims/verilator/TargetConfig.scala
@@ -5,6 +5,7 @@ import _root_.circt.stage.ChiselStage
import org.chipsalliance.cde.config.Config
import freechips.rocketchip.devices.tilelink.{BootROMLocated, BootROMParams}
import freechips.rocketchip.subsystem.InSubsystem
+import framework.top.configs.{SimParam, WithSimParam}
class WithCustomBootROM
extends Config((site, here, up) => {
@@ -132,7 +133,7 @@ object Elaborate extends App {
val configClassName = args(0)
println(s"Elaborating BBSimHarness with config: $configClassName")
- val config: Config =
+ val baseConfig: Config =
try {
val configClass = Class.forName(configClassName)
configClass.getDeclaredConstructor().newInstance().asInstanceOf[Config]
@@ -148,6 +149,11 @@ object Elaborate extends App {
val rawFirtoolOpts = args.drop(1)
+ val config: Config =
+ if (rawFirtoolOpts.contains("--difftest"))
+ new Config(new WithSimParam(SimParam(diffTest = true)).orElse(baseConfig))
+ else baseConfig
+
val outDir = rawFirtoolOpts.collectFirst {
case opt if opt.startsWith("-o=") => opt.stripPrefix("-o=")
}.getOrElse {
@@ -155,7 +161,7 @@ object Elaborate extends App {
}
val firtoolOpts = rawFirtoolOpts.filterNot { opt =>
- opt == "--split-verilog" || opt.startsWith("-o=")
+ opt == "--split-verilog" || opt == "--difftest" || opt.startsWith("-o=")
}
ChiselStage.emitSystemVerilogFile(
diff --git a/bb-tests/workloads/lib/bbhw/isa/33_mvin.c b/bb-tests/workloads/lib/bbhw/isa/33_mvin.c
index 1d366b5e..feb39b91 100644
--- a/bb-tests/workloads/lib/bbhw/isa/33_mvin.c
+++ b/bb-tests/workloads/lib/bbhw/isa/33_mvin.c
@@ -10,7 +10,7 @@
do { \
bb_dma_cache_flush(); \
rushb_mvin(BUCKYBALL_RUSHB_CORE, \
- (uint64_t)(BB_BANK0(bank_id) | BB_ITER(depth)), \
+ (uint64_t)(BB_BANK2(bank_id) | BB_ITER(depth)), \
(uint64_t)(FIELD(mem_addr, 0, 38) | FIELD(stride, 39, 57)), \
(const void *)(uintptr_t)(mem_addr)); \
} while (0)
@@ -19,7 +19,7 @@
do { \
bb_dma_cache_flush(); \
BUCKYBALL_INSTRUCTION_R_R( \
- (BB_BANK0(bank_id) | BB_ITER(depth)), \
+ (BB_BANK2(bank_id) | BB_ITER(depth)), \
(FIELD(mem_addr, 0, 38) | FIELD(stride, 39, 57)), BB_MVIN_FUNC7); \
} while (0)
#endif
diff --git a/bb-tests/workloads/lib/bbhw/isa/34_mvin_2d.c b/bb-tests/workloads/lib/bbhw/isa/34_mvin_2d.c
index 7728e34f..ae62a65d 100644
--- a/bb-tests/workloads/lib/bbhw/isa/34_mvin_2d.c
+++ b/bb-tests/workloads/lib/bbhw/isa/34_mvin_2d.c
@@ -5,7 +5,7 @@
#define BB_MVIN_2D_FUNC7 34
-// rs1: bank id and tile height.
+// rs1: write bank in BANK2 and tile height.
// rs2: [31:0] address, [38:32] physical pixel bytes / 8,
// [48:39] source width, [54:49] destination row base,
// [57:55] tile width - 1, [61:58] valid bytes (0 encodes 16).
@@ -14,7 +14,7 @@
do { \
bb_dma_cache_flush(); \
BUCKYBALL_INSTRUCTION_R_R( \
- (BB_BANK0(bank_id) | BB_ITER(height)), \
+ (BB_BANK2(bank_id) | BB_ITER(height)), \
(FIELD(mem_addr, 0, 31) | FIELD((pixel_bytes) / 8, 32, 38) | \
FIELD(source_width, 39, 48) | FIELD(dst_base, 49, 54) | \
FIELD((tile_width) - 1, 55, 57) | \
diff --git a/bbdev b/bbdev
index 7dfc7dad..2ffd614d 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit 7dfc7dadf98c128fd854c11d4d402e7f489ad178
+Subproject commit 2ffd614db61ecbc66aeddbf8738e8afe2bdecbd5
diff --git a/bebop b/bebop
index de876a89..474fca00 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit de876a89bfe4c1ad29240b59e1ab26b8220948b7
+Subproject commit 474fca006765121b2c271be1da8ebfa53ed3fcca
diff --git a/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.cpp b/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.cpp
index a9f23ecb..8a56ca2f 100644
--- a/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.cpp
+++ b/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.cpp
@@ -121,6 +121,12 @@ Value packRs1BankIter(OpBuilder &b, Location loc, Value bankId, Value depth) {
return packRs1BanksIter(b, loc, bankId, z, z, depth);
}
+Value packRs1WriteBankIter(OpBuilder &b, Location loc, Value bankId,
+ Value depth) {
+ Value z = cstI64(b, loc, 0);
+ return packRs1BanksIter(b, loc, z, z, bankId, depth);
+}
+
Value packRs2MemStride(OpBuilder &b, Location loc, Value memAddr,
Value stride) {
Value mem =
@@ -278,8 +284,8 @@ struct BuckyballMvinLowering : public ConvertOpToLLVMPattern {
MemrefAddress memref = extractMemrefAddress(rewriter, loc, op.getInput());
if (!rushB)
emitDmaCacheFlush(rewriter, loc);
- Value rs1 =
- packRs1BankIter(rewriter, loc, adaptor.getAddr(), adaptor.getDepth());
+ Value rs1 = packRs1WriteBankIter(rewriter, loc, adaptor.getAddr(),
+ adaptor.getDepth());
Value rs2 =
packRs2MemStride(rewriter, loc, memref.address, adaptor.getStride());
if (rushB) {
@@ -306,8 +312,8 @@ struct BuckyballMvin2dLowering : public ConvertOpToLLVMPattern {
Location loc = op.getLoc();
MemrefAddress memref = extractMemrefAddress(rewriter, loc, op.getInput());
emitDmaCacheFlush(rewriter, loc);
- Value rs1 =
- packRs1BankIter(rewriter, loc, adaptor.getAddr(), adaptor.getHeight());
+ Value rs1 = packRs1WriteBankIter(rewriter, loc, adaptor.getAddr(),
+ adaptor.getHeight());
Value address = rewriter.create(
loc, memref.address, cstI64(rewriter, loc, 0xffff'ffffULL));
Value pixel = rewriter.create(loc, adaptor.getPixelBytes(),
diff --git a/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.h b/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.h
index 06302d17..4b05c825 100644
--- a/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.h
+++ b/compiler/src/Dialect/Buckyball/Transforms/LegalizeForLLVMExportBase.h
@@ -40,6 +40,8 @@ mlir::Value packRs1BanksIter(mlir::OpBuilder &b, mlir::Location loc,
mlir::Value wBank, mlir::Value iter);
mlir::Value packRs1BankIter(mlir::OpBuilder &b, mlir::Location loc,
mlir::Value bankId, mlir::Value depth);
+mlir::Value packRs1WriteBankIter(mlir::OpBuilder &b, mlir::Location loc,
+ mlir::Value bankId, mlir::Value depth);
mlir::Value packRs2MemStride(mlir::OpBuilder &b, mlir::Location loc,
mlir::Value memAddr, mlir::Value stride);
void emitMset(mlir::OpBuilder &b, mlir::Location loc, uint64_t bankId,
diff --git a/examples/balls/gemmini/arch/src/main/scala/LoopCmdEncoder.scala b/examples/balls/gemmini/arch/src/main/scala/LoopCmdEncoder.scala
index 526c52d7..9433a1b3 100644
--- a/examples/balls/gemmini/arch/src/main/scala/LoopCmdEncoder.scala
+++ b/examples/balls/gemmini/arch/src/main/scala/LoopCmdEncoder.scala
@@ -90,7 +90,7 @@ class LoopCmdEncoder(val b: GlobalConfig) extends Module {
is(LoopSubCmdType.MVIN) {
slot.cmd.domain_id := DomainId.MEM
slot.cmd.cmd.funct := 0x21.U // MVIN (enable=010, opcode=1)
- slot.cmd.cmd.rs1Data := lsub.bits.bank_id | (lsub.bits.iter << 30)
+ slot.cmd.cmd.rs1Data := (lsub.bits.bank_id << 20) | (lsub.bits.iter << 30)
slot.cmd.cmd.rs2Data := lsub.bits.dram_addr | (lsub.bits.stride << 39)
slot.cmd.bankAccess.wr_bank_valid := true.B
slot.cmd.bankAccess.wr_bank_id := lsub.bits.bank_id
diff --git a/examples/balls/gemmini/emu/src/80_gemmini_loop_ws.rs b/examples/balls/gemmini/emu/src/80_gemmini_loop_ws.rs
index b2fcb873..6b82fa3a 100644
--- a/examples/balls/gemmini/emu/src/80_gemmini_loop_ws.rs
+++ b/examples/balls/gemmini/emu/src/80_gemmini_loop_ws.rs
@@ -4,7 +4,7 @@ use super::super::bank::{bank_row_bytes, MATRIX_SIZE};
use super::gemmini_state::gemini;
use super::instruction::ExecContext;
use super::loop_micro_ops::{
- alloc, checked_stride, compute, free_after_digest, mvin, mvout, preload,
+ alloc, checked_stride, compute, free_after_hash, mvin, mvout, preload,
};
// Shared implementation
@@ -125,9 +125,9 @@ fn exec_loop_impl(xs2: u64, ctx: &mut ExecContext) -> u64 {
}
}
- free_after_digest(ctx, bank_a);
- free_after_digest(ctx, bank_b);
- free_after_digest(ctx, bank_c);
+ free_after_hash(ctx, bank_a);
+ free_after_hash(ctx, bank_b);
+ free_after_hash(ctx, bank_c);
0
}
diff --git a/examples/balls/gemmini/emu/src/96_gemmini_loop_conv_ws.rs b/examples/balls/gemmini/emu/src/96_gemmini_loop_conv_ws.rs
index fb3cb410..36d72f72 100644
--- a/examples/balls/gemmini/emu/src/96_gemmini_loop_conv_ws.rs
+++ b/examples/balls/gemmini/emu/src/96_gemmini_loop_conv_ws.rs
@@ -4,7 +4,7 @@ use super::super::bank::{bank_row_bytes, MATRIX_SIZE};
use super::gemmini_state::gemini;
use super::instruction::ExecContext;
use super::loop_micro_ops::{
- alloc, checked_stride, compute, free_after_digest, mvin, mvout, preload,
+ alloc, checked_stride, compute, free_after_hash, mvin, mvout, preload,
};
// Shared implementation
@@ -266,9 +266,9 @@ fn exec_loop_impl(xs2: u64, ctx: &mut ExecContext) -> u64 {
}
}
- free_after_digest(ctx, bank_input);
- free_after_digest(ctx, bank_weight);
- free_after_digest(ctx, bank_output);
+ free_after_hash(ctx, bank_input);
+ free_after_hash(ctx, bank_weight);
+ free_after_hash(ctx, bank_output);
0
}
diff --git a/examples/balls/gemmini/emu/src/loop_micro_ops.rs b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
index e2f09a2f..eac3f2a0 100644
--- a/examples/balls/gemmini/emu/src/loop_micro_ops.rs
+++ b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
@@ -90,6 +90,6 @@ pub fn compute(
execute(funct, banks(op1, op2, output, iter), xs2, ctx);
}
-pub fn free_after_digest(ctx: &mut ExecContext, bank: u64) {
+pub fn free_after_hash(ctx: &mut ExecContext, bank: u64) {
ctx.defer_bank_free(bank);
}
diff --git a/examples/balls/im2col/arch/src/main/scala/Im2col.scala b/examples/balls/im2col/arch/src/main/scala/Im2col.scala
index 40a55c45..567da6f3 100644
--- a/examples/balls/im2col/arch/src/main/scala/Im2col.scala
+++ b/examples/balls/im2col/arch/src/main/scala/Im2col.scala
@@ -218,4 +218,5 @@ class Im2col(val b: GlobalConfig) extends Module {
win.io.next := true.B
localWindow := localWindow + 1.U
}
+
}
diff --git a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
index e873b216..7e756507 100644
--- a/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
+++ b/examples/chips/pebble/regression/batch/p2e/workloads-pk.toml
@@ -1,4 +1,4 @@
[workloads]
tests = [
- "fw_payload-pebble-pk.hex",
+ "fw_payload-v1-t1-pebble-pk.hex",
]
From bb8f7e70cde620e918d5805a8d74bdd26f0f9b4d Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 02:19:40 +0800
Subject: [PATCH 29/36] update: bump submodule commits for bbdev and bebop to
the latest version
---
.github/workflows/regression.yml | 2 +-
bbdev | 2 +-
bebop | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index bf6239d1..a630d773 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -235,7 +235,7 @@ jobs:
rm -rf "${build_dir}"
done
nix develop -c bbdev bebop-p2e --verilog '--chip ${{ matrix.chip }} --diff'
- nix develop -c bbdev bebop-p2e --buildbitstream '--chip ${{ matrix.chip }}'
+ nix develop -c bbdev bebop-p2e --buildbitstream '--chip ${{ matrix.chip }} --diff'
bits=("${root}"/bebop/build/"${{ matrix.chip }}"-*/fpgaCompDir/bitstream.bit(N))
if (( ${#bits} != 1 )); then
echo "ERROR: expected exactly 1 bitstream.bit for ${{ matrix.chip }}, got ${#bits}" >&2
diff --git a/bbdev b/bbdev
index 2ffd614d..3fc00c06 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit 2ffd614db61ecbc66aeddbf8738e8afe2bdecbd5
+Subproject commit 3fc00c06fc6729d7ae983dddf79da5b58768821c
diff --git a/bebop b/bebop
index 474fca00..f3550acb 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit 474fca006765121b2c271be1da8ebfa53ed3fcca
+Subproject commit f3550acb282d49ab97e724e89c98f074f478eaa2
From ea6f387ddfea577d014b29cc6b2b8cf20c0471c9 Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 03:11:37 +0800
Subject: [PATCH 30/36] refactor: adjust xLen references in Frontend, Boot, and
various decoder files to use tile configuration
---
.../scala/framework/frontend/Frontend.scala | 6 +-
.../scala/framework/frontend/boot/Boot.scala | 10 +--
.../frontend/decoder/GobalDecoder.scala | 6 +-
.../frontend/globalrs/GlobalROB.scala | 2 +-
.../frontend/globalrs/GlobalScheduler.scala | 4 +-
.../sequencer/decoder/DomainDecoder.scala | 2 +-
.../scala/framework/memdomain/MemDomain.scala | 2 +-
.../memdomain/backend/MemBackendTypes.scala | 2 +-
.../memdomain/backend/accpipe/AccPipe.scala | 4 +-
.../backend/banks/btrace/BTraceTypes.scala | 2 +-
.../privatepath/PrivateMemBackend.scala | 6 +-
.../memdomain/backend/shared/SharedMem.scala | 4 +-
.../backend/shared/SharedMemBackend.scala | 4 +-
.../memdomain/frontend/MemFrontend.scala | 2 +-
.../memdomain/frontend/mem/MemConfiger.scala | 4 +-
.../frontend/mem/dma/StreamReader.scala | 2 +-
.../frontend/mem/dma/StreamWriter.scala | 2 +-
.../memdomain/frontend/mem/tlb/BBTLBIO.scala | 18 ++--
.../memdomain/frontend/mem/tlb/TLB.scala | 10 +--
.../frontend/mem/tlb/TLBCluster.scala | 12 +--
.../memdomain/midend/MemMidend.scala | 2 +-
.../system/configloader/ChipLoader.scala | 54 +++++------
.../system/configloader/Topology.scala | 10 ++-
.../accelerator/BuckyballAccelerator.scala | 6 +-
...BoomCoreParam.scala => BoomCpuParam.scala} | 12 +--
...etCoreParam.scala => RocketCpuParam.scala} | 24 +++--
.../scala/framework/system/tile/BBTile.scala | 2 +-
.../scala/framework/system/tile/Configs.scala | 89 ++++++++++---------
.../framework/system/tile/WithBoomTile.scala | 12 +--
.../system/tile/WithBuckyballTiles.scala | 20 +++--
.../configs/TileParam.scala} | 10 +--
.../scala/framework/top/GlobalConfig.scala | 6 +-
bbdev | 2 +-
bebop | 2 +-
.../designs/tiles/16core-incoherent.toml | 8 ++
.../goban/configs/designs/tiles/16core.toml | 8 ++
.../goban/configs/designs/tiles/2core.toml | 8 ++
.../goban/configs/designs/tiles/32core.toml | 8 ++
.../designs/tiles/4core-private-1bb.toml | 8 ++
.../goban/configs/designs/tiles/64core.toml | 8 ++
.../designs/tiles/8core-incoherent.toml | 8 ++
.../goban/configs/designs/tiles/8core.toml | 8 ++
.../goban/configs/designs/tiles/default.toml | 8 ++
.../configs/designs/tiles/32core.toml | 8 ++
.../configs/designs/tiles/48core.toml | 8 ++
.../pebble/configs/designs/tiles/default.toml | 8 ++
.../poly/configs/designs/tiles/default.toml | 8 ++
.../toy/configs/designs/tiles/16core.toml | 8 ++
.../toy/configs/designs/tiles/4core.toml | 8 ++
.../toy/configs/designs/tiles/8core.toml | 8 ++
.../toy/configs/designs/tiles/default.toml | 8 ++
.../cpu/boom/{boomCore.toml => default.toml} | 0
examples/cores/boom/configs/cpu/default.toml | 2 +-
.../cores/decode/configs/cpu/default.toml | 8 +-
examples/cores/goban/configs/cpu/default.toml | 8 +-
.../cores/pebble/configs/cpu/default.toml | 8 +-
.../rocket/{rocketCore.toml => default.toml} | 2 -
.../cores/prefill/configs/cpu/default.toml | 8 +-
.../cores/rocket/configs/cpu/default.toml | 2 +-
.../rocket/{rocketCore.toml => default.toml} | 2 -
examples/cores/toy/configs/cpu/default.toml | 8 +-
61 files changed, 324 insertions(+), 215 deletions(-)
rename arch/src/main/scala/framework/system/core/boom/configs/{BoomCoreParam.scala => BoomCpuParam.scala} (76%)
rename arch/src/main/scala/framework/system/core/rocket/configs/{RocketCoreParam.scala => RocketCpuParam.scala} (82%)
rename arch/src/main/scala/framework/system/{cpu/configs/CpuParam.scala => tile/configs/TileParam.scala} (68%)
rename examples/cores/boom/configs/cpu/boom/{boomCore.toml => default.toml} (100%)
rename examples/cores/pebble/configs/cpu/rocket/{rocketCore.toml => default.toml} (93%)
rename examples/cores/rocket/configs/cpu/rocket/{rocketCore.toml => default.toml} (93%)
diff --git a/arch/src/main/scala/framework/frontend/Frontend.scala b/arch/src/main/scala/framework/frontend/Frontend.scala
index bcc0915f..2a9156a4 100644
--- a/arch/src/main/scala/framework/frontend/Frontend.scala
+++ b/arch/src/main/scala/framework/frontend/Frontend.scala
@@ -23,11 +23,11 @@ class Frontend(val b: GlobalConfig) extends Module {
@public
val io = IO(new Bundle {
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
// RoCC command input
val cmd = Flipped(Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.cpu.xLen)
+ val cmd = new RoCCCommandBB(b.tile.xLen)
}))
// Issue to domains
@@ -51,7 +51,7 @@ class Frontend(val b: GlobalConfig) extends Module {
}
// RoCC response
- val resp = Decoupled(new RoCCResponseBB(b.cpu.xLen))
+ val resp = Decoupled(new RoCCResponseBB(b.tile.xLen))
val busy = Output(Bool())
// Propagates the Global ROB retirement pulse to the host bridge.
val retired = Output(Bool())
diff --git a/arch/src/main/scala/framework/frontend/boot/Boot.scala b/arch/src/main/scala/framework/frontend/boot/Boot.scala
index 5ddf2957..a40aab6a 100644
--- a/arch/src/main/scala/framework/frontend/boot/Boot.scala
+++ b/arch/src/main/scala/framework/frontend/boot/Boot.scala
@@ -15,7 +15,7 @@ class BootRom(val b: GlobalConfig) extends Module {
val io = IO(new Bundle {
val cmd = Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.cpu.xLen)
+ val cmd = new RoCCCommandBB(b.tile.xLen)
})
val schedulerIdle = Input(Bool())
@@ -31,8 +31,8 @@ class BootRom(val b: GlobalConfig) extends Module {
Seq.empty[BuckyballCommand]
private val bootFuncts = VecInit(bootRecords.map(r => r.funct.U(7.W)))
- val bootRs1Data = VecInit(bootRecords.map(r => r.rs1.U(b.cpu.xLen.W)))
- val bootRs2Data = VecInit(bootRecords.map(r => r.rs2.U(b.cpu.xLen.W)))
+ val bootRs1Data = VecInit(bootRecords.map(r => r.rs1.U(b.tile.xLen.W)))
+ val bootRs2Data = VecInit(bootRecords.map(r => r.rs2.U(b.tile.xLen.W)))
private val bootPcWidth = math.max(1, log2Ceil(bootRecords.length + 1))
private val active = RegInit(true.B)
@@ -42,8 +42,8 @@ class BootRom(val b: GlobalConfig) extends Module {
private val atEnd = pc === bootRecords.length.U(bootPcWidth.W)
- val current = Wire(new RoCCCommandBB(b.cpu.xLen))
- current := 0.U.asTypeOf(new RoCCCommandBB(b.cpu.xLen))
+ val current = Wire(new RoCCCommandBB(b.tile.xLen))
+ current := 0.U.asTypeOf(new RoCCCommandBB(b.tile.xLen))
current.funct := Mux(atEnd, 0.U, bootFuncts(pc))
current.funct3 := BuckyballCommand.Custom3Funct3.U
current.opcode := BuckyballCommand.Custom3Opcode.U
diff --git a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
index fa5d0f79..7bf9a41f 100644
--- a/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
+++ b/arch/src/main/scala/framework/frontend/decoder/GobalDecoder.scala
@@ -16,13 +16,13 @@ import framework.frontend.scoreboard.BankAccessInfo
import framework.system.core.rocket.RoCCCommandBB
class BuckyballRawCmd(val b: GlobalConfig) extends Bundle {
- val cmd = new RoCCCommandBB(b.cpu.xLen)
+ val cmd = new RoCCCommandBB(b.tile.xLen)
}
class PostGDCmd(val b: GlobalConfig) extends Bundle {
val domain_id = UInt(4.W)
val ball_bid = UInt(5.W)
- val cmd = new RoCCCommandBB(b.cpu.xLen)
+ val cmd = new RoCCCommandBB(b.tile.xLen)
val bankAccess = new BankAccessInfo(b.frontend.bank_id_len)
val op1_col = UInt(b.memDomain.groupCountWidth.W)
val op2_col = UInt(b.memDomain.groupCountWidth.W)
@@ -40,7 +40,7 @@ class GlobalDecoder(val b: GlobalConfig) extends Module {
val io = IO(new Bundle {
val id_i = Flipped(Decoupled(new Bundle {
- val cmd = new RoCCCommandBB(b.cpu.xLen)
+ val cmd = new RoCCCommandBB(b.tile.xLen)
}))
val id_o = Decoupled(new PostGDCmd(b))
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index 380dddce..21bb4c16 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -27,7 +27,7 @@ class GlobalROB(val b: GlobalConfig) extends Module {
@public
val io = IO(new Bundle {
- val hart_id = Input(UInt(b.cpu.xLen.W))
+ val hart_id = Input(UInt(b.tile.xLen.W))
val alloc = Flipped(new DecoupledIO(new PostGDCmd(b)))
val issue = new DecoupledIO(new GlobalRobEntry(b))
val complete = Flipped(new DecoupledIO(UInt(idWidth.W)))
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
index 8b2ae85f..43bfab49 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalScheduler.scala
@@ -37,7 +37,7 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
@public
val io = IO(new Bundle {
- val hart_id = Input(UInt(b.cpu.xLen.W))
+ val hart_id = Input(UInt(b.tile.xLen.W))
val decode_cmd_i = Flipped(new DecoupledIO(new PostGDCmd(b)))
val ball_issue_o = Decoupled(new GlobalSchedIssue(b))
val mem_issue_o = Decoupled(new GlobalSchedIssue(b))
@@ -56,7 +56,7 @@ class GlobalScheduler(val b: GlobalConfig) extends Module {
}
val scheduler_rocc_o = new Bundle {
- val resp = new DecoupledIO(new RoCCResponseBB(b.cpu.xLen))
+ val resp = new DecoupledIO(new RoCCResponseBB(b.tile.xLen))
val busy = Output(Bool())
}
diff --git a/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala b/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
index 39603da0..533c72b3 100644
--- a/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
+++ b/arch/src/main/scala/framework/gpdomain/sequencer/decoder/DomainDecoder.scala
@@ -30,7 +30,7 @@ object DomainDecoderParameter {
* Domain Decoder IO
*/
class DomainDecoderIO(b: GlobalConfig) extends Bundle {
- val inst_i = Input(new RoCCCommandBB(b.cpu.xLen))
+ val inst_i = Input(new RoCCCommandBB(b.tile.xLen))
val decoded_o = Decoder.bundle(DomainDecoderParameter.decoderParam).cloneType
}
diff --git a/arch/src/main/scala/framework/memdomain/MemDomain.scala b/arch/src/main/scala/framework/memdomain/MemDomain.scala
index 5c492424..ed8e9007 100644
--- a/arch/src/main/scala/framework/memdomain/MemDomain.scala
+++ b/arch/src/main/scala/framework/memdomain/MemDomain.scala
@@ -51,7 +51,7 @@ class MemDomain(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val tlbExp = Vec(1, new BBTLBExceptionIO)
val tl_reader = new TLBundle(edge.bundle)
val tl_writer = new TLBundle(edge.bundle)
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
// Shared memory path
val shared_mem_req = Vec(SharedMemLayout.channelPerHart(b), new MemRequestIO(b))
diff --git a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
index 8bd8859d..6d1fea61 100644
--- a/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/MemBackendTypes.scala
@@ -11,7 +11,7 @@ class MemRequestIO(b: GlobalConfig) extends Bundle {
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val is_shared = Output(Bool())
- val hart_id = Output(UInt(b.cpu.xLen.W))
+ val hart_id = Output(UInt(b.tile.xLen.W))
val rob_id = Output(UInt(log2Up(b.frontend.rob_entries).W))
val inst_id = Output(UInt(64.W))
}
diff --git a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
index 1d6204df..0650e792 100644
--- a/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/accpipe/AccPipe.scala
@@ -22,7 +22,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
val busy = Output(Bool())
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
val bank_id = Output(UInt(b.memDomain.vbankIdWidth.W))
- val hart_id = Output(UInt(b.cpu.xLen.W))
+ val hart_id = Output(UInt(b.tile.xLen.W))
})
// Each group has its own physical bank, so no address shifting is needed.
@@ -36,7 +36,7 @@ class AccPipe(val b: GlobalConfig) extends Module {
//Bank_id output
val bank_id_reg = RegInit(0.U(b.memDomain.vbankIdWidth.W))
io.bank_id := bank_id_reg
- val hart_id_reg = RegInit(0.U(b.cpu.xLen.W))
+ val hart_id_reg = RegInit(0.U(b.tile.xLen.W))
io.hart_id := hart_id_reg
val rd_hold = RegInit(false.B)
diff --git a/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
index 040fbd15..f4f7ce09 100644
--- a/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/banks/btrace/BTraceTypes.scala
@@ -5,7 +5,7 @@ import framework.top.GlobalConfig
class PhysicalBankHash(val b: GlobalConfig) extends Bundle {
val valid = Bool()
- val hartId = UInt(b.cpu.xLen.W)
+ val hartId = UInt(b.tile.xLen.W)
val vbankId = UInt(b.memDomain.vbankIdWidth.W)
val pbankId = UInt(32.W)
val groupId = UInt(32.W)
diff --git a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
index e43815f3..c80b4600 100644
--- a/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/privatepath/PrivateMemBackend.scala
@@ -61,7 +61,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
// -----------------------------------------------------------------------------
class MappingTableEntry extends Bundle {
val valid = Bool()
- val hart_id = UInt(b.cpu.xLen.W)
+ val hart_id = UInt(b.tile.xLen.W)
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
val group_id = UInt(b.memDomain.groupIdWidth.W)
@@ -251,7 +251,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val channelReqAddr = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(log2Ceil(b.memDomain.bankEntries).W)))
val channelReqData = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.bankWidth.W)))
val channelReqMask = Seq.fill(b.memDomain.bankChannel)(Wire(Vec(b.memDomain.bankMaskLen, Bool())))
- val channelHartId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.cpu.xLen.W)))
+ val channelHartId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.tile.xLen.W)))
val channelInstId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(64.W)))
val channelVbankId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.vbankIdWidth.W)))
val channelGroupId = Seq.fill(b.memDomain.bankChannel)(Wire(UInt(b.memDomain.groupIdWidth.W)))
@@ -362,7 +362,7 @@ class PrivateMemBackend(val b: GlobalConfig) extends Module {
val selectedReqMask = VecInit((0 until b.memDomain.bankMaskLen).map { k =>
oneHotOr(1, channelReqMask.map(_(k))).asBool
})
- val selectedHartId = oneHotOr(b.cpu.xLen, channelHartId)
+ val selectedHartId = oneHotOr(b.tile.xLen, channelHartId)
val selectedInstId = oneHotOr(64, channelInstId)
val selectedVbankId = oneHotOr(b.memDomain.vbankIdWidth, channelVbankId)
val selectedGroupId = oneHotOr(b.memDomain.groupIdWidth, channelGroupId)
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
index 4647eaf4..1684266c 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
@@ -46,14 +46,14 @@ object SharedMemLayout {
}
class SharedMemReadReq(val b: GlobalConfig) extends Bundle {
- val hartid = UInt(b.cpu.xLen.W)
+ val hartid = UInt(b.tile.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
}
class SharedMemWriteReq(val b: GlobalConfig) extends Bundle {
- val hartid = UInt(b.cpu.xLen.W)
+ val hartid = UInt(b.tile.xLen.W)
val pbank_id = UInt(log2Ceil(SharedMemLayout.totalBank(b)).W)
val group_id = UInt(b.memDomain.groupIdWidth.W)
val addr = UInt(log2Ceil(b.memDomain.bankEntries).W)
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
index 5b7cb859..addf9f01 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMemBackend.scala
@@ -24,7 +24,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
// Query interface for frontend to get group count
val query_valid = Input(Vec(nCores, Bool()))
- val query_hart_id = Input(Vec(nCores, UInt(b.cpu.xLen.W)))
+ val query_hart_id = Input(Vec(nCores, UInt(b.tile.xLen.W)))
val query_vbank_id = Input(Vec(nCores, UInt(b.memDomain.vbankIdWidth.W)))
val query_group_count = Output(Vec(nCores, UInt(b.memDomain.groupCountWidth.W)))
val bank_hashes = if (b.sim.diffTest) Some(Output(Vec(totalBanks, new PhysicalBankHash(b)))) else None
@@ -66,7 +66,7 @@ class SharedMemBackend(val b: GlobalConfig) extends Module {
// -----------------------------------------------------------------------------
class MappingTableEntry extends Bundle {
val valid = Bool()
- val hart_id = UInt(b.cpu.xLen.W)
+ val hart_id = UInt(b.tile.xLen.W)
val vbank_id = UInt(b.memDomain.vbankIdWidth.W)
val is_multi = Bool()
val group_id = UInt(b.memDomain.groupIdWidth.W)
diff --git a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
index 2e86e289..7b13f75a 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/MemFrontend.scala
@@ -60,7 +60,7 @@ class MemFrontend(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val query_is_shared = Output(Bool())
val query_group_count = Input(UInt(b.memDomain.groupCountWidth.W))
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
// Busy signal
val busy = Output(Bool())
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
index c4b64e62..e38cf490 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/MemConfiger.scala
@@ -14,7 +14,7 @@ class MemConfigerIO(val b: GlobalConfig) extends Bundle {
val is_multi = Output(Bool())
val alloc = Output(Bool())
val group_id = Output(UInt(b.memDomain.groupIdWidth.W))
- val hart_id = Output(UInt(b.cpu.xLen.W))
+ val hart_id = Output(UInt(b.tile.xLen.W))
}
@instantiable
@@ -26,7 +26,7 @@ class MemConfiger(val b: GlobalConfig) extends Module {
val cmdReq = Flipped(Decoupled(new MemRsIssue(b)))
val cmdResp = Decoupled(new MemRsComplete(b))
val config = Decoupled(new MemConfigerIO(b))
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
val bankWrite = Flipped(new BankWrite(b))
})
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
index cf1890b6..ddd4f6f4 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamReader.scala
@@ -89,7 +89,7 @@ class StreamReader(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
val bytesLeft = reqReg.len - bytesRequested
val groupsLeftInRow = reqReg.groups - groupIdx
val rowBytesLeft = groupsLeftInRow << lgBeat
- val pageBytesLeft = (1.U << b.cpu.pgIdxBits) - readVaddr(b.cpu.pgIdxBits - 1, 0)
+ val pageBytesLeft = (1.U << b.tile.pgIdxBits) - readVaddr(b.tile.pgIdxBits - 1, 0)
val maxBurstBytes = Seq(bytesLeft, rowBytesLeft, pageBytesLeft, burstMaxBytes.U).reduce((a, c) => Mux(a < c, a, c))
val burstCandidates = Iterator.iterate(beatBytes)(_ * 2).takeWhile(_ <= burstMaxBytes).toSeq
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
index 6d7ad51d..fe42f5b9 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/dma/StreamWriter.scala
@@ -23,7 +23,7 @@ class BBWriteResponse extends Bundle {
@instantiable
class StreamWriter(val b: GlobalConfig)(edge: TLEdgeOut) extends Module {
- val vaddrBits = b.cpu.vaddrBits
+ val vaddrBits = b.tile.vaddrBits
val beatBits = b.memDomain.dma_buswidth
val dataWidth = b.memDomain.dma_buswidth
val beatBytes = beatBits / 8
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
index 824eb600..719de688 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/BBTLBIO.scala
@@ -146,12 +146,12 @@ class BBPMP(val paddrBits: Int) extends Bundle {
// PTW IO
class BBTLBPTWIO(val b: GlobalConfig) extends Bundle {
- val vaddrBits = b.cpu.vaddrBits
- val paddrBits = b.cpu.paddrBits
- val pgIdxBits = b.cpu.pgIdxBits
- val xLen = b.cpu.xLen
- val pgLevels = b.cpu.pgLevels
- val nPMPs = b.cpu.nPMPs
+ val vaddrBits = b.tile.vaddrBits
+ val paddrBits = b.tile.paddrBits
+ val pgIdxBits = b.tile.pgIdxBits
+ val xLen = b.tile.xLen
+ val pgLevels = b.tile.pgLevels
+ val nPMPs = b.tile.nPMPs
val req = Decoupled(Valid(new BBTLBPTWReq(vaddrBits, pgIdxBits)))
val resp = Flipped(Valid(new BBTLBPTWResp(vaddrBits, paddrBits, pgIdxBits, pgLevels)))
@@ -167,7 +167,7 @@ class BBTLBPTWIO(val b: GlobalConfig) extends Bundle {
// TLB Client IO (used in TLBCluster)
class BBTLBIO(val b: GlobalConfig) extends Bundle {
- val lgMaxSize = log2Ceil(b.cpu.coreDataBytes)
- val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, b.cpu.vaddrBits, b.cpu.xLen)))
- val resp = Decoupled(new BBTLBResp(lgMaxSize, b.cpu.paddrBits, b.cpu.vaddrBits))
+ val lgMaxSize = log2Ceil(b.tile.coreDataBytes)
+ val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, b.tile.vaddrBits, b.tile.xLen)))
+ val resp = Decoupled(new BBTLBResp(lgMaxSize, b.tile.paddrBits, b.tile.vaddrBits))
}
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
index e03a3707..0375587a 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLB.scala
@@ -10,16 +10,16 @@ import framework.top.GlobalConfig
@instantiable
class TLB(val b: GlobalConfig, val lgMaxSize: Int) extends Module {
val entries = b.memDomain.tlb_size
- val vaddrBits = b.cpu.vaddrBits
- val paddrBits = b.cpu.paddrBits
- val pgIdxBits = b.cpu.pgIdxBits
+ val vaddrBits = b.tile.vaddrBits
+ val paddrBits = b.tile.paddrBits
+ val pgIdxBits = b.tile.pgIdxBits
val vpnBits = vaddrBits - pgIdxBits
val ppnBits = paddrBits - pgIdxBits
- val pgLevels = b.cpu.pgLevels
+ val pgLevels = b.tile.pgLevels
@public
val io = IO(new Bundle {
- val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, vaddrBits, b.cpu.xLen)))
+ val req = Flipped(Decoupled(new BBTLBReq(lgMaxSize, vaddrBits, b.tile.xLen)))
val resp = Decoupled(new BBTLBResp(lgMaxSize, paddrBits, vaddrBits))
val ptw = new BBTLBPTWIO(b)
val sfence = Flipped(Valid(Bool())) // Simplified flush signal
diff --git a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
index 2731b8c6..5982162a 100644
--- a/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
+++ b/arch/src/main/scala/framework/memdomain/frontend/mem/tlb/TLBCluster.scala
@@ -11,11 +11,11 @@ class BBTLBCluster(val b: GlobalConfig)(implicit val edge: TLEdgeOut) extends Mo
val nClients = 2
val entries = b.memDomain.tlb_size
- val maxSize = b.cpu.coreDataBytes
- val lgMaxSize = log2Ceil(b.cpu.coreDataBytes)
- val vaddrBits = b.cpu.vaddrBits
- val paddrBits = b.cpu.paddrBits
- val pgIdxBits = b.cpu.pgIdxBits
+ val maxSize = b.tile.coreDataBytes
+ val lgMaxSize = log2Ceil(b.tile.coreDataBytes)
+ val vaddrBits = b.tile.vaddrBits
+ val paddrBits = b.tile.paddrBits
+ val pgIdxBits = b.tile.pgIdxBits
@public
val io = IO(new Bundle {
@@ -33,7 +33,7 @@ class BBTLBCluster(val b: GlobalConfig)(implicit val edge: TLEdgeOut) extends Mo
// Connect PTW
io.ptw(0) <> tlb.io.ptw
- val tlbArb = Module(new RRArbiter(new BBTLBReq(lgMaxSize, vaddrBits, b.cpu.xLen), nClients))
+ val tlbArb = Module(new RRArbiter(new BBTLBReq(lgMaxSize, vaddrBits, b.tile.xLen), nClients))
val tlbArbOut = tlbArb.io.out
val tlb_io = tlb.io
diff --git a/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala b/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
index f7bb5374..2b0b10c6 100644
--- a/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
+++ b/arch/src/main/scala/framework/memdomain/midend/MemMidend.scala
@@ -44,7 +44,7 @@ class MemMidend(val b: GlobalConfig) extends Module {
val ballChannelActive = Input(Vec(b.ballDomain.ballNum, Bool()))
val ballChannelReady = Output(Vec(b.ballDomain.ballNum, Bool()))
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
val inst_ids = Input(Vec(b.frontend.rob_entries, UInt(64.W)))
// Output to backend (MemManager)
diff --git a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
index 647b1b2e..b74dbdef 100644
--- a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
+++ b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
@@ -1,15 +1,16 @@
package framework.system.configloader
import buckyball.config.{
- BoomCoreConfig,
+ BoomCpuConfig,
Chip,
CoreInstance,
CpuConfig,
FrontendConfig,
GpDomainConfig,
MemDomainConfig,
- RocketCoreConfig,
+ RocketCpuConfig,
SharedMemConfig,
+ TileParamConfig,
TilePlacement
}
import java.nio.file.{Files, Path, Paths}
@@ -17,10 +18,10 @@ import framework.balldomain.configs.{BallDomainParam, BallISAEntry, BallIdMappin
import framework.frontend.configs.FrontendParam
import framework.gpdomain.configs.GpDomainParam
import framework.memdomain.configs.MemDomainParam
-import framework.system.cpu.configs.CpuParam
-import framework.system.core.boom.configs.{BoomCoreParam, BoomDCacheParam, BoomICacheParam}
+import framework.system.core.boom.configs.{BoomCpuParam, BoomDCacheParam, BoomICacheParam}
import framework.system.core.rocket.configs._
import framework.system.tile.PrivateDCacheParams
+import framework.system.tile.configs.TileParam
import framework.top.GlobalConfig
import scala.jdk.CollectionConverters._
@@ -76,6 +77,7 @@ object ChipLoader {
val indices = tile.getCoreIndicesList.asScala.map(_.toInt).toSeq
val nCores = indices.size
val hasBuckyball = indices.exists(i => cores(i).getBalldomain.getBallNum > 0)
+ val tileParam = parseTileParam(tile.getParam)
val shared = tile.getSharedMem
val virtualBankCount = tile.getVirtualBankCount
@@ -114,13 +116,14 @@ object ChipLoader {
}
val tileCores = indices.map { idx =>
- parseCore(cores(idx), shared, virtualBankCount, nCores, repo)
+ parseCore(cores(idx), tileParam, shared, virtualBankCount, nCores, repo)
}
- TileTopology(tileCores, privateDCache)
+ TileTopology(tileParam, tileCores, privateDCache)
}
private def parseCore(
core: CoreInstance,
+ tile: TileParam,
shared: SharedMemConfig,
virtualBankCount: Int,
nCores: Int,
@@ -130,7 +133,7 @@ object ChipLoader {
val cpu = core.getCpu
val kind = cpu.getKind
kind match {
- case "rocket" => parseRocketCoreSlot(core, shared, virtualBankCount, nCores, repo)
+ case "rocket" => parseRocketCoreSlot(core, tile, shared, virtualBankCount, nCores, repo)
case "boom" =>
if (core.getBalldomain.getBallNum > 0) {
throw new RuntimeException(s"core ${core.getPkg}: kind=boom forbids balldomain")
@@ -138,7 +141,7 @@ object ChipLoader {
if (!cpu.hasBoom) {
throw new RuntimeException(s"core ${core.getPkg}: kind=boom missing cpu.boom")
}
- BoomTileCore(parseBoomCore(cpu.getBoom))
+ BoomTileCore(parseBoomCpu(cpu.getBoom))
case other =>
throw new RuntimeException(s"core ${core.getPkg}: unsupported kind '$other'")
}
@@ -146,6 +149,7 @@ object ChipLoader {
private def parseRocketCoreSlot(
core: CoreInstance,
+ tile: TileParam,
shared: SharedMemConfig,
virtualBankCount: Int,
nCores: Int,
@@ -155,14 +159,14 @@ object ChipLoader {
if (!cpu.hasRocket) {
throw new RuntimeException(s"core ${core.getPkg}: kind=rocket missing cpu.rocket")
}
- val rocket = parseRocketCore(cpu.getRocket)
+ val rocket = parseRocketCpu(cpu.getRocket)
val domain = core.getBalldomain
if (domain.getBallNum == 0) {
return RocketTileCore(rocket, None)
}
require(core.hasFrontend, s"core ${core.getPkg} missing frontend config")
require(core.hasGpDomain, s"core ${core.getPkg} missing gpdomain config")
- require(cpu.getCoreDataBytes > 0, s"core ${core.getPkg} missing cpu interface config")
+ require(tile.coreDataBytes > 0, s"core ${core.getPkg} missing tile config")
val frontend = core.getFrontend
require(
virtualBankCount <= (1 << frontend.getBankIdLen),
@@ -187,7 +191,7 @@ object ChipLoader {
ballDomain = parseBallDomain(core, repo),
frontend = parseFrontend(core.getFrontend),
gpDomain = parseGpDomain(core.getGpDomain),
- cpu = parseCpuParam(cpu, rocket.pgLevels),
+ tile = tile,
memDomain = parseMemDomain(core.getMem, shared, virtualBankCount, nCores)
)
RocketTileCore(rocket, Some(buckyball))
@@ -274,26 +278,24 @@ object ChipLoader {
laneScale = gp.getLaneScale
)
- def parseCpuParam(cpu: CpuConfig, pgLevels: Int): CpuParam =
- CpuParam(
- coreDataBytes = cpu.getCoreDataBytes,
- xLen = cpu.getXLen,
- vaddrBits = cpu.getVaddrBits,
- paddrBits = cpu.getPaddrBits,
- pgIdxBits = cpu.getPgIdxBits,
- pgLevels = pgLevels,
- nPMPs = cpu.getNPmps
+ private def parseTileParam(param: TileParamConfig): TileParam =
+ TileParam(
+ coreDataBytes = param.getCoreDataBytes,
+ xLen = param.getXLen,
+ vaddrBits = param.getVaddrBits,
+ paddrBits = param.getPaddrBits,
+ pgIdxBits = param.getPgIdxBits,
+ pgLevels = param.getPgLevels,
+ nPMPs = param.getNPmps
)
- private def parseRocketCore(rocket: RocketCoreConfig): RocketCoreParam = {
+ private def parseRocketCpu(rocket: RocketCpuConfig): RocketCpuParam = {
val mulDiv = rocket.getMulDiv
val fpu = rocket.getFpu
val dcache = rocket.getDcache
val icache = rocket.getIcache
val btb = rocket.getBtb
- RocketCoreParam(
- xLen = rocket.getXLen,
- pgLevels = rocket.getPgLevels,
+ RocketCpuParam(
useVM = rocket.getUseVm,
useZba = rocket.getUseZba,
useZbb = rocket.getUseZbb,
@@ -327,10 +329,10 @@ object ChipLoader {
)
}
- private def parseBoomCore(boom: BoomCoreConfig): BoomCoreParam = {
+ private def parseBoomCpu(boom: BoomCpuConfig): BoomCpuParam = {
val dcache = boom.getDcache
val icache = boom.getIcache
- BoomCoreParam(
+ BoomCpuParam(
fetchWidth = boom.getFetchWidth,
decodeWidth = boom.getDecodeWidth,
numRobEntries = boom.getNumRobEntries,
diff --git a/arch/src/main/scala/framework/system/configloader/Topology.scala b/arch/src/main/scala/framework/system/configloader/Topology.scala
index 1d77eb13..28b6d2bd 100644
--- a/arch/src/main/scala/framework/system/configloader/Topology.scala
+++ b/arch/src/main/scala/framework/system/configloader/Topology.scala
@@ -1,8 +1,9 @@
package framework.system.configloader
import framework.system.tile.PrivateDCacheParams
-import framework.system.core.rocket.configs.RocketCoreParam
-import framework.system.core.boom.configs.BoomCoreParam
+import framework.system.core.rocket.configs.RocketCpuParam
+import framework.system.core.boom.configs.BoomCpuParam
+import framework.system.tile.configs.TileParam
import framework.top.GlobalConfig
/** Loader-private bundle of tile-shared memory fields. */
@@ -18,11 +19,11 @@ case class ExampleTopology(tiles: Seq[TileTopology])
sealed trait TileCore
case class RocketTileCore(
- rocket: RocketCoreParam,
+ cpu: RocketCpuParam,
buckyball: Option[GlobalConfig])
extends TileCore
-case class BoomTileCore(boom: BoomCoreParam) extends TileCore
+case class BoomTileCore(cpu: BoomCpuParam) extends TileCore
/**
* Per-tile topology: ordered cores + optional privateDCache.
@@ -30,5 +31,6 @@ case class BoomTileCore(boom: BoomCoreParam) extends TileCore
* CPU kind is per-core. Shared mem / private DCache are tile-level.
*/
case class TileTopology(
+ param: TileParam,
cores: Seq[TileCore],
privateDCache: Option[PrivateDCacheParams])
diff --git a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
index 420606d9..0bb51c91 100644
--- a/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
+++ b/arch/src/main/scala/framework/system/core/accelerator/BuckyballAccelerator.scala
@@ -36,12 +36,12 @@ class BuckyballAccelerator(val b: GlobalConfig)(edge: TLEdgeOut) extends Module
@public
val io = IO(new Bundle {
// RoCC command/response (connected to Rocket core inside tile)
- val cmd = Flipped(Decoupled(new RoCCCommandBB(b.cpu.xLen)))
- val resp = Decoupled(new RoCCResponseBB(b.cpu.xLen))
+ val cmd = Flipped(Decoupled(new RoCCCommandBB(b.tile.xLen)))
+ val resp = Decoupled(new RoCCResponseBB(b.tile.xLen))
val busy = Output(Bool())
val retired = Output(Bool())
val interrupt = Output(Bool())
- val hartid = Input(UInt(b.cpu.xLen.W))
+ val hartid = Input(UInt(b.tile.xLen.W))
// PTW interface (shared with Rocket core's PTW)
val ptw = Vec(1, new BBTLBPTWIO(b))
diff --git a/arch/src/main/scala/framework/system/core/boom/configs/BoomCoreParam.scala b/arch/src/main/scala/framework/system/core/boom/configs/BoomCpuParam.scala
similarity index 76%
rename from arch/src/main/scala/framework/system/core/boom/configs/BoomCoreParam.scala
rename to arch/src/main/scala/framework/system/core/boom/configs/BoomCpuParam.scala
index 1cd7d2b2..3514534a 100644
--- a/arch/src/main/scala/framework/system/core/boom/configs/BoomCoreParam.scala
+++ b/arch/src/main/scala/framework/system/core/boom/configs/BoomCpuParam.scala
@@ -22,24 +22,24 @@ object BoomICacheParam {
implicit val rw: ReadWriter[BoomICacheParam] = macroRW
}
-case class BoomCoreParam(
+case class BoomCpuParam(
fetchWidth: Int = 4,
decodeWidth: Int = 1,
numRobEntries: Int = 32,
dcache: BoomDCacheParam = BoomDCacheParam(),
icache: BoomICacheParam = BoomICacheParam())
-object BoomCoreParam {
- implicit val rw: ReadWriter[BoomCoreParam] = macroRW
+object BoomCpuParam {
+ implicit val rw: ReadWriter[BoomCpuParam] = macroRW
- def toBoomCoreParams(p: BoomCoreParam): BoomCoreParams = BoomCoreParams(
+ def toBoomCoreParams(p: BoomCpuParam): BoomCoreParams = BoomCoreParams(
fetchWidth = p.fetchWidth,
decodeWidth = p.decodeWidth,
numRobEntries = p.numRobEntries,
fpu = Some(FPUParams(sfmaLatency = 4, dfmaLatency = 4, divSqrt = true))
)
- def toDCacheParams(p: BoomCoreParam, rowBits: Int): DCacheParams = DCacheParams(
+ def toDCacheParams(p: BoomCpuParam, rowBits: Int): DCacheParams = DCacheParams(
rowBits = rowBits,
nSets = p.dcache.nSets,
nWays = p.dcache.nWays,
@@ -47,7 +47,7 @@ object BoomCoreParam {
nTLBWays = 8
)
- def toICacheParams(p: BoomCoreParam, rowBits: Int): ICacheParams = ICacheParams(
+ def toICacheParams(p: BoomCpuParam, rowBits: Int): ICacheParams = ICacheParams(
rowBits = rowBits,
nSets = p.icache.nSets,
nWays = p.icache.nWays,
diff --git a/arch/src/main/scala/framework/system/core/rocket/configs/RocketCoreParam.scala b/arch/src/main/scala/framework/system/core/rocket/configs/RocketCpuParam.scala
similarity index 82%
rename from arch/src/main/scala/framework/system/core/rocket/configs/RocketCoreParam.scala
rename to arch/src/main/scala/framework/system/core/rocket/configs/RocketCpuParam.scala
index 187ef001..c41eb0c4 100644
--- a/arch/src/main/scala/framework/system/core/rocket/configs/RocketCoreParam.scala
+++ b/arch/src/main/scala/framework/system/core/rocket/configs/RocketCpuParam.scala
@@ -5,9 +5,9 @@ import freechips.rocketchip.rocket.{BTBParams, DCacheParams, ICacheParams, MulDi
import freechips.rocketchip.tile.FPUParams
/**
- * JSON-serializable Rocket Core configuration parameters.
+ * JSON-serializable Rocket CPU configuration parameters.
*
- * Phase 1: Common parameters (xLen, pgLevels, useVM, Zb*, mulDiv, fpu, cache, btb)
+ * Phase 1: CPU parameters (useVM, Zb*, mulDiv, fpu, cache, btb)
* Phase 2: Advanced parameters (TLB, ECC, clockGate, etc.) - to be added later
*
* Optional features (mulDiv, fpu, btb) use an `enable` flag instead of Option[T],
@@ -101,9 +101,7 @@ object BTBParam {
}
-case class RocketCoreParam(
- xLen: Int = 64,
- pgLevels: Int = 3,
+case class RocketCpuParam(
useVM: Boolean = true,
useZba: Boolean = true,
useZbb: Boolean = true,
@@ -115,16 +113,16 @@ case class RocketCoreParam(
icache: ICacheParam = ICacheParam(),
btb: BTBParam = BTBParam())
-object RocketCoreParam {
- implicit val rw: ReadWriter[RocketCoreParam] = macroRW
+object RocketCpuParam {
+ implicit val rw: ReadWriter[RocketCpuParam] = macroRW
/**
* Convert to rocket-chip RocketCoreParams.
* rowBits and blockBytes are injected from site(SystemBusKey) and site(CacheBlockBytes).
*/
- def toRocketCoreParams(p: RocketCoreParam): RocketCoreParams = RocketCoreParams(
- xLen = p.xLen,
- pgLevels = p.pgLevels,
+ def toRocketCoreParams(p: RocketCpuParam, xLen: Int, pgLevels: Int): RocketCoreParams = RocketCoreParams(
+ xLen = xLen,
+ pgLevels = pgLevels,
useVM = p.useVM,
useZba = p.useZba,
useZbb = p.useZbb,
@@ -134,12 +132,12 @@ object RocketCoreParam {
fpu = FPUParam.toFPUParams(p.fpu)
)
- def toDCacheParams(p: RocketCoreParam, rowBits: Int, blockBytes: Int): DCacheParams =
+ def toDCacheParams(p: RocketCpuParam, rowBits: Int, blockBytes: Int): DCacheParams =
DCacheParam.toDCacheParams(p.dcache, rowBits, blockBytes)
- def toICacheParams(p: RocketCoreParam, rowBits: Int, blockBytes: Int): ICacheParams =
+ def toICacheParams(p: RocketCpuParam, rowBits: Int, blockBytes: Int): ICacheParams =
ICacheParam.toICacheParams(p.icache, rowBits, blockBytes)
- def toBTBParams(p: RocketCoreParam): Option[BTBParams] =
+ def toBTBParams(p: RocketCpuParam): Option[BTBParams] =
BTBParam.toBTBParams(p.btb)
}
diff --git a/arch/src/main/scala/framework/system/tile/BBTile.scala b/arch/src/main/scala/framework/system/tile/BBTile.scala
index 19cf3372..4af88eab 100644
--- a/arch/src/main/scala/framework/system/tile/BBTile.scala
+++ b/arch/src/main/scala/framework/system/tile/BBTile.scala
@@ -638,7 +638,7 @@ class BBTileModuleImp(outer: BBTile) extends BaseTileModuleImp(outer) with HasIC
if (rushBEnabled) {
val source = Module(new RushBCommandBridge(
RushBCoreId(outer.bbParams.tileId, i),
- accelerator.b.cpu.xLen
+ accelerator.b.tile.xLen
))
source.io.retired := accelerator.io.retired
Some(source)
diff --git a/arch/src/main/scala/framework/system/tile/Configs.scala b/arch/src/main/scala/framework/system/tile/Configs.scala
index c9adb2ec..55626cfb 100644
--- a/arch/src/main/scala/framework/system/tile/Configs.scala
+++ b/arch/src/main/scala/framework/system/tile/Configs.scala
@@ -5,7 +5,8 @@ import freechips.rocketchip.rocket.{BTBParams, DCacheParams, ICacheParams, MulDi
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tile.{FPUParams, RocketTileBoundaryBufferParams}
import framework.top.GlobalConfig
-import framework.system.core.rocket.configs.RocketCoreParam
+import framework.system.core.rocket.configs.RocketCpuParam
+import framework.system.tile.configs.TileParam
/**
* Config fragment to add N BBTiles.
@@ -24,34 +25,35 @@ object WithNBBTiles {
}
)
- def resolveRocketCores(
- nCoresPerTile: Int,
- rocketCorePerCore: Option[Seq[RocketCoreParam]]
- ): Seq[RocketCoreParam] = {
- rocketCorePerCore match {
+ def resolveRocketCpus(
+ nCoresPerTile: Int,
+ rocketCpuPerCore: Option[Seq[RocketCpuParam]]
+ ): Seq[RocketCpuParam] = {
+ rocketCpuPerCore match {
case Some(cores) =>
require(
cores.size == nCoresPerTile,
- s"rocketCorePerCore size (${cores.size}) must equal nCoresPerTile ($nCoresPerTile)"
+ s"rocketCpuPerCore size (${cores.size}) must equal nCoresPerTile ($nCoresPerTile)"
)
cores
case None =>
- throw new RuntimeException("rocketCorePerCore must be specified")
+ throw new RuntimeException("rocketCpuPerCore must be specified")
}
}
}
class WithBBTile(
- location: HierarchicalLocation = InSubsystem,
- withBuckyball: Boolean = true,
- buckyballConfig: GlobalConfig = GlobalConfig(),
- crossing: Option[RocketCrossingParams] = None,
- nCoresPerTile: Int = 1,
- buckyballPerCore: Option[Seq[Option[GlobalConfig]]] = None,
- rocketCorePerCore: Option[Seq[RocketCoreParam]] = None,
- privateDCache: Option[PrivateDCacheParams] = None,
- hiddenHartBase: Option[Int] = None)
+ tileParam: TileParam,
+ location: HierarchicalLocation = InSubsystem,
+ withBuckyball: Boolean = true,
+ buckyballConfig: GlobalConfig = GlobalConfig(),
+ crossing: Option[RocketCrossingParams] = None,
+ nCoresPerTile: Int = 1,
+ buckyballPerCore: Option[Seq[Option[GlobalConfig]]] = None,
+ rocketCpuPerCore: Option[Seq[RocketCpuParam]] = None,
+ privateDCache: Option[PrivateDCacheParams] = None,
+ hiddenHartBase: Option[Int] = None)
extends Config((site, here, up) => {
case TilesLocated(`location`) =>
val prev = up(TilesLocated(`location`), site)
@@ -64,11 +66,11 @@ class WithBBTile(
resolvedBuckyballPerCore.size == nCoresPerTile,
s"buckyballPerCore size (${resolvedBuckyballPerCore.size}) must equal nCoresPerTile ($nCoresPerTile)"
)
- val rocketCores = WithNBBTiles.resolveRocketCores(
+ val rocketCpus = WithNBBTiles.resolveRocketCpus(
nCoresPerTile,
- rocketCorePerCore
+ rocketCpuPerCore
)
- val rocketCore = rocketCores.head
+ val rocketCpu = rocketCpus.head
val rowBits = site(SystemBusKey).beatBits
val blockBytes = site(CacheBlockBytes)
val tileParams = BBTileParams(
@@ -76,13 +78,13 @@ class WithBBTile(
withBuckyball = withBuckyball,
buckyballConfig = buckyballConfig,
buckyballPerCore = resolvedBuckyballPerCore,
- rocketCorePerCore = rocketCores.map(RocketCoreParam.toRocketCoreParams),
+ rocketCorePerCore = rocketCpus.map(RocketCpuParam.toRocketCoreParams(_, tileParam.xLen, tileParam.pgLevels)),
privateDCache = privateDCache,
hiddenHartBase = hiddenHartBase,
- core = RocketCoreParam.toRocketCoreParams(rocketCore),
- dcache = Some(RocketCoreParam.toDCacheParams(rocketCore, rowBits, blockBytes)),
- icache = Some(RocketCoreParam.toICacheParams(rocketCore, rowBits, blockBytes)),
- btb = RocketCoreParam.toBTBParams(rocketCore)
+ core = RocketCpuParam.toRocketCoreParams(rocketCpu, tileParam.xLen, tileParam.pgLevels),
+ dcache = Some(RocketCpuParam.toDCacheParams(rocketCpu, rowBits, blockBytes)),
+ icache = Some(RocketCpuParam.toICacheParams(rocketCpu, rowBits, blockBytes)),
+ btb = RocketCpuParam.toBTBParams(rocketCpu)
)
BBTileAttachParams(
tileParams.copy(tileId = idOffset),
@@ -92,16 +94,17 @@ class WithBBTile(
})
class WithNBBTiles(
- n: Int,
- location: HierarchicalLocation = InSubsystem,
- withBuckyball: Boolean = true,
- buckyballConfig: GlobalConfig = GlobalConfig(),
- crossing: Option[RocketCrossingParams] = None,
- nCoresPerTile: Int = 1,
- buckyballPerCore: Option[Seq[Option[GlobalConfig]]] = None,
- rocketCorePerCore: Option[Seq[RocketCoreParam]] = None,
- privateDCache: Option[PrivateDCacheParams] = None,
- hiddenHartBase: Option[Int] = None)
+ n: Int,
+ tileParam: TileParam,
+ location: HierarchicalLocation = InSubsystem,
+ withBuckyball: Boolean = true,
+ buckyballConfig: GlobalConfig = GlobalConfig(),
+ crossing: Option[RocketCrossingParams] = None,
+ nCoresPerTile: Int = 1,
+ buckyballPerCore: Option[Seq[Option[GlobalConfig]]] = None,
+ rocketCpuPerCore: Option[Seq[RocketCpuParam]] = None,
+ privateDCache: Option[PrivateDCacheParams] = None,
+ hiddenHartBase: Option[Int] = None)
extends Config((site, here, up) => {
case TilesLocated(`location`) =>
val prev = up(TilesLocated(`location`), site)
@@ -114,11 +117,11 @@ class WithNBBTiles(
resolvedBuckyballPerCore.size == nCoresPerTile,
s"buckyballPerCore size (${resolvedBuckyballPerCore.size}) must equal nCoresPerTile ($nCoresPerTile)"
)
- val rocketCores = WithNBBTiles.resolveRocketCores(
+ val rocketCpus = WithNBBTiles.resolveRocketCpus(
nCoresPerTile,
- rocketCorePerCore
+ rocketCpuPerCore
)
- val rocketCore = rocketCores.head
+ val rocketCpu = rocketCpus.head
val rowBits = site(SystemBusKey).beatBits
val blockBytes = site(CacheBlockBytes)
val tileParams = BBTileParams(
@@ -126,13 +129,13 @@ class WithNBBTiles(
withBuckyball = withBuckyball,
buckyballConfig = buckyballConfig,
buckyballPerCore = resolvedBuckyballPerCore,
- rocketCorePerCore = rocketCores.map(RocketCoreParam.toRocketCoreParams),
+ rocketCorePerCore = rocketCpus.map(RocketCpuParam.toRocketCoreParams(_, tileParam.xLen, tileParam.pgLevels)),
privateDCache = privateDCache,
hiddenHartBase = hiddenHartBase,
- core = RocketCoreParam.toRocketCoreParams(rocketCore),
- dcache = Some(RocketCoreParam.toDCacheParams(rocketCore, rowBits, blockBytes)),
- icache = Some(RocketCoreParam.toICacheParams(rocketCore, rowBits, blockBytes)),
- btb = RocketCoreParam.toBTBParams(rocketCore)
+ core = RocketCpuParam.toRocketCoreParams(rocketCpu, tileParam.xLen, tileParam.pgLevels),
+ dcache = Some(RocketCpuParam.toDCacheParams(rocketCpu, rowBits, blockBytes)),
+ icache = Some(RocketCpuParam.toICacheParams(rocketCpu, rowBits, blockBytes)),
+ btb = RocketCpuParam.toBTBParams(rocketCpu)
)
List.tabulate(n)(i =>
BBTileAttachParams(
diff --git a/arch/src/main/scala/framework/system/tile/WithBoomTile.scala b/arch/src/main/scala/framework/system/tile/WithBoomTile.scala
index 585d5b36..c8376902 100644
--- a/arch/src/main/scala/framework/system/tile/WithBoomTile.scala
+++ b/arch/src/main/scala/framework/system/tile/WithBoomTile.scala
@@ -3,10 +3,10 @@ package framework.system.tile
import org.chipsalliance.cde.config._
import freechips.rocketchip.subsystem._
import boom.v3.common.{BoomTileAttachParams, BoomTileParams, WithTAGELBPD}
-import framework.system.core.boom.configs.BoomCoreParam
+import framework.system.core.boom.configs.BoomCpuParam
-/** Attach one BoomTile from BoomCoreParam. */
-class WithBoomTile(param: BoomCoreParam, location: HierarchicalLocation = InSubsystem)
+/** Attach one BoomTile from BoomCpuParam. */
+class WithBoomTile(param: BoomCpuParam, location: HierarchicalLocation = InSubsystem)
extends Config(
new WithTAGELBPD ++
new Config((site, here, up) => {
@@ -15,9 +15,9 @@ class WithBoomTile(param: BoomCoreParam, location: HierarchicalLocation = InSubs
val idOffset = up(NumTiles)
val rowBits = site(SystemBusKey).beatBits
val tileParams = BoomTileParams(
- core = BoomCoreParam.toBoomCoreParams(param),
- dcache = Some(BoomCoreParam.toDCacheParams(param, rowBits)),
- icache = Some(BoomCoreParam.toICacheParams(param, rowBits)),
+ core = BoomCpuParam.toBoomCoreParams(param),
+ dcache = Some(BoomCpuParam.toDCacheParams(param, rowBits)),
+ icache = Some(BoomCpuParam.toICacheParams(param, rowBits)),
tileId = idOffset
)
BoomTileAttachParams(
diff --git a/arch/src/main/scala/framework/system/tile/WithBuckyballTiles.scala b/arch/src/main/scala/framework/system/tile/WithBuckyballTiles.scala
index 8c0e4ad9..98249c05 100644
--- a/arch/src/main/scala/framework/system/tile/WithBuckyballTiles.scala
+++ b/arch/src/main/scala/framework/system/tile/WithBuckyballTiles.scala
@@ -50,28 +50,29 @@ object WithBuckyballTiles {
throw new RuntimeException("boom-only tile cannot enable privateDCache")
}
tile.cores.map {
- case BoomTileCore(boom) => new WithBoomTile(boom)
- case other => throw new RuntimeException(s"expected BoomTileCore, got $other")
+ case BoomTileCore(cpu) => new WithBoomTile(cpu)
+ case other => throw new RuntimeException(s"expected BoomTileCore, got $other")
}
} else {
if (tile.privateDCache.isDefined) {
throw new RuntimeException("heterogeneous tile cannot enable privateDCache")
}
tile.cores.map {
- case RocketTileCore(rocket, buckyball) =>
+ case RocketTileCore(cpu, buckyball) =>
if (buckyball.isDefined) {
throw new RuntimeException("heterogeneous tile cannot enable buckyball")
}
new WithBBTile(
+ tileParam = tile.param,
withBuckyball = false,
nCoresPerTile = 1,
buckyballPerCore = Some(Seq(None)),
- rocketCorePerCore = Some(Seq(rocket)),
+ rocketCpuPerCore = Some(Seq(cpu)),
privateDCache = None,
hiddenHartBase = hiddenHartBase
)
- case BoomTileCore(boom) =>
- new WithBoomTile(boom)
+ case BoomTileCore(cpu) =>
+ new WithBoomTile(cpu)
}
}
}
@@ -82,17 +83,18 @@ object WithBuckyballTiles {
hiddenHartBase: Option[Int]
): Config = {
val rockets = tile.cores.map {
- case RocketTileCore(rocket, bb) => (rocket, bb)
- case other => throw new RuntimeException(s"expected RocketTileCore, got $other")
+ case RocketTileCore(cpu, bb) => (cpu, bb)
+ case other => throw new RuntimeException(s"expected RocketTileCore, got $other")
}
val resolved =
if (withBuckyball) rockets.map(_._2)
else rockets.map(_ => None)
new WithBBTile(
+ tileParam = tile.param,
withBuckyball = resolved.exists(_.isDefined),
nCoresPerTile = rockets.size,
buckyballPerCore = Some(resolved),
- rocketCorePerCore = Some(rockets.map(_._1)),
+ rocketCpuPerCore = Some(rockets.map(_._1)),
privateDCache = tile.privateDCache,
hiddenHartBase = hiddenHartBase
)
diff --git a/arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala b/arch/src/main/scala/framework/system/tile/configs/TileParam.scala
similarity index 68%
rename from arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala
rename to arch/src/main/scala/framework/system/tile/configs/TileParam.scala
index 1609deef..bb59efd4 100644
--- a/arch/src/main/scala/framework/system/cpu/configs/CpuParam.scala
+++ b/arch/src/main/scala/framework/system/tile/configs/TileParam.scala
@@ -1,8 +1,8 @@
-package framework.system.cpu.configs
+package framework.system.tile.configs
import upickle.default._
-case class CpuParam(
+case class TileParam(
coreDataBytes: Int,
xLen: Int,
vaddrBits: Int,
@@ -11,10 +11,10 @@ case class CpuParam(
pgLevels: Int,
nPMPs: Int) // Physical Memory Protection entries, typically 8 or 16
-object CpuParam {
- implicit val rw: ReadWriter[CpuParam] = macroRW
+object TileParam {
+ implicit val rw: ReadWriter[TileParam] = macroRW
- def apply(): CpuParam = CpuParam(
+ def apply(): TileParam = TileParam(
coreDataBytes = 0,
xLen = 0,
vaddrBits = 0,
diff --git a/arch/src/main/scala/framework/top/GlobalConfig.scala b/arch/src/main/scala/framework/top/GlobalConfig.scala
index 4fcfc150..28b41dc5 100644
--- a/arch/src/main/scala/framework/top/GlobalConfig.scala
+++ b/arch/src/main/scala/framework/top/GlobalConfig.scala
@@ -6,7 +6,7 @@ import framework.memdomain.configs.MemDomainParam
import framework.frontend.configs.FrontendParam
import framework.gpdomain.configs.GpDomainParam
import framework.balldomain.configs.BallDomainParam
-import framework.system.cpu.configs.CpuParam
+import framework.system.tile.configs.TileParam
import framework.top.configs.SimParam
case class GlobalConfig(
@@ -14,7 +14,7 @@ case class GlobalConfig(
frontend: FrontendParam,
gpDomain: GpDomainParam,
ballDomain: BallDomainParam,
- cpu: CpuParam,
+ tile: TileParam,
sim: SimParam)
extends SerializableModuleParameter
@@ -27,7 +27,7 @@ object GlobalConfig {
frontend = FrontendParam(),
gpDomain = GpDomainParam(),
ballDomain = BallDomainParam(),
- cpu = CpuParam(),
+ tile = TileParam(),
sim = SimParam()
)
}
diff --git a/bbdev b/bbdev
index 3fc00c06..b06f4061 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit 3fc00c06fc6729d7ae983dddf79da5b58768821c
+Subproject commit b06f40617fb2fdebe86dba38901d830e0e01201e
diff --git a/bebop b/bebop
index f3550acb..e622d631 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit f3550acb282d49ab97e724e89c98f074f478eaa2
+Subproject commit e622d6316306773b19ef6720534295c03e18760e
diff --git a/examples/chips/goban/configs/designs/tiles/16core-incoherent.toml b/examples/chips/goban/configs/designs/tiles/16core-incoherent.toml
index aceef646..64b651ec 100644
--- a/examples/chips/goban/configs/designs/tiles/16core-incoherent.toml
+++ b/examples/chips/goban/configs/designs/tiles/16core-incoherent.toml
@@ -1,5 +1,13 @@
# Goban Tile (16 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/16core.toml b/examples/chips/goban/configs/designs/tiles/16core.toml
index 57648b82..ab6d3325 100644
--- a/examples/chips/goban/configs/designs/tiles/16core.toml
+++ b/examples/chips/goban/configs/designs/tiles/16core.toml
@@ -1,5 +1,13 @@
# Goban Tile (16 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/2core.toml b/examples/chips/goban/configs/designs/tiles/2core.toml
index 7660cbf3..438dfaa1 100644
--- a/examples/chips/goban/configs/designs/tiles/2core.toml
+++ b/examples/chips/goban/configs/designs/tiles/2core.toml
@@ -1,5 +1,13 @@
# Goban Tile (2 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/32core.toml b/examples/chips/goban/configs/designs/tiles/32core.toml
index 62a4faa3..54ea67e3 100644
--- a/examples/chips/goban/configs/designs/tiles/32core.toml
+++ b/examples/chips/goban/configs/designs/tiles/32core.toml
@@ -1,5 +1,13 @@
# Goban Tile (32 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/4core-private-1bb.toml b/examples/chips/goban/configs/designs/tiles/4core-private-1bb.toml
index f324a376..0d60159e 100644
--- a/examples/chips/goban/configs/designs/tiles/4core-private-1bb.toml
+++ b/examples/chips/goban/configs/designs/tiles/4core-private-1bb.toml
@@ -1,5 +1,13 @@
# Goban Tile (4 cores: core 0 has Buckyball, cores 1-3 are Rocket-only)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/64core.toml b/examples/chips/goban/configs/designs/tiles/64core.toml
index f46dd4bf..11652d00 100644
--- a/examples/chips/goban/configs/designs/tiles/64core.toml
+++ b/examples/chips/goban/configs/designs/tiles/64core.toml
@@ -1,5 +1,13 @@
# Goban Tile (16 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/8core-incoherent.toml b/examples/chips/goban/configs/designs/tiles/8core-incoherent.toml
index 90d1f5c8..77b7d0a2 100644
--- a/examples/chips/goban/configs/designs/tiles/8core-incoherent.toml
+++ b/examples/chips/goban/configs/designs/tiles/8core-incoherent.toml
@@ -1,5 +1,13 @@
# Goban Tile (8 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/8core.toml b/examples/chips/goban/configs/designs/tiles/8core.toml
index dfb6f941..d4c6ef4e 100644
--- a/examples/chips/goban/configs/designs/tiles/8core.toml
+++ b/examples/chips/goban/configs/designs/tiles/8core.toml
@@ -1,5 +1,13 @@
# Goban Tile (8 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/goban/configs/designs/tiles/default.toml b/examples/chips/goban/configs/designs/tiles/default.toml
index fc5bd61b..86ff6b54 100644
--- a/examples/chips/goban/configs/designs/tiles/default.toml
+++ b/examples/chips/goban/configs/designs/tiles/default.toml
@@ -1,5 +1,13 @@
# Goban Tile (default: 4 identical cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/multi-rocket/configs/designs/tiles/32core.toml b/examples/chips/multi-rocket/configs/designs/tiles/32core.toml
index 53f18508..77e54ded 100644
--- a/examples/chips/multi-rocket/configs/designs/tiles/32core.toml
+++ b/examples/chips/multi-rocket/configs/designs/tiles/32core.toml
@@ -1,5 +1,13 @@
# multi-rocket Tile (32 Rocket-only cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
[privateDCache]
enable = true
ways = 4
diff --git a/examples/chips/multi-rocket/configs/designs/tiles/48core.toml b/examples/chips/multi-rocket/configs/designs/tiles/48core.toml
index 0dcd6c8b..c4468831 100644
--- a/examples/chips/multi-rocket/configs/designs/tiles/48core.toml
+++ b/examples/chips/multi-rocket/configs/designs/tiles/48core.toml
@@ -1,5 +1,13 @@
# multi-rocket Tile (48 Rocket-only cores)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
[privateDCache]
enable = true
ways = 4
diff --git a/examples/chips/pebble/configs/designs/tiles/default.toml b/examples/chips/pebble/configs/designs/tiles/default.toml
index e91d7b9b..6ea1654c 100644
--- a/examples/chips/pebble/configs/designs/tiles/default.toml
+++ b/examples/chips/pebble/configs/designs/tiles/default.toml
@@ -1,5 +1,13 @@
# Pebble tile configuration
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/poly/configs/designs/tiles/default.toml b/examples/chips/poly/configs/designs/tiles/default.toml
index fdf1973e..14ae03d1 100644
--- a/examples/chips/poly/configs/designs/tiles/default.toml
+++ b/examples/chips/poly/configs/designs/tiles/default.toml
@@ -1,5 +1,13 @@
# Poly Tile: three prefill Cores and two decode Cores.
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/toy/configs/designs/tiles/16core.toml b/examples/chips/toy/configs/designs/tiles/16core.toml
index 33db43e8..01d7a0ee 100644
--- a/examples/chips/toy/configs/designs/tiles/16core.toml
+++ b/examples/chips/toy/configs/designs/tiles/16core.toml
@@ -1,5 +1,13 @@
# Toy Tile Configuration (16 cores, shared tile-private L2)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/toy/configs/designs/tiles/4core.toml b/examples/chips/toy/configs/designs/tiles/4core.toml
index 71e4fd90..43b34ad7 100644
--- a/examples/chips/toy/configs/designs/tiles/4core.toml
+++ b/examples/chips/toy/configs/designs/tiles/4core.toml
@@ -1,5 +1,13 @@
# Toy Tile Configuration (8 cores, shared tile-private L2)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/toy/configs/designs/tiles/8core.toml b/examples/chips/toy/configs/designs/tiles/8core.toml
index 2db67672..3b323e41 100644
--- a/examples/chips/toy/configs/designs/tiles/8core.toml
+++ b/examples/chips/toy/configs/designs/tiles/8core.toml
@@ -1,5 +1,13 @@
# Toy Tile Configuration (8 cores, shared tile-private L2)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/chips/toy/configs/designs/tiles/default.toml b/examples/chips/toy/configs/designs/tiles/default.toml
index d83ed303..f830aaba 100644
--- a/examples/chips/toy/configs/designs/tiles/default.toml
+++ b/examples/chips/toy/configs/designs/tiles/default.toml
@@ -1,5 +1,13 @@
# Toy Tile Configuration (1 core)
+coreDataBytes = 64
+xLen = 64
+vaddrBits = 39
+paddrBits = 56
+pgIdxBits = 12
+pgLevels = 3
+nPMPs = 8
+
memBallChannelNum = 6
[privateDCache]
diff --git a/examples/cores/boom/configs/cpu/boom/boomCore.toml b/examples/cores/boom/configs/cpu/boom/default.toml
similarity index 100%
rename from examples/cores/boom/configs/cpu/boom/boomCore.toml
rename to examples/cores/boom/configs/cpu/boom/default.toml
diff --git a/examples/cores/boom/configs/cpu/default.toml b/examples/cores/boom/configs/cpu/default.toml
index 6e81612a..40b4f000 100644
--- a/examples/cores/boom/configs/cpu/default.toml
+++ b/examples/cores/boom/configs/cpu/default.toml
@@ -1,2 +1,2 @@
kind = "boom"
-config = "./boom/boomCore.toml"
+config = "./boom/default.toml"
diff --git a/examples/cores/decode/configs/cpu/default.toml b/examples/cores/decode/configs/cpu/default.toml
index af32891c..1bf2f46e 100644
--- a/examples/cores/decode/configs/cpu/default.toml
+++ b/examples/cores/decode/configs/cpu/default.toml
@@ -1,8 +1,2 @@
kind = "rocket"
-config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
+config = "../../../rocket/configs/cpu/rocket/default.toml"
diff --git a/examples/cores/goban/configs/cpu/default.toml b/examples/cores/goban/configs/cpu/default.toml
index af32891c..1bf2f46e 100644
--- a/examples/cores/goban/configs/cpu/default.toml
+++ b/examples/cores/goban/configs/cpu/default.toml
@@ -1,8 +1,2 @@
kind = "rocket"
-config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
+config = "../../../rocket/configs/cpu/rocket/default.toml"
diff --git a/examples/cores/pebble/configs/cpu/default.toml b/examples/cores/pebble/configs/cpu/default.toml
index 2420ad1e..e651581c 100644
--- a/examples/cores/pebble/configs/cpu/default.toml
+++ b/examples/cores/pebble/configs/cpu/default.toml
@@ -1,8 +1,2 @@
kind = "rocket"
-config = "./rocket/rocketCore.toml"
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
+config = "./rocket/default.toml"
diff --git a/examples/cores/pebble/configs/cpu/rocket/rocketCore.toml b/examples/cores/pebble/configs/cpu/rocket/default.toml
similarity index 93%
rename from examples/cores/pebble/configs/cpu/rocket/rocketCore.toml
rename to examples/cores/pebble/configs/cpu/rocket/default.toml
index c84e83e9..b44c13ce 100644
--- a/examples/cores/pebble/configs/cpu/rocket/rocketCore.toml
+++ b/examples/cores/pebble/configs/cpu/rocket/default.toml
@@ -1,5 +1,3 @@
-xLen = 64
-pgLevels = 3
useVM = true
useZba = true
useZbb = true
diff --git a/examples/cores/prefill/configs/cpu/default.toml b/examples/cores/prefill/configs/cpu/default.toml
index af32891c..1bf2f46e 100644
--- a/examples/cores/prefill/configs/cpu/default.toml
+++ b/examples/cores/prefill/configs/cpu/default.toml
@@ -1,8 +1,2 @@
kind = "rocket"
-config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
+config = "../../../rocket/configs/cpu/rocket/default.toml"
diff --git a/examples/cores/rocket/configs/cpu/default.toml b/examples/cores/rocket/configs/cpu/default.toml
index 4d5aca16..e651581c 100644
--- a/examples/cores/rocket/configs/cpu/default.toml
+++ b/examples/cores/rocket/configs/cpu/default.toml
@@ -1,2 +1,2 @@
kind = "rocket"
-config = "./rocket/rocketCore.toml"
+config = "./rocket/default.toml"
diff --git a/examples/cores/rocket/configs/cpu/rocket/rocketCore.toml b/examples/cores/rocket/configs/cpu/rocket/default.toml
similarity index 93%
rename from examples/cores/rocket/configs/cpu/rocket/rocketCore.toml
rename to examples/cores/rocket/configs/cpu/rocket/default.toml
index daffea1a..854871f1 100644
--- a/examples/cores/rocket/configs/cpu/rocket/rocketCore.toml
+++ b/examples/cores/rocket/configs/cpu/rocket/default.toml
@@ -1,5 +1,3 @@
-xLen = 64
-pgLevels = 3
useVM = true
useZba = true
useZbb = true
diff --git a/examples/cores/toy/configs/cpu/default.toml b/examples/cores/toy/configs/cpu/default.toml
index af32891c..1bf2f46e 100644
--- a/examples/cores/toy/configs/cpu/default.toml
+++ b/examples/cores/toy/configs/cpu/default.toml
@@ -1,8 +1,2 @@
kind = "rocket"
-config = "../../../rocket/configs/cpu/rocket/rocketCore.toml"
-coreDataBytes = 64
-xLen = 64
-vaddrBits = 39
-paddrBits = 56
-pgIdxBits = 12
-nPMPs = 8
+config = "../../../rocket/configs/cpu/rocket/default.toml"
From 9242bea7e907e65df461c55b0c0919be582b454f Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 10:57:39 +0800
Subject: [PATCH 31/36] update: bump bbdev and bebop to the latest version
---
bbdev | 2 +-
bebop | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/bbdev b/bbdev
index b06f4061..fb687354 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit b06f40617fb2fdebe86dba38901d830e0e01201e
+Subproject commit fb68735418896a2acf8f462b7a68ce63eabe95c7
diff --git a/bebop b/bebop
index e622d631..29d4307d 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit e622d6316306773b19ef6720534295c03e18760e
+Subproject commit 29d4307d1391f69f845a4ed1de1ed2569bfee424
From f4a3ba3e74438ba18fc35cbb95542d40bd35e6fa Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 11:02:56 +0800
Subject: [PATCH 32/36] fix: refine CI repo lock script
---
.github/scripts/ci_repo_lock.sh | 4 ++--
bbdev | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/scripts/ci_repo_lock.sh b/.github/scripts/ci_repo_lock.sh
index ec729fee..32805b5f 100755
--- a/.github/scripts/ci_repo_lock.sh
+++ b/.github/scripts/ci_repo_lock.sh
@@ -26,8 +26,8 @@ repo_reset() {
# buckyball repository it self never depend on submodules in submodules unless llvm in buddy-mlir
git fetch --force --prune origin "${want_sha}"
- git -c checkout --detach --force "${want_sha}"
- git -c reset --hard "${want_sha}"
+ git checkout --detach --force "${want_sha}"
+ git reset --hard "${want_sha}"
git clean -ffd
rm -rf arch/out
diff --git a/bbdev b/bbdev
index fb687354..75ad612d 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit fb68735418896a2acf8f462b7a68ce63eabe95c7
+Subproject commit 75ad612d7e052f16d745309fae56ba775a444259
From 848c9d4b75efff24cdf81dbd528967ea1cfbd2f3 Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 11:37:49 +0800
Subject: [PATCH 33/36] fix: clean up gemmini state and loop micro ops code
---
bbdev | 2 +-
bebop | 2 +-
.../balls/gemmini/emu/src/gemmini_state.rs | 24 -----------------
.../balls/gemmini/emu/src/loop_micro_ops.rs | 9 +++++--
examples/chips/poly/emu/Cargo.lock | 21 ++++++++++-----
examples/chips/poly/emu/src/main.rs | 27 ++++++++++++++-----
6 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/bbdev b/bbdev
index 75ad612d..f636bdf6 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit 75ad612d7e052f16d745309fae56ba775a444259
+Subproject commit f636bdf675d852a1340304c34111b5d0508ceffe
diff --git a/bebop b/bebop
index 29d4307d..cb3b763f 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit 29d4307d1391f69f845a4ed1de1ed2569bfee424
+Subproject commit cb3b763fba83572bab67956012736e6e9689b6b7
diff --git a/examples/balls/gemmini/emu/src/gemmini_state.rs b/examples/balls/gemmini/emu/src/gemmini_state.rs
index 3da2a795..04c4b9d4 100644
--- a/examples/balls/gemmini/emu/src/gemmini_state.rs
+++ b/examples/balls/gemmini/emu/src/gemmini_state.rs
@@ -1,5 +1,4 @@
//! Global config for Gemmini / loop instructions. Mutex is fine because Spike calls in on a single worker.
-use super::super::bank::{mem_read, mem_write};
use std::sync::{Mutex, OnceLock};
#[derive(Clone, Default)]
@@ -98,26 +97,3 @@ pub fn in_shift(v: i32, shift: u32) -> i32 {
base
}
}
-
-pub fn mem_u8(mem: &[u8], addr: u64) -> u8 {
- mem_read(mem, addr)
-}
-
-pub fn mem_i8(mem: &[u8], addr: u64) -> i8 {
- mem_u8(mem, addr) as i8
-}
-
-pub fn mem_i32_le(mem: &[u8], addr: u64) -> i32 {
- let mut b = [0u8; 4];
- for (i, byte) in b.iter_mut().enumerate() {
- *byte = mem_read(mem, addr + i as u64);
- }
- i32::from_le_bytes(b)
-}
-
-pub fn mem_write_i32(mem: &mut [u8], addr: u64, v: i32) {
- let b = v.to_le_bytes();
- for (i, byte) in b.iter().enumerate() {
- mem_write(mem, addr + i as u64, *byte);
- }
-}
diff --git a/examples/balls/gemmini/emu/src/loop_micro_ops.rs b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
index eac3f2a0..9ff84641 100644
--- a/examples/balls/gemmini/emu/src/loop_micro_ops.rs
+++ b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
@@ -59,7 +59,7 @@ pub fn alloc(ctx: &mut ExecContext, bank: u64, groups: u64) {
}
pub fn mvin(ctx: &mut ExecContext, bank: u64, addr: u64, iter: u64, stride: u64) {
- execute(FUNCT_MVIN, banks(bank, 0, 0, iter), dma(addr, stride), ctx);
+ execute(FUNCT_MVIN, banks(0, 0, bank, iter), dma(addr, stride), ctx);
}
pub fn mvout(ctx: &mut ExecContext, bank: u64, addr: u64, iter: u64, stride: u64) {
@@ -67,7 +67,12 @@ pub fn mvout(ctx: &mut ExecContext, bank: u64, addr: u64, iter: u64, stride: u64
}
pub fn preload(ctx: &mut ExecContext, source: u64, output: u64, iter: u64) {
- execute(ball_funct("GEMMINI_PRELOAD"), banks(source, 0, output, iter), 1, ctx);
+ execute(
+ ball_funct("GEMMINI_PRELOAD"),
+ banks(source, 0, output, iter),
+ 1,
+ ctx,
+ );
}
pub fn compute(
diff --git a/examples/chips/poly/emu/Cargo.lock b/examples/chips/poly/emu/Cargo.lock
index 0f1ef121..9d6543b9 100644
--- a/examples/chips/poly/emu/Cargo.lock
+++ b/examples/chips/poly/emu/Cargo.lock
@@ -104,7 +104,6 @@ dependencies = [
"serde",
"serde_json",
"snafu",
- "xxhash-rust",
]
[[package]]
@@ -113,8 +112,10 @@ version = "0.1.0"
dependencies = [
"bebop-bank-hash",
"bebop-bemu-profile",
+ "bebop-clint",
"bebop-dtb",
"bebop-elf",
+ "bebop-plic",
"bebop-rushb",
"bebop-syscall",
"bebop-uart",
@@ -145,14 +146,26 @@ dependencies = [
"walkdir",
]
+[[package]]
+name = "bebop-clint"
+version = "0.1.0"
+
[[package]]
name = "bebop-dtb"
version = "0.1.0"
+dependencies = [
+ "bebop-clint",
+ "bebop-plic",
+]
[[package]]
name = "bebop-elf"
version = "0.1.0"
+[[package]]
+name = "bebop-plic"
+version = "0.1.0"
+
[[package]]
name = "bebop-rushb"
version = "0.1.0"
@@ -1037,12 +1050,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "xxhash-rust"
-version = "0.8.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6"
-
[[package]]
name = "zmij"
version = "1.0.23"
diff --git a/examples/chips/poly/emu/src/main.rs b/examples/chips/poly/emu/src/main.rs
index 2b1ee4fb..b94a544e 100644
--- a/examples/chips/poly/emu/src/main.rs
+++ b/examples/chips/poly/emu/src/main.rs
@@ -1,5 +1,5 @@
-use clap::Parser;
use bebop_bemu::{tile_topology, BemuInstance, SharedMemory, TraceConfig};
+use clap::Parser;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
use std::sync::{mpsc, Arc, Condvar, Mutex};
@@ -42,9 +42,15 @@ impl StartGate {
}
fn wait(&self) -> Result<(), String> {
- let mut result = self.result.lock().map_err(|_| "BEMU start gate poisoned".to_string())?;
+ let mut result = self
+ .result
+ .lock()
+ .map_err(|_| "BEMU start gate poisoned".to_string())?;
while result.is_none() {
- result = self.ready.wait(result).map_err(|_| "BEMU start gate poisoned".to_string())?;
+ result = self
+ .ready
+ .wait(result)
+ .map_err(|_| "BEMU start gate poisoned".to_string())?;
}
result.as_ref().expect("BEMU start gate was set").clone()
}
@@ -137,7 +143,10 @@ fn run(args: Args) -> Result<(), String> {
let mut preparation_error = None;
for _ in 0..workers.len() {
- if let Err(error) = prepared_rx.recv().map_err(|_| "Core worker exited before initialization".to_string())? {
+ if let Err(error) = prepared_rx
+ .recv()
+ .map_err(|_| "Core worker exited before initialization".to_string())?
+ {
preparation_error.get_or_insert(error);
}
}
@@ -182,7 +191,9 @@ fn run_core(
"[INFO] starting Core worker hart={hart_id} core={core_name} core_index={core_index}"
);
let prepared_bemu = (|| {
- let _turn = schedule.lock().map_err(|_| "BEMU scheduler poisoned".to_string())?;
+ let _turn = schedule
+ .lock()
+ .map_err(|_| "BEMU scheduler poisoned".to_string())?;
let mut bemu = BemuInstance::new_with_core_hart(
log_dir,
trace,
@@ -213,12 +224,14 @@ fn run_core(
loop {
let barrier_hit = {
- let _turn = schedule.lock().map_err(|_| "BEMU scheduler poisoned".to_string())?;
+ let _turn = schedule
+ .lock()
+ .map_err(|_| "BEMU scheduler poisoned".to_string())?;
if done.load(Ordering::Acquire) {
bemu.stop(exit_code.load(Ordering::Acquire));
break;
}
- if let Err(error) = bemu.step() {
+ if let Err(error) = bemu.step(1) {
exit_code.store(1, Ordering::Release);
done.store(true, Ordering::Release);
memory.abort_barrier();
From cb89ab7d55f911ff702acde51cda83db7fe2d10f Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 13:03:23 +0800
Subject: [PATCH 34/36] fix: refine shared memory configuration, and enhance
Gemmini micro-operations
---
.../memdomain/backend/shared/SharedMem.scala | 8 +--
.../memdomain/configs/MemDomainParam.scala | 4 +-
.../system/configloader/ChipLoader.scala | 37 ++++++++------
.../system/configloader/Topology.scala | 7 ---
bb-tests/workloads/CMakeLists.txt | 3 ++
bbdev | 2 +-
bebop | 2 +-
compiler/lib/RushBRuntime.c | 49 +++++++++++++++++++
.../balls/gemmini/emu/src/loop_micro_ops.rs | 29 +++++------
examples/chips/goban/emu/Cargo.lock | 21 +++++---
examples/chips/goban/emu/src/main.rs | 2 +-
examples/chips/multi-rocket/emu/src/main.rs | 27 +++++++---
.../scala/sims/verilator/TargetConfigs.scala | 7 +--
13 files changed, 128 insertions(+), 70 deletions(-)
diff --git a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
index 1684266c..91dc4cfe 100644
--- a/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
+++ b/arch/src/main/scala/framework/memdomain/backend/shared/SharedMem.scala
@@ -10,12 +10,8 @@ object SharedMemLayout {
def totalBank(b: GlobalConfig): Int = {
require(b.memDomain.sharedEnable, "shared memory is disabled")
- require(b.memDomain.sharedEntries > 0, "sharedEntries must be > 0")
- require(
- b.memDomain.sharedEntries % b.memDomain.bankEntries == 0,
- s"sharedEntries(${b.memDomain.sharedEntries}) must be divisible by bankEntries(${b.memDomain.bankEntries})"
- )
- b.memDomain.sharedEntries / b.memDomain.bankEntries
+ require(b.memDomain.sharedBankNum > 0, "sharedBankNum must be > 0")
+ b.memDomain.sharedBankNum
}
def channelPerHart(b: GlobalConfig): Int = {
diff --git a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
index 757794c0..015045b6 100644
--- a/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
+++ b/arch/src/main/scala/framework/memdomain/configs/MemDomainParam.scala
@@ -17,6 +17,7 @@ case class MemDomainParam(
virtualBankCount: Int,
sharedEnable: Boolean,
sharedEntries: Int,
+ sharedBankNum: Int,
sharedInputChannels: Int,
sharedDefaultGroupCount: Int,
nCores: Int,
@@ -39,7 +40,7 @@ case class MemDomainParam(
val mmioBankBytes: Int = mmioBankEntries * (mmioBankWidth / 8)
val mmioTotalBytes: Int = mmioBankNum * mmioBankBytes
val vbankIdWidth: Int = chisel3.util.log2Up(virtualBankCount)
- val maxGroupCount: Int = math.max(bankNum, if (sharedEnable) sharedEntries / bankEntries else bankNum)
+ val maxGroupCount: Int = math.max(bankNum, if (sharedEnable) sharedBankNum else bankNum)
val groupCountWidth: Int = chisel3.util.log2Up(maxGroupCount + 1)
val groupIdWidth: Int = chisel3.util.log2Up(maxGroupCount)
}
@@ -56,6 +57,7 @@ object MemDomainParam {
virtualBankCount = 0,
sharedEnable = false,
sharedEntries = 0,
+ sharedBankNum = 0,
sharedInputChannels = 0,
sharedDefaultGroupCount = 0,
nCores = 0,
diff --git a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
index b74dbdef..5edb8a9a 100644
--- a/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
+++ b/arch/src/main/scala/framework/system/configloader/ChipLoader.scala
@@ -85,21 +85,22 @@ object ChipLoader {
if (hasBuckyball) {
require(virtualBankCount > 0, s"tile ${tile.getPath}: virtual_bank_count must be > 0")
}
- if (shared.getEnable) {
- val first = cores(indices.head)
- val firstBank = first.getMem.getBank
- indices.iterator.map(idx => cores(idx)).filter(_.getBalldomain.getBallNum > 0).foreach { core =>
+ val sharedBankNum =
+ if (shared.getEnable) {
+ val firstBank = cores(indices.head).getMem.getBank
+ indices.iterator.map(idx => cores(idx)).filter(_.getBalldomain.getBallNum > 0).foreach { core =>
+ require(
+ core.getMem.getBank.getWidth == firstBank.getWidth,
+ s"tile ${tile.getPath}: all Buckyball cores must use shared bank width ${firstBank.getWidth}"
+ )
+ }
+ require(shared.getEntries > 0, s"tile ${tile.getPath}: shared entries must be > 0")
require(
- core.getMem.getBank.getWidth == firstBank.getWidth,
- s"tile ${tile.getPath}: all Buckyball cores must use shared bank width ${firstBank.getWidth}"
+ shared.getEntries % firstBank.getEntries == 0,
+ s"tile ${tile.getPath}: shared entries ${shared.getEntries} must be divisible by slot-0 bank entries ${firstBank.getEntries}"
)
- }
- require(shared.getEntries > 0, s"tile ${tile.getPath}: shared entries must be > 0")
- require(
- shared.getEntries % firstBank.getEntries == 0,
- s"tile ${tile.getPath}: shared entries ${shared.getEntries} must be divisible by slot-0 bank entries ${firstBank.getEntries}"
- )
- }
+ shared.getEntries / firstBank.getEntries
+ } else 0
val privateDCache =
if (!tile.hasPrivateDcache || !tile.getPrivateDcache.getEnable) None
else {
@@ -116,7 +117,7 @@ object ChipLoader {
}
val tileCores = indices.map { idx =>
- parseCore(cores(idx), tileParam, shared, virtualBankCount, nCores, repo)
+ parseCore(cores(idx), tileParam, shared, sharedBankNum, virtualBankCount, nCores, repo)
}
TileTopology(tileParam, tileCores, privateDCache)
}
@@ -125,6 +126,7 @@ object ChipLoader {
core: CoreInstance,
tile: TileParam,
shared: SharedMemConfig,
+ sharedBankNum: Int,
virtualBankCount: Int,
nCores: Int,
repo: Path
@@ -133,7 +135,7 @@ object ChipLoader {
val cpu = core.getCpu
val kind = cpu.getKind
kind match {
- case "rocket" => parseRocketCoreSlot(core, tile, shared, virtualBankCount, nCores, repo)
+ case "rocket" => parseRocketCoreSlot(core, tile, shared, sharedBankNum, virtualBankCount, nCores, repo)
case "boom" =>
if (core.getBalldomain.getBallNum > 0) {
throw new RuntimeException(s"core ${core.getPkg}: kind=boom forbids balldomain")
@@ -151,6 +153,7 @@ object ChipLoader {
core: CoreInstance,
tile: TileParam,
shared: SharedMemConfig,
+ sharedBankNum: Int,
virtualBankCount: Int,
nCores: Int,
repo: Path
@@ -192,7 +195,7 @@ object ChipLoader {
frontend = parseFrontend(core.getFrontend),
gpDomain = parseGpDomain(core.getGpDomain),
tile = tile,
- memDomain = parseMemDomain(core.getMem, shared, virtualBankCount, nCores)
+ memDomain = parseMemDomain(core.getMem, shared, sharedBankNum, virtualBankCount, nCores)
)
RocketTileCore(rocket, Some(buckyball))
}
@@ -220,6 +223,7 @@ object ChipLoader {
private def parseMemDomain(
mem: MemDomainConfig,
shared: SharedMemConfig,
+ sharedBankNum: Int,
virtualBankCount: Int,
nCores: Int
): MemDomainParam = {
@@ -236,6 +240,7 @@ object ChipLoader {
virtualBankCount = virtualBankCount,
sharedEnable = shared.getEnable,
sharedEntries = shared.getEntries,
+ sharedBankNum = sharedBankNum,
sharedInputChannels = shared.getInputChannels,
sharedDefaultGroupCount = shared.getDefaultGroupCount,
nCores = nCores,
diff --git a/arch/src/main/scala/framework/system/configloader/Topology.scala b/arch/src/main/scala/framework/system/configloader/Topology.scala
index 28b6d2bd..d1cfbc29 100644
--- a/arch/src/main/scala/framework/system/configloader/Topology.scala
+++ b/arch/src/main/scala/framework/system/configloader/Topology.scala
@@ -6,13 +6,6 @@ import framework.system.core.boom.configs.BoomCpuParam
import framework.system.tile.configs.TileParam
import framework.top.GlobalConfig
-/** Loader-private bundle of tile-shared memory fields. */
-private[configloader] case class SharedMemFields(
- sharedEnable: Boolean,
- sharedEntries: Int,
- sharedInputChannels: Int,
- sharedDefaultGroupCount: Int)
-
/** Top-level example topology loaded from chip.pb. */
case class ExampleTopology(tiles: Seq[TileTopology])
diff --git a/bb-tests/workloads/CMakeLists.txt b/bb-tests/workloads/CMakeLists.txt
index 57cf8971..a1fd342f 100644
--- a/bb-tests/workloads/CMakeLists.txt
+++ b/bb-tests/workloads/CMakeLists.txt
@@ -244,6 +244,7 @@ function(add_buckyball_rushb_native TARGET_NAME)
if(RUSHB_BACKEND STREQUAL "bemu")
set(RUSHB_LIBRARY ${BUCKYBALL_RUSHB_BEMU_LIBRARY})
set(RUSHB_LIBRARY_NAME bebop_bemu)
+ set(RUSHB_BACKEND_DEFINE -DBUCKYBALL_RUSHB_BEMU)
set(RUSHB_BUILD_RUNTIME
COMMAND ${CMAKE_COMMAND} -E env
--unset=CC --unset=CXX
@@ -253,6 +254,7 @@ function(add_buckyball_rushb_native TARGET_NAME)
else()
set(RUSHB_LIBRARY ${BUCKYBALL_RUSHB_VERILATOR_LIBRARY})
set(RUSHB_LIBRARY_NAME bebop_verilator)
+ set(RUSHB_BACKEND_DEFINE -DBUCKYBALL_RUSHB_VERILATOR)
set(RUSHB_BUILD_RUNTIME)
set(RUSHB_RUNTIME_DEPENDENCY ${BUCKYBALL_RUSHB_VERILATOR_LIBRARY})
endif()
@@ -297,6 +299,7 @@ function(add_buckyball_rushb_native TARGET_NAME)
OUTPUT ${RUSHB_BINARY} ${RUSHB_INSTALLED} ${RUSHB_SYNCED}
COMMAND ${CMAKE_COMMAND} -E make_directory ${RUSHB_BUILD_DIR}
COMMAND ${RUSHB_COMPILER} -no-pie ${RUSHB_STANDARD} -O2 -DBUCKYBALL_RUSHB
+ ${RUSHB_BACKEND_DEFINE}
-DBUCKYBALL_RUSHB_CORE_ID=${ARG_CORE_ID}
${RUSHB_INCLUDE_ARGS}
${ARG_SOURCES} ${BUCKYBALL_REPO_ROOT}/compiler/lib/RushBRuntime.c
diff --git a/bbdev b/bbdev
index f636bdf6..f8a97b13 160000
--- a/bbdev
+++ b/bbdev
@@ -1 +1 @@
-Subproject commit f636bdf675d852a1340304c34111b5d0508ceffe
+Subproject commit f8a97b13f6458a37a54382d3e4e05ea4af40f47e
diff --git a/bebop b/bebop
index cb3b763f..e3fe25f1 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit cb3b763fba83572bab67956012736e6e9689b6b7
+Subproject commit e3fe25f1f7f64b16a43d458f258b6478ad7e0587
diff --git a/compiler/lib/RushBRuntime.c b/compiler/lib/RushBRuntime.c
index d1f83bf2..28710989 100644
--- a/compiler/lib/RushBRuntime.c
+++ b/compiler/lib/RushBRuntime.c
@@ -1,5 +1,54 @@
#include
+#if defined(BUCKYBALL_RUSHB_BEMU)
+#define RUSHB_BACKEND(name) bemu_##name
+#elif defined(BUCKYBALL_RUSHB_VERILATOR)
+#define RUSHB_BACKEND(name) verilator_##name
+#else
+#error "RushB backend is not selected"
+#endif
+
+extern void RUSHB_BACKEND(rushb_init)(void);
+extern void RUSHB_BACKEND(rushb_destroy)(void);
+extern void RUSHB_BACKEND(rushb_mset)(uint32_t core_id, uint64_t xs1,
+ uint64_t xs2);
+extern void RUSHB_BACKEND(rushb_mvin)(uint32_t core_id, uint64_t xs1,
+ uint64_t packed_xs2,
+ const void *host_ptr);
+extern void RUSHB_BACKEND(rushb_mvin_mmio)(uint32_t core_id, uint64_t xs1,
+ uint64_t packed_xs2,
+ const void *host_ptr);
+extern void RUSHB_BACKEND(rushb_mvout)(uint32_t core_id, uint64_t xs1,
+ uint64_t packed_xs2, void *host_ptr);
+extern void RUSHB_BACKEND(rushb_custom)(uint32_t core_id, uint64_t xs1,
+ uint64_t xs2, uint32_t funct7);
+extern uint64_t RUSHB_BACKEND(rushb_cycles)(uint32_t core_id);
+
+void rushb_init(void) { RUSHB_BACKEND(rushb_init)(); }
+void rushb_destroy(void) { RUSHB_BACKEND(rushb_destroy)(); }
+void rushb_mset(uint32_t core_id, uint64_t xs1, uint64_t xs2) {
+ RUSHB_BACKEND(rushb_mset)(core_id, xs1, xs2);
+}
+void rushb_mvin(uint32_t core_id, uint64_t xs1, uint64_t packed_xs2,
+ const void *host_ptr) {
+ RUSHB_BACKEND(rushb_mvin)(core_id, xs1, packed_xs2, host_ptr);
+}
+void rushb_mvin_mmio(uint32_t core_id, uint64_t xs1, uint64_t packed_xs2,
+ const void *host_ptr) {
+ RUSHB_BACKEND(rushb_mvin_mmio)(core_id, xs1, packed_xs2, host_ptr);
+}
+void rushb_mvout(uint32_t core_id, uint64_t xs1, uint64_t packed_xs2,
+ void *host_ptr) {
+ RUSHB_BACKEND(rushb_mvout)(core_id, xs1, packed_xs2, host_ptr);
+}
+void rushb_custom(uint32_t core_id, uint64_t xs1, uint64_t xs2,
+ uint32_t funct7) {
+ RUSHB_BACKEND(rushb_custom)(core_id, xs1, xs2, funct7);
+}
+uint64_t rushb_cycles(uint32_t core_id) {
+ return RUSHB_BACKEND(rushb_cycles)(core_id);
+}
+
static void __attribute__((constructor)) rushb_runtime_init(void) {
rushb_init();
}
diff --git a/examples/balls/gemmini/emu/src/loop_micro_ops.rs b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
index 9ff84641..2363ff88 100644
--- a/examples/balls/gemmini/emu/src/loop_micro_ops.rs
+++ b/examples/balls/gemmini/emu/src/loop_micro_ops.rs
@@ -1,16 +1,14 @@
use super::decode;
-use super::instruction::ExecContext;
+use super::f53_gemmini_preload::GemminiPreload;
+use super::f66_gemmini_compute_preloaded::GemminiComputePreloaded;
+use super::f67_gemmini_compute_accumulated::GemminiComputeAccumulated;
+use super::instruction::{BallInstruction, ExecContext};
const FUNCT_MVOUT: u32 = 16;
const FUNCT_MSET: u32 = 32;
const FUNCT_MVIN: u32 = 33;
const MAX_DMA_STRIDE: u64 = (1 << 19) - 1;
-fn ball_funct(mnemonic: &str) -> u32 {
- crate::config::ball_domain::funct_for_mnemonic(mnemonic)
- .unwrap_or_else(|| panic!("Gemmini mnemonic {mnemonic} is not declared in Core ballISA"))
-}
-
fn execute(funct: u32, xs1: u64, xs2: u64, ctx: &mut ExecContext) {
decode::execute_known(funct, xs1, xs2, ctx)
.unwrap_or_else(|| panic!("Gemmini loop emitted unsupported micro-op funct7={funct}"));
@@ -67,12 +65,7 @@ pub fn mvout(ctx: &mut ExecContext, bank: u64, addr: u64, iter: u64, stride: u64
}
pub fn preload(ctx: &mut ExecContext, source: u64, output: u64, iter: u64) {
- execute(
- ball_funct("GEMMINI_PRELOAD"),
- banks(source, 0, output, iter),
- 1,
- ctx,
- );
+ GemminiPreload::exec(banks(source, 0, output, iter), 1, ctx);
}
pub fn compute(
@@ -85,14 +78,14 @@ pub fn compute(
zero_op2: bool,
zero_op1_tail: bool,
) {
- let funct = if accumulated {
- ball_funct("GEMMINI_COMPUTE_ACCUMULATED")
- } else {
- ball_funct("GEMMINI_COMPUTE_PRELOADED")
- };
let mode = if accumulated { 3 } else { 2 };
let xs2 = mode | ((zero_op2 as u64) << 4) | ((zero_op1_tail as u64) << 5);
- execute(funct, banks(op1, op2, output, iter), xs2, ctx);
+ let xs1 = banks(op1, op2, output, iter);
+ if accumulated {
+ GemminiComputeAccumulated::exec(xs1, xs2, ctx);
+ } else {
+ GemminiComputePreloaded::exec(xs1, xs2, ctx);
+ }
}
pub fn free_after_hash(ctx: &mut ExecContext, bank: u64) {
diff --git a/examples/chips/goban/emu/Cargo.lock b/examples/chips/goban/emu/Cargo.lock
index 462490dc..e197405d 100644
--- a/examples/chips/goban/emu/Cargo.lock
+++ b/examples/chips/goban/emu/Cargo.lock
@@ -104,7 +104,6 @@ dependencies = [
"serde",
"serde_json",
"snafu",
- "xxhash-rust",
]
[[package]]
@@ -113,8 +112,10 @@ version = "0.1.0"
dependencies = [
"bebop-bank-hash",
"bebop-bemu-profile",
+ "bebop-clint",
"bebop-dtb",
"bebop-elf",
+ "bebop-plic",
"bebop-rushb",
"bebop-syscall",
"bebop-uart",
@@ -145,14 +146,26 @@ dependencies = [
"walkdir",
]
+[[package]]
+name = "bebop-clint"
+version = "0.1.0"
+
[[package]]
name = "bebop-dtb"
version = "0.1.0"
+dependencies = [
+ "bebop-clint",
+ "bebop-plic",
+]
[[package]]
name = "bebop-elf"
version = "0.1.0"
+[[package]]
+name = "bebop-plic"
+version = "0.1.0"
+
[[package]]
name = "bebop-rushb"
version = "0.1.0"
@@ -1037,12 +1050,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "xxhash-rust"
-version = "0.8.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6"
-
[[package]]
name = "zmij"
version = "1.0.23"
diff --git a/examples/chips/goban/emu/src/main.rs b/examples/chips/goban/emu/src/main.rs
index 39ef1cbe..dfb46a43 100644
--- a/examples/chips/goban/emu/src/main.rs
+++ b/examples/chips/goban/emu/src/main.rs
@@ -231,7 +231,7 @@ fn run_core(
bemu.stop(exit_code.load(Ordering::Acquire));
break;
}
- if let Err(error) = bemu.step() {
+ if let Err(error) = bemu.step(1) {
exit_code.store(1, Ordering::Release);
done.store(true, Ordering::Release);
memory.abort_barrier();
diff --git a/examples/chips/multi-rocket/emu/src/main.rs b/examples/chips/multi-rocket/emu/src/main.rs
index 175e089d..aea42b9f 100644
--- a/examples/chips/multi-rocket/emu/src/main.rs
+++ b/examples/chips/multi-rocket/emu/src/main.rs
@@ -1,5 +1,5 @@
-use clap::Parser;
use bebop_bemu::{tile_topology, BemuInstance, SharedMemory, TraceConfig};
+use clap::Parser;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
use std::sync::{mpsc, Arc, Condvar, Mutex};
@@ -38,9 +38,15 @@ impl StartGate {
}
fn wait(&self) -> Result<(), String> {
- let mut result = self.result.lock().map_err(|_| "BEMU start gate poisoned".to_string())?;
+ let mut result = self
+ .result
+ .lock()
+ .map_err(|_| "BEMU start gate poisoned".to_string())?;
while result.is_none() {
- result = self.ready.wait(result).map_err(|_| "BEMU start gate poisoned".to_string())?;
+ result = self
+ .ready
+ .wait(result)
+ .map_err(|_| "BEMU start gate poisoned".to_string())?;
}
result.as_ref().expect("BEMU start gate was set").clone()
}
@@ -129,7 +135,10 @@ fn run(args: Args) -> Result<(), String> {
let mut preparation_error = None;
for _ in 0..workers.len() {
- if let Err(error) = prepared_rx.recv().map_err(|_| "Core worker exited before initialization".to_string())? {
+ if let Err(error) = prepared_rx
+ .recv()
+ .map_err(|_| "Core worker exited before initialization".to_string())?
+ {
preparation_error.get_or_insert(error);
}
}
@@ -172,7 +181,9 @@ fn run_core(
"[INFO] starting Core worker hart={hart_id} core={core_name} core_index={core_index}"
);
let prepared_bemu = (|| {
- let _turn = schedule.lock().map_err(|_| "BEMU scheduler poisoned".to_string())?;
+ let _turn = schedule
+ .lock()
+ .map_err(|_| "BEMU scheduler poisoned".to_string())?;
let mut bemu = BemuInstance::new_with_core_hart(
log_dir,
TraceConfig::new(false, false),
@@ -203,12 +214,14 @@ fn run_core(
loop {
let barrier_hit = {
- let _turn = schedule.lock().map_err(|_| "BEMU scheduler poisoned".to_string())?;
+ let _turn = schedule
+ .lock()
+ .map_err(|_| "BEMU scheduler poisoned".to_string())?;
if done.load(Ordering::Acquire) {
bemu.stop(exit_code.load(Ordering::Acquire));
break;
}
- if let Err(error) = bemu.step() {
+ if let Err(error) = bemu.step(1) {
exit_code.store(1, Ordering::Release);
done.store(true, Ordering::Release);
memory.abort_barrier();
diff --git a/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala b/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
index 145798c8..3c1bab49 100644
--- a/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
+++ b/examples/chips/poly/arch/src/main/scala/sims/verilator/TargetConfigs.scala
@@ -1,13 +1,10 @@
package sims.verilator
-import org.chipsalliance.cde.config.{Config, Parameters}
+import org.chipsalliance.cde.config.Config
class BuckyballPolyVerilatorConfig
extends Config(
- (if (sys.env.get("CI").contains("true"))
- new freechips.rocketchip.subsystem.WithoutTLMonitors
- else
- new Config(Parameters.empty)) ++
+ new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new BBSimConfig(maxHarts = 20) ++
new WithCustomBootROM ++
new examples.poly.BuckyballPolyConfig
From 0418764d230a4c2862ab8237012130bb67da85fa Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 16:07:58 +0800
Subject: [PATCH 35/36] fix: refactor state management in smatmul and goban
examples for muti-core diff
---
.../framework/frontend/globalrs/GlobalROB.scala | 3 +--
bebop | 2 +-
examples/balls/smatmul/emu/src/smatmul.rs | 17 +++++++++++------
examples/chips/goban/emu/src/main.rs | 2 +-
examples/chips/poly/emu/src/main.rs | 2 +-
5 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
index 21bb4c16..67907f48 100644
--- a/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
+++ b/arch/src/main/scala/framework/frontend/globalrs/GlobalROB.scala
@@ -318,8 +318,7 @@ class GlobalROB(val b: GlobalConfig) extends Module {
val physical = Mux1H(matches, io.bank_hashes.get)
def rotateLeft(value: UInt, amount: Int): UInt = Cat(value(31 - amount, 0), value(31, 32 - amount))
- val mapping = rotateLeft(physical.groupId, 7) ^ rotateLeft(physical.pbankId, 17)
- val mixed = physical.statusHash ^ mapping ^ "h9e3779b9".U
+ val mixed = physical.statusHash ^ rotateLeft(physical.groupId, 7) ^ "h9e3779b9".U
val nextHash = rotateLeft(currentHash, 5) ^ mixed ^ rotateLeft(mixed, 13)
when(collecting) {
diff --git a/bebop b/bebop
index e3fe25f1..6d027b72 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit e3fe25f1f7f64b16a43d458f258b6478ad7e0587
+Subproject commit 6d027b728a94b85ceaff154c849ba2a16422c2ff
diff --git a/examples/balls/smatmul/emu/src/smatmul.rs b/examples/balls/smatmul/emu/src/smatmul.rs
index 2bde413b..e4152858 100644
--- a/examples/balls/smatmul/emu/src/smatmul.rs
+++ b/examples/balls/smatmul/emu/src/smatmul.rs
@@ -2,6 +2,7 @@ use super::super::bank::{bank_lines, bank_row_bytes};
use super::decode::{pbank, rs1_b0, rs1_b1, rs1_b2, rs1_iter};
use super::instruction::ExecContext;
use std::cell::RefCell;
+use std::collections::HashMap;
const BALL_CLASS: &str = "examples.balls.smatmul.SMatMulBall";
@@ -23,7 +24,7 @@ struct Chain {
}
thread_local! {
- static STATE: RefCell = RefCell::new(State::default());
+ static STATES: RefCell> = RefCell::new(HashMap::new());
}
fn read_i32(bank: &[u8], row: usize, lane: usize) -> i32 {
@@ -50,8 +51,9 @@ pub(crate) fn exec_bias(xs1: u64, xs2: u64, ctx: &mut ExecContext) -> u64 {
bias[group * 4 + lane] = read_i32(&ctx.banks[physical], input_base + group, lane);
}
}
- STATE.with(|state| {
- let mut state = state.borrow_mut();
+ STATES.with(|states| {
+ let mut states = states.borrow_mut();
+ let state = states.entry(ctx.hart_id).or_default();
if state.chain.is_some() {
panic!("smatmul_bias: cannot replace bias during an accumulation chain");
}
@@ -100,8 +102,9 @@ pub(crate) fn exec_smatmul(xs1: u64, xs2: u64, ctx: &mut ExecContext) -> u64 {
panic!("smatmul: bank footprint exceeds bank depth");
}
- let mut chain = STATE.with(|state| {
- let mut state = state.borrow_mut();
+ let mut chain = STATES.with(|states| {
+ let mut states = states.borrow_mut();
+ let state = states.entry(ctx.hart_id).or_default();
if first {
if state.chain.is_some() {
panic!("smatmul: first block issued while another chain is live");
@@ -179,7 +182,9 @@ pub(crate) fn exec_smatmul(xs1: u64, xs2: u64, ctx: &mut ExecContext) -> u64 {
}
}
} else {
- STATE.with(|state| state.borrow_mut().chain = Some(chain));
+ STATES.with(|states| {
+ states.borrow_mut().entry(ctx.hart_id).or_default().chain = Some(chain);
+ });
}
0
}
diff --git a/examples/chips/goban/emu/src/main.rs b/examples/chips/goban/emu/src/main.rs
index dfb46a43..dbb8c2f0 100644
--- a/examples/chips/goban/emu/src/main.rs
+++ b/examples/chips/goban/emu/src/main.rs
@@ -237,7 +237,7 @@ fn run_core(
memory.abort_barrier();
return Err(error.to_string());
}
- bemu.barrier_hit()
+ bemu.take_barrier()
};
if barrier_hit {
memory.wait_barrier(local_id);
diff --git a/examples/chips/poly/emu/src/main.rs b/examples/chips/poly/emu/src/main.rs
index b94a544e..8c83f351 100644
--- a/examples/chips/poly/emu/src/main.rs
+++ b/examples/chips/poly/emu/src/main.rs
@@ -237,7 +237,7 @@ fn run_core(
memory.abort_barrier();
return Err(error.to_string());
}
- bemu.barrier_hit()
+ bemu.take_barrier()
};
if barrier_hit {
memory.wait_barrier(local_id);
From 31e96473d9d94dd2960a4b85aa0feaccb7b1634b Mon Sep 17 00:00:00 2001
From: shirohasuki
Date: Tue, 22 Sep 2026 17:24:46 +0800
Subject: [PATCH 36/36] fix: removing unused synchronization structures in
Goban and Poly
---
bebop | 2 +-
examples/chips/goban/emu/src/main.rs | 222 ++++-----------------------
examples/chips/poly/emu/src/main.rs | 220 ++++----------------------
3 files changed, 65 insertions(+), 379 deletions(-)
diff --git a/bebop b/bebop
index 6d027b72..a9f30755 160000
--- a/bebop
+++ b/bebop
@@ -1 +1 @@
-Subproject commit 6d027b728a94b85ceaff154c849ba2a16422c2ff
+Subproject commit a9f30755fc5fd81f8e35458d7fd6000674386870
diff --git a/examples/chips/goban/emu/src/main.rs b/examples/chips/goban/emu/src/main.rs
index dbb8c2f0..ff846a96 100644
--- a/examples/chips/goban/emu/src/main.rs
+++ b/examples/chips/goban/emu/src/main.rs
@@ -1,15 +1,12 @@
use bebop_bemu::{tile_topology, BemuInstance, SharedMemory, TraceConfig};
use clap::Parser;
use std::path::{Path, PathBuf};
-use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
-use std::sync::{mpsc, Arc, Condvar, Mutex};
-use std::thread;
+use std::sync::Arc;
const DRAM_SIZE: usize = 1 << 30;
#[derive(Parser, Debug)]
struct Args {
- /// Tile index in the chip bundle.
#[arg(long, default_value_t = 0)]
tile_index: usize,
#[arg(long)]
@@ -28,39 +25,6 @@ struct Args {
mtrace: bool,
}
-struct StartGate {
- result: Mutex