提交 3116c25b 编写于 作者: Y Yinan Xu

Merge remote-tracking branch 'origin/master' into opt-storeunit

......@@ -11,7 +11,7 @@ import chisel3.experimental.chiselName
trait HasBPUParameter extends HasXSParameter {
val BPUDebug = true
val EnableCFICommitLog = true
val EnbaleCFIPredLog = false
val EnbaleCFIPredLog = true
val EnableBPUTimeRecord = EnableCFICommitLog || EnbaleCFIPredLog
}
......@@ -368,6 +368,9 @@ class BPUStage3 extends BPUStage {
XSDebug(io.inFire && s3IO.predecode.mask(i), "predecode(%d): brType:%d, br:%d, jal:%d, jalr:%d, call:%d, ret:%d, RVC:%d, excType:%d\n",
i.U, p.brType, p.isBr, p.isJal, p.isJalr, p.isCall, p.isRet, p.isRVC, p.excType)
}
XSDebug(p"brs:${Binary(brs)} jals:${Binary(jals)} jalrs:${Binary(jalrs)} calls:${Binary(calls)} rets:${Binary(rets)} rvcs:${Binary(RVCs)}\n")
XSDebug(p"callIdx:${callIdx} retIdx:${retIdx}\n")
XSDebug(p"brPred:${Binary(brPred)} loopRes:${Binary(loopRes)} prevHalfTaken:${prevHalfTaken} brTakens:${Binary(brTakens)}\n")
}
if (EnbaleCFIPredLog) {
......@@ -560,14 +563,6 @@ class BPU extends BaseBPU {
s2.io.debug_hist := s2_hist
s3.io.debug_hist := s3_hist
// val s1_histPtr = RegEnable(io.in.histPtr, enable=s1_fire)
// val s2_histPtr = RegEnable(s1_histPtr, enable=s2_fire)
// val s3_histPtr = RegEnable(s2_histPtr, enable=s3_fire)
// s1.io.debug_histPtr := s1_histPtr
// s2.io.debug_histPtr := s2_histPtr
// s3.io.debug_histPtr := s3_histPtr
//**********************Stage 2****************************//
tage.io.flush := io.flush(1) // TODO: fix this
tage.io.pc.valid := s2_fire
......
......@@ -35,8 +35,8 @@ class BIM extends BasePredictor with BimParams {
val bimAddr = new TableAddr(log2Up(BimSize), BimBanks)
val bankAlignedPC = bankAligned(io.pc.bits)
val pcLatch = RegEnable(bankAlignedPC, io.pc.valid)
val if1_bankAlignedPC = bankAligned(io.pc.bits)
val if2_pc = RegEnable(if1_bankAlignedPC, io.pc.valid)
val bim = List.fill(BimBanks) {
Module(new SRAMTemplate(UInt(2.W), set = nRows, shouldReset = false, holdRead = true))
......@@ -48,34 +48,34 @@ class BIM extends BasePredictor with BimParams {
when (resetRow === (nRows-1).U) { doing_reset := false.B }
// this bank means cache bank
val startsAtOddBank = bankInGroup(bankAlignedPC)(0)
val if1_startsAtOddBank = bankInGroup(if1_bankAlignedPC)(0)
val realMask = Mux(startsAtOddBank,
val if1_realMask = Mux(if1_startsAtOddBank,
Cat(io.inMask(bankWidth-1,0), io.inMask(PredictWidth-1, bankWidth)),
io.inMask)
val isInNextRow = VecInit((0 until BimBanks).map(i => Mux(startsAtOddBank, (i < bankWidth).B, false.B)))
val if1_isInNextRow = VecInit((0 until BimBanks).map(i => Mux(if1_startsAtOddBank, (i < bankWidth).B, false.B)))
val baseRow = bimAddr.getBankIdx(bankAlignedPC)
val if1_baseRow = bimAddr.getBankIdx(if1_bankAlignedPC)
val realRow = VecInit((0 until BimBanks).map(b => Mux(isInNextRow(b), (baseRow+1.U)(log2Up(nRows)-1, 0), baseRow)))
val if1_realRow = VecInit((0 until BimBanks).map(b => Mux(if1_isInNextRow(b), (if1_baseRow+1.U)(log2Up(nRows)-1, 0), if1_baseRow)))
val realRowLatch = VecInit(realRow.map(RegEnable(_, enable=io.pc.valid)))
val if2_realRow = VecInit(if1_realRow.map(RegEnable(_, enable=io.pc.valid)))
for (b <- 0 until BimBanks) {
bim(b).io.r.req.valid := realMask(b) && io.pc.valid
bim(b).io.r.req.bits.setIdx := realRow(b)
bim(b).io.r.req.valid := if1_realMask(b) && io.pc.valid
bim(b).io.r.req.bits.setIdx := if1_realRow(b)
}
val bimRead = VecInit(bim.map(_.io.r.resp.data(0)))
val if2_bimRead = VecInit(bim.map(_.io.r.resp.data(0)))
val startsAtOddBankLatch = bankInGroup(pcLatch)(0)
val if2_startsAtOddBank = bankInGroup(if2_pc)(0)
for (b <- 0 until BimBanks) {
val realBank = (if (b < bankWidth) Mux(startsAtOddBankLatch, (b+bankWidth).U, b.U)
else Mux(startsAtOddBankLatch, (b-bankWidth).U, b.U))
val ctr = bimRead(realBank)
val realBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, (b+bankWidth).U, b.U)
else Mux(if2_startsAtOddBank, (b-bankWidth).U, b.U))
val ctr = if2_bimRead(realBank)
io.resp.ctrs(b) := ctr
io.meta.ctrs(b) := ctr
}
......
......@@ -72,9 +72,9 @@ class BTB extends BasePredictor with BTBParams{
override val io = IO(new BTBIO)
val btbAddr = new TableAddr(log2Up(BtbSize/BtbWays), BtbBanks)
val bankAlignedPC = bankAligned(io.pc.bits)
val if1_bankAlignedPC = bankAligned(io.pc.bits)
val pcLatch = RegEnable(bankAlignedPC, io.pc.valid)
val if2_pc = RegEnable(if1_bankAlignedPC, io.pc.valid)
val data = List.fill(BtbWays) {
List.fill(BtbBanks) {
......@@ -91,61 +91,61 @@ class BTB extends BasePredictor with BTBParams{
// BTB read requests
// this bank means cache bank
val startsAtOddBank = bankInGroup(bankAlignedPC)(0)
val if1_startsAtOddBank = bankInGroup(if1_bankAlignedPC)(0)
val baseBank = btbAddr.getBank(bankAlignedPC)
val if1_baseBank = btbAddr.getBank(if1_bankAlignedPC)
val realMask = Mux(startsAtOddBank,
val if1_realMask = Mux(if1_startsAtOddBank,
Cat(io.inMask(bankWidth-1,0), io.inMask(PredictWidth-1, bankWidth)),
io.inMask)
val realMaskLatch = RegEnable(realMask, io.pc.valid)
val if2_realMask = RegEnable(if1_realMask, io.pc.valid)
val isInNextRow = VecInit((0 until BtbBanks).map(i => Mux(startsAtOddBank, (i < bankWidth).B, false.B)))
val if1_isInNextRow = VecInit((0 until BtbBanks).map(i => Mux(if1_startsAtOddBank, (i < bankWidth).B, false.B)))
val baseRow = btbAddr.getBankIdx(bankAlignedPC)
val if1_baseRow = btbAddr.getBankIdx(if1_bankAlignedPC)
val nextRowStartsUp = baseRow.andR
val if1_nextRowStartsUp = if1_baseRow.andR
val realRow = VecInit((0 until BtbBanks).map(b => Mux(isInNextRow(b), (baseRow+1.U)(log2Up(nRows)-1, 0), baseRow)))
val if1_realRow = VecInit((0 until BtbBanks).map(b => Mux(if1_isInNextRow(b), (if1_baseRow+1.U)(log2Up(nRows)-1, 0), if1_baseRow)))
val realRowLatch = VecInit(realRow.map(RegEnable(_, enable=io.pc.valid)))
val if2_realRow = VecInit(if1_realRow.map(RegEnable(_, enable=io.pc.valid)))
for (w <- 0 until BtbWays) {
for (b <- 0 until BtbBanks) {
meta(w)(b).io.r.req.valid := realMask(b) && io.pc.valid
meta(w)(b).io.r.req.bits.setIdx := realRow(b)
data(w)(b).io.r.req.valid := realMask(b) && io.pc.valid
data(w)(b).io.r.req.bits.setIdx := realRow(b)
meta(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid
meta(w)(b).io.r.req.bits.setIdx := if1_realRow(b)
data(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid
data(w)(b).io.r.req.bits.setIdx := if1_realRow(b)
}
}
for (b <- 0 to 1) {
edata(b).io.r.req.valid := io.pc.valid
val row = if (b == 0) { Mux(startsAtOddBank, realRow(bankWidth), realRow(0)) }
else { Mux(startsAtOddBank, realRow(0), realRow(bankWidth))}
val row = if (b == 0) { Mux(if1_startsAtOddBank, if1_realRow(bankWidth), if1_realRow(0)) }
else { Mux(if1_startsAtOddBank, if1_realRow(0), if1_realRow(bankWidth))}
edata(b).io.r.req.bits.setIdx := row
}
// Entries read from SRAM
val metaRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => meta(w)(b).io.r.resp.data(0)))))
val dataRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => data(w)(b).io.r.resp.data(0)))))
val edataRead = VecInit((0 to 1).map(i => edata(i).io.r.resp.data(0)))
val if2_metaRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => meta(w)(b).io.r.resp.data(0)))))
val if2_dataRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => data(w)(b).io.r.resp.data(0)))))
val if2_edataRead = VecInit((0 to 1).map(i => edata(i).io.r.resp.data(0)))
val baseBankLatch = btbAddr.getBank(pcLatch)
val startsAtOddBankLatch = bankInGroup(pcLatch)(0)
val baseTag = btbAddr.getTag(pcLatch)
val if2_baseBank = btbAddr.getBank(if2_pc)
val if2_startsAtOddBank = bankInGroup(if2_pc)(0)
val if2_baseTag = btbAddr.getTag(if2_pc)
val tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(isInNextRow(b.U) && nextRowStartsUp, io.pc.valid)))
val realTags = VecInit((0 until BtbBanks).map(b => Mux(tagIncremented(b), baseTag + 1.U, baseTag)))
val if2_tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(if1_isInNextRow(b.U) && if1_nextRowStartsUp, io.pc.valid)))
val if2_realTags = VecInit((0 until BtbBanks).map(b => Mux(if2_tagIncremented(b), if2_baseTag + 1.U, if2_baseTag)))
val totalHits = VecInit((0 until BtbBanks).map( b =>
val if2_totalHits = VecInit((0 until BtbBanks).map( b =>
VecInit((0 until BtbWays).map( w =>
// This should correspond to the real mask from last valid cycle!
metaRead(w)(b).tag === realTags(b) && metaRead(w)(b).valid && realMaskLatch(b)
if2_metaRead(w)(b).tag === if2_realTags(b) && if2_metaRead(w)(b).valid && if2_realMask(b)
))
))
val bankHits = VecInit(totalHits.map(_.reduce(_||_)))
val bankHitWays = VecInit(totalHits.map(PriorityEncoder(_)))
val if2_bankHits = VecInit(if2_totalHits.map(_.reduce(_||_)))
val if2_bankHitWays = VecInit(if2_totalHits.map(PriorityEncoder(_)))
def allocWay(valids: UInt, meta_tags: UInt, req_tag: UInt) = {
......@@ -167,30 +167,30 @@ class BTB extends BasePredictor with BTBParams{
}
}
val allocWays = VecInit((0 until BtbBanks).map(b =>
allocWay(VecInit(metaRead.map(w => w(b).valid)).asUInt,
VecInit(metaRead.map(w => w(b).tag)).asUInt,
realTags(b))))
allocWay(VecInit(if2_metaRead.map(w => w(b).valid)).asUInt,
VecInit(if2_metaRead.map(w => w(b).tag)).asUInt,
if2_realTags(b))))
val writeWay = VecInit((0 until BtbBanks).map(
b => Mux(bankHits(b), bankHitWays(b), allocWays(b))
b => Mux(if2_bankHits(b), if2_bankHitWays(b), allocWays(b))
))
for (b <- 0 until BtbBanks) {
val realBank = (if (b < bankWidth) Mux(startsAtOddBankLatch, (b+bankWidth).U, b.U)
else Mux(startsAtOddBankLatch, (b-bankWidth).U, b.U))
val meta_entry = metaRead(bankHitWays(realBank))(realBank)
val data_entry = dataRead(bankHitWays(realBank))(realBank)
val edataBank = (if (b < bankWidth) Mux(startsAtOddBankLatch, 1.U, 0.U)
else Mux(startsAtOddBankLatch, 0.U, 1.U))
val realBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, (b+bankWidth).U, b.U)
else Mux(if2_startsAtOddBank, (b-bankWidth).U, b.U))
val meta_entry = if2_metaRead(if2_bankHitWays(realBank))(realBank)
val data_entry = if2_dataRead(if2_bankHitWays(realBank))(realBank)
val edataBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, 1.U, 0.U)
else Mux(if2_startsAtOddBank, 0.U, 1.U))
// Use real pc to calculate the target
io.resp.targets(b) := Mux(data_entry.extended, edataRead(edataBank), (pcLatch.asSInt + (b << 1).S + data_entry.offset).asUInt)
io.resp.hits(b) := bankHits(realBank)
io.resp.targets(b) := Mux(data_entry.extended, if2_edataRead(edataBank), (if2_pc.asSInt + (b << 1).S + data_entry.offset).asUInt)
io.resp.hits(b) := if2_bankHits(realBank)
io.resp.types(b) := meta_entry.btbType
io.resp.isRVC(b) := meta_entry.isRVC
io.meta.writeWay(b) := writeWay(realBank)
io.meta.hitJal(b) := bankHits(realBank) && meta_entry.btbType === BTBtype.J
io.meta.hitJal(b) := if2_bankHits(realBank) && meta_entry.btbType === BTBtype.J
}
def pdInfoToBTBtype(pd: PreDecodeInfo) = {
......@@ -244,35 +244,35 @@ class BTB extends BasePredictor with BTBParams{
XSDebug("isInNextRow: ")
(0 until BtbBanks).foreach(i => {
XSDebug(false, true.B, "%d ", isInNextRow(i))
XSDebug(false, true.B, "%d ", if1_isInNextRow(i))
if (i == BtbBanks-1) { XSDebug(false, true.B, "\n") }
})
val validLatch = RegNext(io.pc.valid)
XSDebug(io.pc.valid, "read: pc=0x%x, baseBank=%d, realMask=%b\n", bankAlignedPC, baseBank, realMask)
XSDebug(io.pc.valid, "read: pc=0x%x, baseBank=%d, realMask=%b\n", if1_bankAlignedPC, if1_baseBank, if1_realMask)
XSDebug(validLatch, "read_resp: pc=0x%x, readIdx=%d-------------------------------\n",
pcLatch, btbAddr.getIdx(pcLatch))
if2_pc, btbAddr.getIdx(if2_pc))
if (debug_verbose) {
for (i <- 0 until BtbBanks){
for (j <- 0 until BtbWays) {
XSDebug(validLatch, "read_resp[w=%d][b=%d][r=%d] is valid(%d) mask(%d), tag=0x%x, offset=0x%x, type=%d, isExtend=%d, isRVC=%d\n",
j.U, i.U, realRowLatch(i), metaRead(j)(i).valid, realMaskLatch(i), metaRead(j)(i).tag, dataRead(j)(i).offset, metaRead(j)(i).btbType, dataRead(j)(i).extended, metaRead(j)(i).isRVC)
j.U, i.U, if2_realRow(i), if2_metaRead(j)(i).valid, if2_realMask(i), if2_metaRead(j)(i).tag, if2_dataRead(j)(i).offset, if2_metaRead(j)(i).btbType, if2_dataRead(j)(i).extended, if2_metaRead(j)(i).isRVC)
}
}
}
// e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4)
val bankIdxInOrder = VecInit((0 until BtbBanks).map(b => (baseBankLatch +& b.U)(log2Up(BtbBanks)-1,0)))
val bankIdxInOrder = VecInit((0 until BtbBanks).map(b => (if2_baseBank +& b.U)(log2Up(BtbBanks)-1,0)))
for (i <- 0 until BtbBanks) {
val idx = bankIdxInOrder(i)
XSDebug(validLatch && bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n",
XSDebug(validLatch && if2_bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n",
i.U, idx, io.resp.targets(i), io.resp.isRVC(i), io.resp.types(i))
}
XSDebug(updateValid, "update_req: cycle=%d, pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n",
u.brInfo.debug_btb_cycle, u.pc, new_target, u.isMisPred, new_offset, new_extended, updateWay, updateBankIdx, updateRow)
for (i <- 0 until BtbBanks) {
// Conflict when not hit and allocating a valid entry
val conflict = metaRead(allocWays(i))(i).valid && !bankHits(i)
val conflict = if2_metaRead(allocWays(i))(i).valid && !if2_bankHits(i)
XSDebug(conflict, "bank(%d) is trying to allocate a valid way(%d)\n", i.U, allocWays(i))
// There is another circumstance when a branch is on its way to update while another
// branch chose the same way to udpate, then after the first branch is wrote in,
......
......@@ -159,14 +159,6 @@ class IFU extends XSModule with HasIFUConst
}
if2_predicted_gh := if2_gh.update(if2_bp.hasNotTakenBrs, if2_bp.takenOnBr)
// when (if2_fire && if2_GHInfo.shifted) {
// val if2_newPtr = if2_GHInfo.newPtr()
// updatePtr := true.B
// newPtr := if2_newPtr
// extHist(if2_newPtr) := if2_GHInfo.takenOnBr.asUInt
// }
//********************** IF3 ****************************//
val if3_valid = RegInit(init = false.B)
......@@ -361,11 +353,6 @@ class IFU extends XSModule with HasIFUConst
when (if4_redirect) {
if1_npc := if4_target
}
// val if4_newPtr = if4_GHInfo.newPtr()
// updatePtr := true.B
// newPtr := if4_newPtr
// extHist(if4_newPtr) := if4_GHInfo.takenOnBr.asUInt
// }
when (if4_fire) {
final_gh := if4_predicted_gh
......@@ -442,7 +429,7 @@ class IFU extends XSModule with HasIFUConst
bpu.io.predecode.mask := if4_pd.mask
bpu.io.predecode.lastHalf := if4_pd.lastHalf
bpu.io.predecode.pd := if4_pd.pd
bpu.io.predecode.hasLastHalfRVI := if4_pc =/= if4_pd.pc(0)
bpu.io.predecode.hasLastHalfRVI := if4_prevHalfInstrMet
bpu.io.realMask := if4_mask
bpu.io.prevHalf := if4_prevHalfInstr
......
......@@ -50,6 +50,7 @@ class RAS extends BasePredictor
}
override val io = IO(new RASIO)
override val debug = true
@chiselName
class RASStack(val rasSize: Int) extends XSModule {
......@@ -66,6 +67,11 @@ class RAS extends BasePredictor
val copy_out_mem = Output(Vec(rasSize, rasEntry()))
val copy_out_sp = Output(UInt(log2Up(rasSize).W))
})
val debugIO = IO(new Bundle{
val write_entry = Output(rasEntry())
val alloc_new = Output(Bool())
val sp = Output(UInt(log2Up(rasSize).W))
})
@chiselName
class Stack(val size: Int) extends XSModule {
val io = IO(new Bundle {
......@@ -98,9 +104,13 @@ class RAS extends BasePredictor
val alloc_new = io.new_addr =/= top_addr
stack.wen := io.push_valid || io.pop_valid && top_ctr =/= 1.U
stack.wIdx := Mux(io.pop_valid && top_ctr =/= 1.U, sp - 1.U, Mux(alloc_new, sp, sp - 1.U))
stack.wdata := Mux(io.pop_valid && top_ctr =/= 1.U,
RASEntry(top_addr, top_ctr - 1.U),
Mux(alloc_new, RASEntry(io.new_addr, 1.U), RASEntry(top_addr, top_ctr + 1.U)))
val write_addr = Mux(io.pop_valid && top_ctr =/= 1.U, top_addr, io.new_addr)
val write_ctr = Mux(io.pop_valid && top_ctr =/= 1.U, top_ctr - 1.U, Mux(alloc_new, 1.U, top_ctr + 1.U))
val write_entry = RASEntry(write_addr, write_ctr)
stack.wdata := write_entry
debugIO.write_entry := write_entry
debugIO.alloc_new := alloc_new
debugIO.sp := sp
when (io.push_valid && alloc_new) {
sp := sp + 1.U
......@@ -138,7 +148,9 @@ class RAS extends BasePredictor
// val commit_ras = Reg(Vec(RasSize, rasEntry()))
// val commit_sp = RegInit(0.U(log2Up(RasSize).W))
val spec_ras = Module(new RASStack(RasSize)).io
val spec = Module(new RASStack(RasSize))
val spec_ras = spec.io
val spec_push = WireInit(false.B)
val spec_pop = WireInit(false.B)
......@@ -153,7 +165,8 @@ class RAS extends BasePredictor
spec_push := !spec_is_full && io.callIdx.valid && io.pc.valid
spec_pop := !spec_is_empty && io.is_ret && io.pc.valid
val commit_ras = Module(new RASStack(RasSize)).io
val commit = Module(new RASStack(RasSize))
val commit_ras = commit.io
val commit_push = WireInit(false.B)
val commit_pop = WireInit(false.B)
......@@ -179,7 +192,7 @@ class RAS extends BasePredictor
spec_ras.copy_valid := copy_next
spec_ras.copy_in_mem := commit_ras.copy_out_mem
spec_ras.copy_in_sp := commit_ras.copy_out_sp
commit_ras.copy_valid := DontCare
commit_ras.copy_valid := false.B
commit_ras.copy_in_mem := DontCare
commit_ras.copy_in_sp := DontCare
......@@ -189,26 +202,28 @@ class RAS extends BasePredictor
io.branchInfo.rasToqAddr := DontCare
if (BPUDebug && debug) {
// XSDebug("----------------RAS(spec)----------------\n")
// XSDebug(" index addr ctr \n")
// for(i <- 0 until RasSize){
// XSDebug(" (%d) 0x%x %d",i.U,spec_ras(i).retAddr,spec_ras(i).ctr)
// when(i.U === spec_sp){XSDebug(false,true.B," <----sp")}
// XSDebug(false,true.B,"\n")
// }
// XSDebug("----------------RAS(commit)----------------\n")
// XSDebug(" index addr ctr \n")
// for(i <- 0 until RasSize){
// XSDebug(" (%d) 0x%x %d",i.U,commit_ras(i).retAddr,commit_ras(i).ctr)
// when(i.U === commit_sp){XSDebug(false,true.B," <----sp")}
// XSDebug(false,true.B,"\n")
// }
// XSDebug(spec_push, "(spec_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n",spec_ras_write.retAddr,spec_ras_write.ctr,sepc_alloc_new,spec_sp.asUInt)
// XSDebug(spec_pop, "(spec_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
// XSDebug(commit_push, "(commit_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n",commit_ras_write.retAddr,commit_ras_write.ctr,sepc_alloc_new,commit_sp.asUInt)
// XSDebug(commit_pop, "(commit_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
// XSDebug("copyValid:%d copyNext:%d \n",copy_valid,copy_next)
val spec_debug = spec.debugIO
val commit_debug = commit.debugIO
XSDebug("----------------RAS(spec)----------------\n")
XSDebug(" index addr ctr \n")
for(i <- 0 until RasSize){
XSDebug(" (%d) 0x%x %d",i.U,spec_ras.copy_out_mem(i).retAddr,spec_ras.copy_out_mem(i).ctr)
when(i.U === spec_ras.copy_out_sp){XSDebug(false,true.B," <----sp")}
XSDebug(false,true.B,"\n")
}
XSDebug("----------------RAS(commit)----------------\n")
XSDebug(" index addr ctr \n")
for(i <- 0 until RasSize){
XSDebug(" (%d) 0x%x %d",i.U,commit_ras.copy_out_mem(i).retAddr,commit_ras.copy_out_mem(i).ctr)
when(i.U === commit_ras.copy_out_sp){XSDebug(false,true.B," <----sp")}
XSDebug(false,true.B,"\n")
}
XSDebug(spec_push, "(spec_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n",spec_new_addr,spec_debug.write_entry.ctr,spec_debug.alloc_new,spec_debug.sp.asUInt)
XSDebug(spec_pop, "(spec_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
XSDebug(commit_push, "(commit_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n",commit_new_addr,commit_debug.write_entry.ctr,commit_debug.alloc_new,commit_debug.sp.asUInt)
XSDebug(commit_pop, "(commit_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
XSDebug("copyValid:%d copyNext:%d \n",copy_valid,copy_next)
}
......
......@@ -121,26 +121,26 @@ class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPerio
val tageEntrySz = 1 + tagLen + TageCtrBits
val bankAlignedPC = bankAligned(io.req.bits.pc)
val if2_bankAlignedPC = bankAligned(io.req.bits.pc)
// this bank means cache bank
val startsAtOddBank = bankInGroup(bankAlignedPC)(0)
val if2_startsAtOddBank = bankInGroup(if2_bankAlignedPC)(0)
// use real address to index
// val unhashed_idxes = VecInit((0 until TageBanks).map(b => ((io.req.bits.pc >> 1.U) + b.U) >> log2Up(TageBanks).U))
val unhashed_idx = Wire(Vec(2, UInt((log2Ceil(nRows)+tagLen).W)))
val if2_unhashed_idx = Wire(Vec(2, UInt((log2Ceil(nRows)+tagLen).W)))
// the first bank idx always correspond with pc
unhashed_idx(0) := io.req.bits.pc >> (1+log2Ceil(TageBanks))
if2_unhashed_idx(0) := io.req.bits.pc >> (1+log2Ceil(TageBanks))
// when pc is at odd bank, the second bank is at the next idx
unhashed_idx(1) := unhashed_idx(0) + startsAtOddBank
if2_unhashed_idx(1) := if2_unhashed_idx(0) + if2_startsAtOddBank
// val idxes_and_tags = (0 until TageBanks).map(b => compute_tag_and_hash(unhashed_idxes(b.U), io.req.bits.hist))
// val (idx, tag) = compute_tag_and_hash(unhashed_idx, io.req.bits.hist)
val idxes_and_tags = unhashed_idx.map(compute_tag_and_hash(_, io.req.bits.hist))
// val idxes = VecInit(idxes_and_tags.map(_._1))
// val tags = VecInit(idxes_and_tags.map(_._2))
// val idxes_and_tags = (0 until TageBanks).map(b => compute_tag_and_hash(if2_unhashed_idxes(b.U), io.req.bits.hist))
// val (idx, tag) = compute_tag_and_hash(if2_unhashed_idx, io.req.bits.hist)
val if2_idxes_and_tags = if2_unhashed_idx.map(compute_tag_and_hash(_, io.req.bits.hist))
// val idxes = VecInit(if2_idxes_and_tags.map(_._1))
// val tags = VecInit(if2_idxes_and_tags.map(_._2))
val idxes_latch = RegEnable(VecInit(idxes_and_tags.map(_._1)), io.req.valid)
val tags_latch = RegEnable(VecInit(idxes_and_tags.map(_._2)), io.req.valid)
// and_tags_latch = RegEnable(idxes_and_tags, enable=io.req.valid)
val if3_idxes = RegEnable(VecInit(if2_idxes_and_tags.map(_._1)), io.req.valid)
val if3_tags = RegEnable(VecInit(if2_idxes_and_tags.map(_._2)), io.req.valid)
// and_if3_tags = RegEnable(if2_idxes_and_tags, enable=io.req.valid)
// val idxLatch = RegEnable(idx, enable=io.req.valid)
// val tagLatch = RegEnable(tag, enable=io.req.valid)
......@@ -175,59 +175,59 @@ class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPerio
val lo_us = List.fill(TageBanks)(Module(new HL_Bank(nRows)))
val table = List.fill(TageBanks)(Module(new SRAMTemplate(new TageEntry, set=nRows, shouldReset=false, holdRead=true, singlePort=false)))
val hi_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
val lo_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
val table_r = WireInit(0.U.asTypeOf(Vec(TageBanks, new TageEntry)))
val if3_hi_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
val if3_lo_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
val if3_table_r = WireInit(0.U.asTypeOf(Vec(TageBanks, new TageEntry)))
val baseBank = io.req.bits.pc(log2Up(TageBanks), 1)
val baseBankLatch = RegEnable(baseBank, enable=io.req.valid)
val if2_baseBank = io.req.bits.pc(log2Up(TageBanks), 1)
val if3_baseBank = RegEnable(if2_baseBank, enable=io.req.valid)
val bankIdxInOrder = VecInit((0 until TageBanks).map(b => (baseBankLatch +& b.U)(log2Up(TageBanks)-1, 0)))
val if3_bankIdxInOrder = VecInit((0 until TageBanks).map(b => (if3_baseBank +& b.U)(log2Up(TageBanks)-1, 0)))
val realMask = Mux(startsAtOddBank,
val if2_realMask = Mux(if2_startsAtOddBank,
Cat(io.req.bits.mask(bankWidth-1,0), io.req.bits.mask(PredictWidth-1, bankWidth)),
io.req.bits.mask)
val maskLatch = RegEnable(realMask, enable=io.req.valid)
val if3_realMask = RegEnable(if2_realMask, enable=io.req.valid)
(0 until TageBanks).map(
b => {
val idxes = VecInit(idxes_and_tags.map(_._1))
val idx = (if (b < bankWidth) Mux(startsAtOddBank, idxes(1), idxes(0))
else Mux(startsAtOddBank, idxes(0), idxes(1)))
hi_us(b).io.r.req.valid := io.req.valid && realMask(b)
val idxes = VecInit(if2_idxes_and_tags.map(_._1))
val idx = (if (b < bankWidth) Mux(if2_startsAtOddBank, idxes(1), idxes(0))
else Mux(if2_startsAtOddBank, idxes(0), idxes(1)))
hi_us(b).io.r.req.valid := io.req.valid && if2_realMask(b)
hi_us(b).io.r.req.bits.setIdx := idx
lo_us(b).io.r.req.valid := io.req.valid && realMask(b)
lo_us(b).io.r.req.valid := io.req.valid && if2_realMask(b)
lo_us(b).io.r.req.bits.setIdx := idx
table(b).reset := reset.asBool
table(b).io.r.req.valid := io.req.valid && realMask(b)
table(b).io.r.req.valid := io.req.valid && if2_realMask(b)
table(b).io.r.req.bits.setIdx := idx
hi_us_r(b) := hi_us(b).io.r.resp.data
lo_us_r(b) := lo_us(b).io.r.resp.data
table_r(b) := table(b).io.r.resp.data(0)
if3_hi_us_r(b) := hi_us(b).io.r.resp.data
if3_lo_us_r(b) := lo_us(b).io.r.resp.data
if3_table_r(b) := table(b).io.r.resp.data(0)
}
)
val startsAtOddBankLatch = RegEnable(startsAtOddBank, io.req.valid)
val if3_startsAtOddBank = RegEnable(if2_startsAtOddBank, io.req.valid)
val req_rhits = VecInit((0 until TageBanks).map(b => {
val tag = (if (b < bankWidth) Mux(startsAtOddBank, tags_latch(1), tags_latch(0))
else Mux(startsAtOddBank, tags_latch(0), tags_latch(1)))
val bank = (if (b < bankWidth) Mux(startsAtOddBankLatch, (b+bankWidth).U, b.U)
else Mux(startsAtOddBankLatch, (b-bankWidth).U, b.U))
table_r(bank).valid && table_r(bank).tag === tag
val if3_req_rhits = VecInit((0 until TageBanks).map(b => {
val tag = (if (b < bankWidth) Mux(if3_startsAtOddBank, if3_tags(1), if3_tags(0))
else Mux(if3_startsAtOddBank, if3_tags(0), if3_tags(1)))
val bank = (if (b < bankWidth) Mux(if3_startsAtOddBank, (b+bankWidth).U, b.U)
else Mux(if3_startsAtOddBank, (b-bankWidth).U, b.U))
if3_table_r(bank).valid && if3_table_r(bank).tag === tag
}))
(0 until TageBanks).map(b => {
val bank = (if (b < bankWidth) Mux(startsAtOddBankLatch, (b+bankWidth).U, b.U)
else Mux(startsAtOddBankLatch, (b-bankWidth).U, b.U))
io.resp(b).valid := req_rhits(b) && maskLatch(b)
io.resp(b).bits.ctr := table_r(bank).ctr
io.resp(b).bits.u := Cat(hi_us_r(bank),lo_us_r(bank))
val bank = (if (b < bankWidth) Mux(if3_startsAtOddBank, (b+bankWidth).U, b.U)
else Mux(if3_startsAtOddBank, (b-bankWidth).U, b.U))
io.resp(b).valid := if3_req_rhits(b) && if3_realMask(b)
io.resp(b).bits.ctr := if3_table_r(bank).ctr
io.resp(b).bits.u := Cat(if3_hi_us_r(bank),if3_lo_us_r(bank))
})
......@@ -292,7 +292,7 @@ class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPerio
// when (RegNext(wrbypass_rhit)) {
// for (b <- 0 until TageBanks) {
// when (RegNext(wrbypass_rctr_hits(b.U + baseBank))) {
// io.resp(b).bits.ctr := rhit_ctrs(bankIdxInOrder(b))
// io.resp(b).bits.ctr := rhit_ctrs(if3_bankIdxInOrder(b))
// }
// }
// }
......@@ -335,17 +335,17 @@ class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPerio
val u = io.update
val b = PriorityEncoder(u.mask)
val ub = PriorityEncoder(u.uMask)
val idx = idxes_and_tags.map(_._1)
val tag = idxes_and_tags.map(_._2)
val idx = if2_idxes_and_tags.map(_._1)
val tag = if2_idxes_and_tags.map(_._2)
XSDebug(io.req.valid, "tableReq: pc=0x%x, hist=%x, idx=(%d,%d), tag=(%x,%x), baseBank=%d, mask=%b, realMask=%b\n",
io.req.bits.pc, io.req.bits.hist, idx(0), idx(1), tag(0), tag(1), baseBank, io.req.bits.mask, realMask)
io.req.bits.pc, io.req.bits.hist, idx(0), idx(1), tag(0), tag(1), if2_baseBank, io.req.bits.mask, if2_realMask)
for (i <- 0 until TageBanks) {
XSDebug(RegNext(io.req.valid) && req_rhits(i), "TageTableResp[%d]: idx=(%d,%d), hit:%d, ctr:%d, u:%d\n",
i.U, idxes_latch(0), idxes_latch(1), req_rhits(i), io.resp(i).bits.ctr, io.resp(i).bits.u)
XSDebug(RegNext(io.req.valid) && if3_req_rhits(i), "TageTableResp[%d]: idx=(%d,%d), hit:%d, ctr:%d, u:%d\n",
i.U, if3_idxes(0), if3_idxes(1), if3_req_rhits(i), io.resp(i).bits.ctr, io.resp(i).bits.u)
}
XSDebug(RegNext(io.req.valid), "TageTableResp: hits:%b, maskLatch is %b\n", req_rhits.asUInt, maskLatch)
XSDebug(RegNext(io.req.valid) && !req_rhits.reduce(_||_), "TageTableResp: no hits!\n")
XSDebug(RegNext(io.req.valid), "TageTableResp: hits:%b, maskLatch is %b\n", if3_req_rhits.asUInt, if3_realMask)
XSDebug(RegNext(io.req.valid) && !if3_req_rhits.reduce(_||_), "TageTableResp: no hits!\n")
XSDebug(io.update.mask.reduce(_||_), "update Table: pc:%x, fetchIdx:%d, hist:%x, bank:%d, taken:%d, alloc:%d, oldCtr:%d\n",
u.pc, u.fetchIdx, u.hist, b, u.taken(b), u.alloc(b), u.oldCtr(b))
......@@ -435,12 +435,12 @@ class Tage extends BaseTage {
override val debug = true
// Keep the table responses to process in s3
val resps = VecInit(tables.map(t => RegEnable(t.io.resp, enable=io.s3Fire)))
val scResps = VecInit(scTables.map(t => RegEnable(t.io.resp, enable=io.s3Fire)))
val if4_resps = RegEnable(VecInit(tables.map(t => t.io.resp)), enable=io.s3Fire)
val if4_scResps = RegEnable(VecInit(scTables.map(t => t.io.resp)), enable=io.s3Fire)
// val flushLatch = RegNext(io.flush)
val s2_bim = RegEnable(io.bim, enable=io.pc.valid) // actually it is s2Fire
val s3_bim = RegEnable(s2_bim, enable=io.s3Fire)
val if3_bim = RegEnable(io.bim, enable=io.pc.valid) // actually it is s2Fire
val if4_bim = RegEnable(if3_bim, enable=io.s3Fire)
val debug_pc_s2 = RegEnable(io.pc.bits, enable=io.pc.valid)
val debug_pc_s3 = RegEnable(debug_pc_s2, enable=io.s3Fire)
......@@ -482,37 +482,37 @@ class Tage extends BaseTage {
// access tag tables and output meta info
for (w <- 0 until TageBanks) {
val tageTaken = WireInit(s3_bim.ctrs(w)(1).asBool)
var altPred = s3_bim.ctrs(w)(1)
val finalAltPred = WireInit(s3_bim.ctrs(w)(1))
var provided = false.B
var provider = 0.U
io.resp.takens(w) := s3_bim.ctrs(w)(1)
val if4_tageTaken = WireInit(if4_bim.ctrs(w)(1).asBool)
var if4_altPred = if4_bim.ctrs(w)(1)
val if4_finalAltPred = WireInit(if4_bim.ctrs(w)(1))
var if4_provided = false.B
var if4_provider = 0.U
io.resp.takens(w) := if4_bim.ctrs(w)(1)
for (i <- 0 until TageNTables) {
val hit = resps(i)(w).valid
val ctr = resps(i)(w).bits.ctr
val hit = if4_resps(i)(w).valid
val ctr = if4_resps(i)(w).bits.ctr
when (hit) {
io.resp.takens(w) := Mux(ctr === 3.U || ctr === 4.U, altPred, ctr(2)) // Use altpred on weak taken
tageTaken := Mux(ctr === 3.U || ctr === 4.U, altPred, ctr(2))
finalAltPred := altPred
io.resp.takens(w) := Mux(ctr === 3.U || ctr === 4.U, if4_altPred, ctr(2)) // Use altpred on weak taken
if4_tageTaken := Mux(ctr === 3.U || ctr === 4.U, if4_altPred, ctr(2))
if4_finalAltPred := if4_altPred
}
provided = provided || hit // Once hit then provide
provider = Mux(hit, i.U, provider) // Use the last hit as provider
altPred = Mux(hit, ctr(2), altPred) // Save current pred as potential altpred
if4_provided = if4_provided || hit // Once hit then provide
if4_provider = Mux(hit, i.U, if4_provider) // Use the last hit as provider
if4_altPred = Mux(hit, ctr(2), if4_altPred) // Save current pred as potential altpred
}
io.resp.hits(w) := provided
io.meta(w).provider.valid := provided
io.meta(w).provider.bits := provider
io.meta(w).altDiffers := finalAltPred =/= io.resp.takens(w)
io.meta(w).providerU := resps(provider)(w).bits.u
io.meta(w).providerCtr := resps(provider)(w).bits.ctr
io.meta(w).taken := tageTaken
io.resp.hits(w) := if4_provided
io.meta(w).provider.valid := if4_provided
io.meta(w).provider.bits := if4_provider
io.meta(w).altDiffers := if4_finalAltPred =/= io.resp.takens(w)
io.meta(w).providerU := if4_resps(if4_provider)(w).bits.u
io.meta(w).providerCtr := if4_resps(if4_provider)(w).bits.ctr
io.meta(w).taken := if4_tageTaken
// Create a mask fo tables which did not hit our query, and also contain useless entries
// and also uses a longer history than the provider
val allocatableSlots = (VecInit(resps.map(r => !r(w).valid && r(w).bits.u === 0.U)).asUInt &
~(LowerMask(UIntToOH(provider), TageNTables) & Fill(TageNTables, provided.asUInt))
val allocatableSlots = (VecInit(if4_resps.map(r => !r(w).valid && r(w).bits.u === 0.U)).asUInt &
~(LowerMask(UIntToOH(if4_provider), TageNTables) & Fill(TageNTables, if4_provided.asUInt))
)
val allocLFSR = LFSR64()(TageNTables - 1, 0)
val firstEntry = PriorityEncoder(allocatableSlots)
......@@ -525,12 +525,12 @@ class Tage extends BaseTage {
scMeta := DontCare
val scTableSums = VecInit(
(0 to 1) map { i => {
// val providerCtr = resps(provider)(w).bits.ctr.zext()
// val providerCtr = if4_resps(if4_provider)(w).bits.ctr.zext()
// val pvdrCtrCentered = (((providerCtr - 4.S) << 1) + 1.S) << 3
// sum += pvdrCtrCentered
if (EnableSC) {
(0 until SCNTables) map { j =>
scTables(j).getCenteredValue(scResps(j)(w).ctr(i))
scTables(j).getCenteredValue(if4_scResps(j)(w).ctr(i))
} reduce (_+_) // TODO: rewrite with adder tree
}
else 0.S
......@@ -539,21 +539,21 @@ class Tage extends BaseTage {
)
if (EnableSC) {
scMeta.tageTaken := tageTaken
scMeta.scUsed := provided
scMeta.scPred := tageTaken
scMeta.tageTaken := if4_tageTaken
scMeta.scUsed := if4_provided
scMeta.scPred := if4_tageTaken
scMeta.sumAbs := 0.U
when (provided) {
val providerCtr = resps(provider)(w).bits.ctr.zext()
when (if4_provided) {
val providerCtr = if4_resps(if4_provider)(w).bits.ctr.zext()
val pvdrCtrCentered = ((((providerCtr - 4.S) << 1).asSInt + 1.S) << 3).asSInt
val totalSum = scTableSums(tageTaken.asUInt) + pvdrCtrCentered
val totalSum = scTableSums(if4_tageTaken.asUInt) + pvdrCtrCentered
val sumAbs = totalSum.abs().asUInt
val sumBelowThreshold = totalSum.abs.asUInt < useThreshold
val scPred = totalSum >= 0.S
scMeta.sumAbs := sumAbs
scMeta.ctrs := VecInit(scResps.map(r => r(w).ctr(tageTaken.asUInt)))
scMeta.ctrs := VecInit(if4_scResps.map(r => r(w).ctr(if4_tageTaken.asUInt)))
for (i <- 0 until SCNTables) {
XSDebug(RegNext(io.s3Fire), p"SCTable(${i.U})(${w.U}): ctr:(${scResps(i)(w).ctr(0)},${scResps(i)(w).ctr(1)})\n")
XSDebug(RegNext(io.s3Fire), p"SCTable(${i.U})(${w.U}): ctr:(${if4_scResps(i)(w).ctr(0)},${if4_scResps(i)(w).ctr(1)})\n")
}
XSDebug(RegNext(io.s3Fire), p"SC(${w.U}): pvdCtr(${providerCtr}), pvdCentred(${pvdrCtrCentered}), totalSum(${totalSum}), abs(${sumAbs}) useThres(${useThreshold}), scPred(${scPred})\n")
// Use prediction from Statistical Corrector
......@@ -664,7 +664,7 @@ class Tage extends BaseTage {
XSDebug(RegNext(io.s3Fire), "s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n",
debug_pc_s3, debug_hist_s3, io.resp.hits.asUInt, io.resp.takens.asUInt)
for (i <- 0 until TageNTables) {
XSDebug(RegNext(io.s3Fire), "TageTable(%d): valids:%b, resp_ctrs:%b, resp_us:%b\n", i.U, VecInit(resps(i).map(_.valid)).asUInt, Cat(resps(i).map(_.bits.ctr)), Cat(resps(i).map(_.bits.u)))
XSDebug(RegNext(io.s3Fire), "TageTable(%d): valids:%b, resp_ctrs:%b, resp_us:%b\n", i.U, VecInit(if4_resps(i).map(_.valid)).asUInt, Cat(if4_resps(i).map(_.bits.ctr)), Cat(if4_resps(i).map(_.bits.u)))
}
XSDebug(io.update.valid, "update: pc=%x, fetchpc=%x, cycle=%d, hist=%x, taken:%d, misPred:%d, bimctr:%d, pvdr(%d):%d, altDiff:%d, pvdrU:%d, pvdrCtr:%d, alloc(%d):%d\n",
u.pc, u.pc - (bri.fetchIdx << 1.U), bri.debug_tage_cycle, updateHist, u.taken, u.isMisPred, bri.bimCtr, m.provider.valid, m.provider.bits, m.altDiffers, m.providerU, m.providerCtr, m.allocate.valid, m.allocate.bits)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册