Skip to content

Commit 212c7ee

Browse files
committed
Add configurable BHT history parameters via CSR
1 parent 8f1e33b commit 212c7ee

5 files changed

Lines changed: 33 additions & 8 deletions

File tree

src/main/scala/rocket/BTB.scala

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,26 @@ class BHTResp(implicit p: Parameters) extends BtbBundle()(p) {
7272
// - each counter corresponds with the address of the fetch packet ("fetch pc").
7373
// - updated when a branch resolves (and BTB was a hit for that branch).
7474
// The updating branch must provide its "fetch pc".
75-
class BHT(params: BHTParams)(implicit val p: Parameters) extends HasCoreParameters {
75+
class BHT(params: BHTParams, historyLengthConfig: UInt, historyBitsConfig: UInt)(implicit val p: Parameters) extends HasCoreParameters {
7676
def index(addr: UInt, history: UInt) = {
77-
def hashHistory(hist: UInt) = if (params.historyLength == params.historyBits) hist else {
78-
val k = math.sqrt(3)/2
79-
val i = BigDecimal(k * math.pow(2, params.historyLength)).toBigInt
80-
(i.U * hist)(params.historyLength-1, params.historyLength-params.historyBits)
77+
def hashHistory(hist: UInt) = {
78+
Mux(historyBitsConfig >= historyLengthConfig,
79+
hist,
80+
{
81+
val k = math.sqrt(3)/2
82+
val i = (BigDecimal(k * math.pow(2, params.historyLength)).toBigInt.U) >> (params.historyLength.U - historyLengthConfig)
83+
val product = i * hist
84+
(product >> (historyLengthConfig - historyBitsConfig)) & ((1.U << historyLengthConfig) - 1.U)
85+
}
86+
)
8187
}
8288
def hashAddr(addr: UInt) = {
8389
val hi = addr >> log2Ceil(fetchBytes)
8490
hi(log2Ceil(params.nEntries)-1, 0) ^ (hi >> log2Ceil(params.nEntries))(1, 0)
8591
}
86-
hashAddr(addr) ^ (hashHistory(history) << (log2Up(params.nEntries) - params.historyBits))
92+
val slicedInputHistory = history >> (params.historyLength.U - historyLengthConfig)
93+
val hashValue = hashHistory(slicedInputHistory)
94+
hashAddr(addr) ^ (hashValue << (log2Up(params.nEntries).U - historyBitsConfig))
8795
}
8896
def get(addr: UInt): BHTResp = {
8997
val res = Wire(new BHTResp)
@@ -114,6 +122,8 @@ class BHT(params: BHTParams)(implicit val p: Parameters) extends HasCoreParamete
114122
private val table = Mem(params.nEntries, UInt(params.counterLength.W))
115123
val history = RegInit(0.U(params.historyLength.W))
116124

125+
val slicedHistory = history >> (params.historyLength.U - historyLengthConfig)
126+
117127
private val reset_waddr = RegInit(0.U((params.nEntries.log2+1).W))
118128
private val resetting = !reset_waddr(params.nEntries.log2)
119129
private val wen = WireInit(resetting)
@@ -192,6 +202,8 @@ class BTB(implicit p: Parameters) extends BtbModule {
192202
val ras_update = Flipped(Valid(new RASUpdate))
193203
val ras_head = Valid(UInt(vaddrBits.W))
194204
val flush = Input(Bool())
205+
val historyLengthConfig = Input(UInt(4.W))
206+
val historyBitsConfig = Input(UInt(4.W))
195207
})
196208

197209
val idxs = Reg(Vec(entries, UInt((matchBits - log2Up(coreInstBytes)).W)))
@@ -299,7 +311,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
299311
}
300312

301313
if (btbParams.bhtParams.nonEmpty) {
302-
val bht = new BHT(btbParams.bhtParams.get)
314+
val bht = new BHT(btbParams.bhtParams.get, io.historyLengthConfig, io.historyBitsConfig)
303315
val isBranch = (idxHit & cfiType.map(_ === CFIType.branch).asUInt).orR
304316
val res = bht.get(io.req.bits.addr)
305317
when (io.bht_advance.valid) {

src/main/scala/rocket/CSR.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,17 @@ class CSRFile(
797797
require(!read_mapping.contains(csr.id))
798798
val reg = csr.init.map(init => RegInit(init.U(xLen.W))).getOrElse(Reg(UInt(xLen.W)))
799799
val read = io.rw.cmd =/= CSR.N && io.rw.addr === csr.id.U
800+
val write = io.rw.cmd.isOneOf(CSR.W, CSR.S, CSR.C) && io.rw.addr === csr.id.U
800801
csr_io.ren := read
802+
csr_io.wen := write
801803
when (read && csr_io.stall) { io.rw_stall := true.B }
804+
// Handle writes for writable CSRs (mask != 0)
805+
if (csr.mask != 0) {
806+
when (write) {
807+
val wdata = readModifyWriteCSR(io.rw.cmd, reg, io.rw.wdata)
808+
reg := wdata & csr.mask.U
809+
}
810+
}
802811
read_mapping += csr.id -> reg
803812
reg
804813
}

src/main/scala/rocket/Frontend.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
218218
val force_taken = io.ptw.customCSRs.bpmStatic
219219
when (io.ptw.customCSRs.flushBTB) { btb.io.flush := true.B }
220220
when (force_taken) { btb.io.bht_update.valid := false.B }
221+
btb.io.historyLengthConfig := io.ptw.customCSRs.historyLengthConfig
222+
btb.io.historyBitsConfig := io.ptw.customCSRs.historyBitsConfig
221223

222224
val s2_base_pc = ~(~s2_pc | (fetchBytes-1).U)
223225
val taken_idx = Wire(UInt())

src/main/scala/rocket/RocketCore.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ trait HasRocketCoreParameters extends HasCoreParameters {
9797

9898
class RocketCustomCSRs(implicit p: Parameters) extends CustomCSRs with HasRocketCoreParameters {
9999
override def bpmCSR = {
100-
rocketParams.branchPredictionModeCSR.option(CustomCSR(bpmCSRId, BigInt(1), Some(BigInt(0))))
100+
rocketParams.branchPredictionModeCSR.option(CustomCSR(bpmCSRId, BigInt(0x1FF), Some(BigInt(0))))
101101
}
102102

103103
private def haveDCache = tileParams.dcache.get.scratch.isEmpty

src/main/scala/tile/CustomCSRs.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class CustomCSRs(implicit p: Parameters) extends CoreBundle {
4040

4141
def flushBTB = getOrElse(bpmCSR, _.wen, false.B)
4242
def bpmStatic = getOrElse(bpmCSR, _.value(0), false.B)
43+
def historyLengthConfig = getOrElse(bpmCSR, _.value(4,1), 0.U)
44+
def historyBitsConfig = getOrElse(bpmCSR, _.value(8,5), 0.U)
4345
def disableDCacheClockGate = getOrElse(chickenCSR, _.value(0), false.B)
4446
def disableICacheClockGate = getOrElse(chickenCSR, _.value(1), false.B)
4547
def disableCoreClockGate = getOrElse(chickenCSR, _.value(2), false.B)

0 commit comments

Comments
 (0)