From 3e256439c9bc121c824360c02e08dd876c3ca409 Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Wed, 24 Sep 2014 13:04:20 -0700 Subject: [PATCH 1/9] Add abstract class Tile --- rocket/src/main/scala/tile.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index 34533e80..04c7753d 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -12,11 +12,14 @@ case object NTilePorts extends Field[Int] case object NPTWPorts extends Field[Int] case object BuildRoCC extends Field[Option[() => RoCC]] -class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { +abstract class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { val io = new Bundle { val tilelink = new TileLinkIO val host = new HTIFIO } +} + +class RocketTile(resetSignal: Bool = null) extends Tile(resetSignal) { val icache = Module(new Frontend, { case CacheName => "L1I"; case CoreName => "Rocket" }) val dcache = Module(new HellaCache, { case CacheName => "L1D" }) From b55c38cdc716a2573238f658bd9cdcb72e3b55d6 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 24 Sep 2014 22:17:28 -0700 Subject: [PATCH 2/9] Remove spurious vec consts --- rocket/src/main/scala/consts.scala | 25 ------------------------- rocket/src/main/scala/package.scala | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 464ac39b..4c601d81 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -61,28 +61,3 @@ trait ScalarOpConstants { val RA = UInt(1, 5) } - -trait VectorOpConstants { - val VEC_X = Bits("b??", 2).toUInt - val VEC_FN_N = UInt(0, 2) - val VEC_VL = UInt(1, 2) - val VEC_CFG = UInt(2, 2) - val VEC_CFGVL = UInt(3, 2) - - val VCMD_I = UInt(0, 3) - val VCMD_F = UInt(1, 3) - val VCMD_TX = UInt(2, 3) - val VCMD_TF = UInt(3, 3) - val VCMD_MX = UInt(4, 3) - val VCMD_MF = UInt(5, 3) - val VCMD_A = UInt(6, 3) - val VCMD_X = UInt(0, 3) - - val VIMM_VLEN = UInt(0, 1) - val VIMM_ALU = UInt(1, 1) - val VIMM_X = UInt(0, 1) - - val VIMM2_RS2 = UInt(0, 1) - val VIMM2_ALU = UInt(1, 1) - val VIMM2_X = UInt(0, 1) -} diff --git a/rocket/src/main/scala/package.scala b/rocket/src/main/scala/package.scala index 85a0bf11..e24c646f 100644 --- a/rocket/src/main/scala/package.scala +++ b/rocket/src/main/scala/package.scala @@ -1,8 +1,7 @@ // See LICENSE for license details. package object rocket extends - rocket.constants.ScalarOpConstants with - rocket.constants.VectorOpConstants + rocket.constants.ScalarOpConstants { val START_ADDR = 0x2000 } From 8eb64205f5f004f54f6ca99001c175ba842d93f8 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 25 Sep 2014 11:59:19 -0700 Subject: [PATCH 3/9] bug fix for nbdcache s2_data --- rocket/src/main/scala/nbdcache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index 9ed5658f..3d9bc150 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -817,7 +817,7 @@ class HellaCache extends L1HellaCacheModule { val regs = Vec.fill(rowWords){Reg(Bits(width = encDataBits))} val en1 = s1_clk_en && s1_tag_eq_way(w) for (i <- 0 until regs.size) { - val en = en1 && (Bool(i == 0 || !doNarrowRead) || s1_writeback) + val en = en1 && ((Bool(i == 0) || !Bool(doNarrowRead)) || s1_writeback) when (en) { regs(i) := data.io.resp(w) >> encDataBits*i } } s2_data(w) := regs.toBits From 868e74765697add459e3ee2577c58894aefaf20f Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Thu, 25 Sep 2014 18:52:58 -0700 Subject: [PATCH 4/9] Factored out Rocket specifics from CoreParameters - Added new RocketCoreParameters - Other cores using Rocket as a library will no longer conflict against Rocket's requires(). --- rocket/src/main/scala/core.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rocket/src/main/scala/core.scala b/rocket/src/main/scala/core.scala index f02f1424..ecb41f01 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -28,10 +28,15 @@ abstract trait CoreParameters extends UsesParameters { val coreMaxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits) if(params(FastLoadByte)) require(params(FastLoadWord)) +} + +abstract trait RocketCoreParameters extends CoreParameters +{ require(params(RetireWidth) == 1) // for now... } -abstract class CoreBundle extends Bundle with CoreParameters -abstract class CoreModule extends Module with CoreParameters + +abstract class CoreBundle extends Bundle with RocketCoreParameters +abstract class CoreModule extends Module with RocketCoreParameters class RocketIO extends Bundle { From f9178100616240ea1801a327fe5f7aaa40a90285 Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Fri, 26 Sep 2014 05:14:50 -0700 Subject: [PATCH 5/9] Removed RocketCoreParameters from use. - The nbdache (among others?) use CoreParameters, which has nothing to do with RetireWidth requirements. - This conflicts with other cores which uses nbdcache. - RocketCoreParameters may be unneccessary, and the require() check can be moved deeper into Rocket. --- rocket/src/main/scala/core.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocket/src/main/scala/core.scala b/rocket/src/main/scala/core.scala index ecb41f01..a49ca7e2 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -35,8 +35,8 @@ abstract trait RocketCoreParameters extends CoreParameters require(params(RetireWidth) == 1) // for now... } -abstract class CoreBundle extends Bundle with RocketCoreParameters -abstract class CoreModule extends Module with RocketCoreParameters +abstract class CoreBundle extends Bundle with CoreParameters +abstract class CoreModule extends Module with CoreParameters class RocketIO extends Bundle { From a71bdbbc5418d8325a45ac89e0ede1d4efb79b4e Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Fri, 19 Sep 2014 15:05:45 -0700 Subject: [PATCH 6/9] Update history register in fetch speculatively --- rocket/src/main/scala/btb.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 02ca111e..f6de407e 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -41,7 +41,9 @@ class RAS(nras: Int) { } class BHTResp extends Bundle with BTBParameters { + // TODO only carry history, not both index and history val index = UInt(width = log2Up(nBHT).max(1)) + val history = UInt(width = log2Up(nBHT).max(1)) val value = UInt(width = 2) } @@ -50,12 +52,19 @@ class BHT(nbht: Int) { def get(addr: UInt): BHTResp = { val res = new BHTResp res.index := addr(nbhtbits+1,2) ^ history + res.history := history res.value := table(res.index) + // TODO we actually want to include the final prediction result from the BTB + val taken = res.value(0) + // TODO only update history on an actual instruction fetch + history := Cat(taken, history(nbhtbits-1,1)) res } - def update(d: BHTResp, taken: Bool): Unit = { + def update(d: BHTResp, taken: Bool, mispredict: Bool): Unit = { table(d.index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) - history := Cat(taken, history(nbhtbits-1,1)) + when (mispredict) { + history := Cat(taken, d.history(nbhtbits-1,1)) + } } private val table = Mem(UInt(width = 2), nbht) @@ -197,7 +206,7 @@ class BTB extends Module with BTBParameters { if (nBHT > 0) { val bht = new BHT(nBHT) val res = bht.get(io.req) - when (update.valid && updateHit && !update.bits.isJump) { bht.update(update.bits.prediction.bits.bht, update.bits.taken) } + when (update.valid && updateHit && !update.bits.isJump) { bht.update(update.bits.prediction.bits.bht, update.bits.taken, update.bits.incorrectTarget) } when (!res.value(0) && !Mux1H(hits, isJump)) { io.resp.bits.taken := false } io.resp.bits.bht := res } From 681b43f3983bc9303db0d63a65ae7f133b22f8bf Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Fri, 26 Sep 2014 10:39:57 -0700 Subject: [PATCH 7/9] Bug fixes with global history register. - Updated in fetch speculatively. * Updates gated off by cpu.resp.fire(). * BTB direction factored into history update. - All branches update the BHT. - Each instruction carries history; index into BHT is recomputed by passing in mem_reg_pc. --- rocket/src/main/scala/btb.scala | 41 +++++++++++++++--------------- rocket/src/main/scala/icache.scala | 3 ++- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index f6de407e..7dfd15a2 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -8,7 +8,7 @@ import Node._ import uncore._ case object NBTBEntries extends Field[Int] -case object NRAS extends Field[Int] +case object NRAS extends Field[Int] abstract trait BTBParameters extends UsesParameters { val vaddrBits = params(VAddrBits) @@ -41,27 +41,26 @@ class RAS(nras: Int) { } class BHTResp extends Bundle with BTBParameters { - // TODO only carry history, not both index and history - val index = UInt(width = log2Up(nBHT).max(1)) val history = UInt(width = log2Up(nBHT).max(1)) val value = UInt(width = 2) } class BHT(nbht: Int) { - val nbhtbits = log2Up(nbht) - def get(addr: UInt): BHTResp = { + val nbhtbits = log2Up(nbht) + def get(enable: Bool, addr: UInt, btb_hit: Bool): BHTResp = { val res = new BHTResp - res.index := addr(nbhtbits+1,2) ^ history + val index = addr(nbhtbits+1,2) ^ history res.history := history - res.value := table(res.index) - // TODO we actually want to include the final prediction result from the BTB - val taken = res.value(0) - // TODO only update history on an actual instruction fetch - history := Cat(taken, history(nbhtbits-1,1)) + res.value := table(index) + val taken = res.value(0) && btb_hit + when (enable) { + history := Cat(taken, history(nbhtbits-1,1)) + } res } - def update(d: BHTResp, taken: Bool, mispredict: Bool): Unit = { - table(d.index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) + def update(addr: UInt, d: BHTResp, taken: Bool, mispredict: Bool): Unit = { + val index = addr(nbhtbits+1,2) ^ d.history + table(index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) when (mispredict) { history := Cat(taken, d.history(nbhtbits-1,1)) } @@ -93,7 +92,7 @@ class BTBResp extends Bundle with BTBParameters { // fully-associative branch target buffer class BTB extends Module with BTBParameters { val io = new Bundle { - val req = UInt(INPUT, vaddrBits) + val req = Valid(UInt(INPUT, vaddrBits)).flip val resp = Valid(new BTBResp) val update = Valid(new BTBUpdate).flip val invalidate = Bool(INPUT) @@ -125,10 +124,10 @@ class BTB extends Module with BTBParameters { } val update = Pipe(io.update) - val update_target = io.req + val update_target = io.req.bits - val pageHit = pageMatch(io.req) - val hits = tagMatch(io.req, pageHit) + val pageHit = pageMatch(io.req.bits) + val hits = tagMatch(io.req.bits, pageHit) val updatePageHit = pageMatch(update.bits.pc) val updateHits = tagMatch(update.bits.pc, updatePageHit) @@ -169,7 +168,7 @@ class BTB extends Module with BTBParameters { idxValid(waddr) := updateValid when (updateTarget) { - assert(io.req === update.bits.target, "BTB request != I$ target") + assert(io.req.bits === update.bits.target, "BTB request != I$ target") idxs(waddr) := update.bits.pc tgts(waddr) := update_target idxPages(waddr) := idxPageUpdate @@ -205,8 +204,10 @@ class BTB extends Module with BTBParameters { if (nBHT > 0) { val bht = new BHT(nBHT) - val res = bht.get(io.req) - when (update.valid && updateHit && !update.bits.isJump) { bht.update(update.bits.prediction.bits.bht, update.bits.taken, update.bits.incorrectTarget) } + val res = bht.get(io.req.valid, io.req.bits, hits.orR) + when (update.valid && !update.bits.isJump) { + bht.update(update.bits.pc, update.bits.prediction.bits.bht, update.bits.taken, update.bits.incorrectTarget) + } when (!res.value(0) && !Mux1H(hits, isJump)) { io.resp.bits.taken := false } io.resp.bits.bht := res } diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index fb2dbb0c..da1f4c85 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -85,7 +85,8 @@ class Frontend extends FrontendModule s2_valid := Bool(false) } - btb.io.req := s1_pc & SInt(-coreInstBytes) + btb.io.req.valid := io.cpu.resp.fire() + btb.io.req.bits := s1_pc & SInt(-coreInstBytes) btb.io.update := io.cpu.btb_update btb.io.invalidate := io.cpu.invalidate || io.cpu.ptw.invalidate From 8ccd07cfeb5af8e487758eb44b49e9d28277f5c4 Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Sun, 28 Sep 2014 05:16:36 -0700 Subject: [PATCH 8/9] Moved updating global history from fetch to decode. - No longer update global history in fetch stage. - Only update global history when instruction is a branch. - Does allow for the possibility of back-to-back branches to see slightly different histories on subsequent executions. --- rocket/src/main/scala/btb.scala | 27 +++++++++++++++------------ rocket/src/main/scala/icache.scala | 27 ++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 7dfd15a2..644b02ee 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -47,17 +47,16 @@ class BHTResp extends Bundle with BTBParameters { class BHT(nbht: Int) { val nbhtbits = log2Up(nbht) - def get(enable: Bool, addr: UInt, btb_hit: Bool): BHTResp = { + def get(addr: UInt): BHTResp = { val res = new BHTResp val index = addr(nbhtbits+1,2) ^ history - res.history := history res.value := table(index) - val taken = res.value(0) && btb_hit - when (enable) { - history := Cat(taken, history(nbhtbits-1,1)) - } + res.history := history res } + def updateSpeculativeHistory(taken: Bool): Unit = { + history := Cat(taken, history(nbhtbits-1,1)) + } def update(addr: UInt, d: BHTResp, taken: Bool, mispredict: Bool): Unit = { val index = addr(nbhtbits+1,2) ^ d.history table(index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) @@ -92,9 +91,10 @@ class BTBResp extends Bundle with BTBParameters { // fully-associative branch target buffer class BTB extends Module with BTBParameters { val io = new Bundle { - val req = Valid(UInt(INPUT, vaddrBits)).flip + val req = UInt(INPUT, vaddrBits) val resp = Valid(new BTBResp) val update = Valid(new BTBUpdate).flip + val decode = Valid(new Bundle{val taken = Bool()}).flip val invalidate = Bool(INPUT) } @@ -124,10 +124,10 @@ class BTB extends Module with BTBParameters { } val update = Pipe(io.update) - val update_target = io.req.bits + val update_target = io.req - val pageHit = pageMatch(io.req.bits) - val hits = tagMatch(io.req.bits, pageHit) + val pageHit = pageMatch(io.req) + val hits = tagMatch(io.req, pageHit) val updatePageHit = pageMatch(update.bits.pc) val updateHits = tagMatch(update.bits.pc, updatePageHit) @@ -168,7 +168,7 @@ class BTB extends Module with BTBParameters { idxValid(waddr) := updateValid when (updateTarget) { - assert(io.req.bits === update.bits.target, "BTB request != I$ target") + assert(io.req === update.bits.target, "BTB request != I$ target") idxs(waddr) := update.bits.pc tgts(waddr) := update_target idxPages(waddr) := idxPageUpdate @@ -204,7 +204,10 @@ class BTB extends Module with BTBParameters { if (nBHT > 0) { val bht = new BHT(nBHT) - val res = bht.get(io.req.valid, io.req.bits, hits.orR) + val res = bht.get(io.req) + when (io.decode.valid) { + bht.updateSpeculativeHistory(io.decode.bits.taken) + } when (update.valid && !update.bits.isJump) { bht.update(update.bits.pc, update.bits.prediction.bits.bht, update.bits.taken, update.bits.incorrectTarget) } diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index da1f4c85..4119683d 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -5,6 +5,7 @@ package rocket import Chisel._ import uncore._ import Util._ +import Instructions._ case object NITLBEntries extends Field[Int] case object ECCCode extends Field[Option[Code]] @@ -44,7 +45,7 @@ class Frontend extends FrontendModule val cpu = new CPUFrontendIO().flip val mem = new UncachedTileLinkIO } - + val btb = Module(new BTB) val icache = Module(new ICache) val tlb = Module(new TLB(params(NITLBEntries))) @@ -85,10 +86,12 @@ class Frontend extends FrontendModule s2_valid := Bool(false) } - btb.io.req.valid := io.cpu.resp.fire() - btb.io.req.bits := s1_pc & SInt(-coreInstBytes) + btb.io.req := s1_pc & SInt(-coreInstBytes) btb.io.update := io.cpu.btb_update btb.io.invalidate := io.cpu.invalidate || io.cpu.ptw.invalidate + btb.io.decode.valid := io.cpu.resp.valid && DecodeIsBr(io.cpu.resp.bits.data) + btb.io.decode.bits.taken := Reg(next=btb.io.resp.bits.taken) + tlb.io.ptw <> io.cpu.ptw tlb.io.req.valid := !stall && !icmiss @@ -285,3 +288,21 @@ class ICache extends FrontendModule } } } + +object DecodeIsBr { + def apply(inst: Bits): Bool = { + val signal = DecodeLogic(inst.toUInt, List(N), + Array(//JAL -> List(Y), + //JALR -> List(Y), + BEQ -> List(Y), + BNE -> List(Y), + BGE -> List(Y), + BGEU -> List(Y), + BLT -> List(Y), + BLTU -> List(Y))) + + val (is_br: Bool) :: Nil = signal + is_br + } +} + From 9cc35dee9a46dec0c906c976b2ac24d5636d8280 Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Mon, 29 Sep 2014 21:41:07 -0700 Subject: [PATCH 9/9] Returned history update to fetch. - Global history only contains branches. - Only update BHT and history on BTB hits. - Gate off speculative update on stall or icmiss. - Fixed bug where BHT updates were delayed a cycle. --- rocket/src/main/scala/btb.scala | 69 +++++++++++++++--------------- rocket/src/main/scala/icache.scala | 25 +---------- 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 644b02ee..0f1ee962 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -47,22 +47,19 @@ class BHTResp extends Bundle with BTBParameters { class BHT(nbht: Int) { val nbhtbits = log2Up(nbht) - def get(addr: UInt): BHTResp = { + def get(addr: UInt, update: Bool): BHTResp = { val res = new BHTResp val index = addr(nbhtbits+1,2) ^ history res.value := table(index) res.history := history + val taken = res.value(0) + when (update) { history := Cat(taken, history(nbhtbits-1,1)) } res } - def updateSpeculativeHistory(taken: Bool): Unit = { - history := Cat(taken, history(nbhtbits-1,1)) - } def update(addr: UInt, d: BHTResp, taken: Bool, mispredict: Bool): Unit = { val index = addr(nbhtbits+1,2) ^ d.history table(index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) - when (mispredict) { - history := Cat(taken, d.history(nbhtbits-1,1)) - } + when (mispredict) { history := Cat(taken, d.history(nbhtbits-1,1)) } } private val table = Mem(UInt(width = 2), nbht) @@ -88,13 +85,16 @@ class BTBResp extends Bundle with BTBParameters { val bht = new BHTResp } +class BTBReq extends Bundle with BTBParameters { + val addr = UInt(width = vaddrBits) +} + // fully-associative branch target buffer class BTB extends Module with BTBParameters { val io = new Bundle { - val req = UInt(INPUT, vaddrBits) + val req = Valid(new BTBReq).flip val resp = Valid(new BTBResp) val update = Valid(new BTBUpdate).flip - val decode = Valid(new Bundle{val taken = Bool()}).flip val invalidate = Bool(INPUT) } @@ -123,23 +123,23 @@ class BTB extends Module with BTBParameters { idxValid & idxMatch & idxPageMatch } - val update = Pipe(io.update) - val update_target = io.req + val r_update = Pipe(io.update) + val update_target = io.req.bits.addr - val pageHit = pageMatch(io.req) - val hits = tagMatch(io.req, pageHit) - val updatePageHit = pageMatch(update.bits.pc) - val updateHits = tagMatch(update.bits.pc, updatePageHit) + val pageHit = pageMatch(io.req.bits.addr) + val hits = tagMatch(io.req.bits.addr, pageHit) + val updatePageHit = pageMatch(r_update.bits.pc) + val updateHits = tagMatch(r_update.bits.pc, updatePageHit) - private var lfsr = LFSR16(update.valid) + private var lfsr = LFSR16(r_update.valid) def rand(width: Int) = { lfsr = lfsr(lfsr.getWidth-1,1) Random.oneHot(width, lfsr) } - val updateHit = update.bits.prediction.valid - val updateValid = update.bits.incorrectTarget || updateHit && Bool(nBHT > 0) - val updateTarget = updateValid && update.bits.incorrectTarget + val updateHit = r_update.bits.prediction.valid + val updateValid = r_update.bits.incorrectTarget || updateHit && Bool(nBHT > 0) + val updateTarget = updateValid && r_update.bits.incorrectTarget val useUpdatePageHit = updatePageHit.orR val doIdxPageRepl = updateTarget && !useUpdatePageHit @@ -148,7 +148,7 @@ class BTB extends Module with BTBParameters { val idxPageUpdate = OHToUInt(idxPageUpdateOH) val idxPageReplEn = Mux(doIdxPageRepl, idxPageRepl, UInt(0)) - val samePage = page(update.bits.pc) === page(update_target) + val samePage = page(r_update.bits.pc) === page(update_target) val usePageHit = (pageHit & ~idxPageReplEn).orR val doTgtPageRepl = updateTarget && !samePage && !usePageHit val tgtPageRepl = Mux(samePage, idxPageUpdateOH, idxPageUpdateOH(nPages-2,0) << 1 | idxPageUpdateOH(nPages-1)) @@ -157,24 +157,24 @@ class BTB extends Module with BTBParameters { val doPageRepl = doIdxPageRepl || doTgtPageRepl val pageReplEn = idxPageReplEn | tgtPageReplEn - idxPageRepl := UIntToOH(Counter(update.valid && doPageRepl, nPages)._1) + idxPageRepl := UIntToOH(Counter(r_update.valid && doPageRepl, nPages)._1) - when (update.valid && !(updateValid && !updateTarget)) { + when (r_update.valid && !(updateValid && !updateTarget)) { val nextRepl = Counter(!updateHit && updateValid, entries)._1 - val waddr = Mux(updateHit, update.bits.prediction.bits.entry, nextRepl) + val waddr = Mux(updateHit, r_update.bits.prediction.bits.entry, nextRepl) // invalidate entries if we stomp on pages they depend upon idxValid := idxValid & ~Vec.tabulate(entries)(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits idxValid(waddr) := updateValid when (updateTarget) { - assert(io.req === update.bits.target, "BTB request != I$ target") - idxs(waddr) := update.bits.pc + assert(io.req.bits.addr === r_update.bits.target, "BTB request != I$ target") + idxs(waddr) := r_update.bits.pc tgts(waddr) := update_target idxPages(waddr) := idxPageUpdate tgtPages(waddr) := tgtPageUpdate - useRAS(waddr) := update.bits.isReturn - isJump(waddr) := update.bits.isJump + useRAS(waddr) := r_update.bits.isReturn + isJump(waddr) := r_update.bits.isJump } require(nPages % 2 == 0) @@ -185,9 +185,9 @@ class BTB extends Module with BTBParameters { when (en && pageReplEn(i)) { pages(i) := data } writeBank(0, 2, Mux(idxWritesEven, doIdxPageRepl, doTgtPageRepl), - Mux(idxWritesEven, page(update.bits.pc), page(update_target))) + Mux(idxWritesEven, page(r_update.bits.pc), page(update_target))) writeBank(1, 2, Mux(idxWritesEven, doTgtPageRepl, doIdxPageRepl), - Mux(idxWritesEven, page(update_target), page(update.bits.pc))) + Mux(idxWritesEven, page(update_target), page(r_update.bits.pc))) when (doPageRepl) { pageValid := pageValid | pageReplEn } } @@ -204,12 +204,11 @@ class BTB extends Module with BTBParameters { if (nBHT > 0) { val bht = new BHT(nBHT) - val res = bht.get(io.req) - when (io.decode.valid) { - bht.updateSpeculativeHistory(io.decode.bits.taken) - } - when (update.valid && !update.bits.isJump) { - bht.update(update.bits.pc, update.bits.prediction.bits.bht, update.bits.taken, update.bits.incorrectTarget) + val res = bht.get(io.req.bits.addr, io.req.valid && hits.orR && !Mux1H(hits, isJump)) + val update_btb_hit = io.update.bits.prediction.valid + when (io.update.valid && update_btb_hit && !io.update.bits.isJump) { + bht.update(io.update.bits.pc, io.update.bits.prediction.bits.bht, + io.update.bits.taken, io.update.bits.incorrectTarget) } when (!res.value(0) && !Mux1H(hits, isJump)) { io.resp.bits.taken := false } io.resp.bits.bht := res diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index 4119683d..45327e46 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -5,7 +5,6 @@ package rocket import Chisel._ import uncore._ import Util._ -import Instructions._ case object NITLBEntries extends Field[Int] case object ECCCode extends Field[Option[Code]] @@ -86,12 +85,10 @@ class Frontend extends FrontendModule s2_valid := Bool(false) } - btb.io.req := s1_pc & SInt(-coreInstBytes) + btb.io.req.valid := !stall && !icmiss + btb.io.req.bits.addr := s1_pc & SInt(-coreInstBytes) btb.io.update := io.cpu.btb_update btb.io.invalidate := io.cpu.invalidate || io.cpu.ptw.invalidate - btb.io.decode.valid := io.cpu.resp.valid && DecodeIsBr(io.cpu.resp.bits.data) - btb.io.decode.bits.taken := Reg(next=btb.io.resp.bits.taken) - tlb.io.ptw <> io.cpu.ptw tlb.io.req.valid := !stall && !icmiss @@ -288,21 +285,3 @@ class ICache extends FrontendModule } } } - -object DecodeIsBr { - def apply(inst: Bits): Bool = { - val signal = DecodeLogic(inst.toUInt, List(N), - Array(//JAL -> List(Y), - //JALR -> List(Y), - BEQ -> List(Y), - BNE -> List(Y), - BGE -> List(Y), - BGEU -> List(Y), - BLT -> List(Y), - BLTU -> List(Y))) - - val (is_br: Bool) :: Nil = signal - is_br - } -} -