提交 016586c6 编写于 作者: Y Yinan Xu

brq: wrap data into DataModuleTemplate

上级 f6f819c2
......@@ -70,16 +70,21 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val s_idle :: s_wb :: Nil = Enum(2)
// data and state
val brQueue = Mem(BrqSize, new BrqEntry) //Reg(Vec(BrqSize, new BrqEntry))
val decodeData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, DecodeWidth))
val writebackData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, exuParameters.AluCnt + exuParameters.JmpCnt))
val ptrFlagVec = Reg(Vec(BrqSize, Bool()))
val stateQueue = RegInit(VecInit(Seq.fill(BrqSize)(s_idle)))
// queue pointers
val headPtr, tailPtr = RegInit(BrqPtr(false.B, 0.U))
val writebackPtr = RegInit(BrqPtr(false.B, 0.U))
val writebackPtr_next = WireInit(writebackPtr)
writebackPtr := writebackPtr_next
val headIdx = headPtr.value
val writebackIdx = writebackPtr.value
/**
* commit (dequeue): after ROB commits branch instructions, move headPtr forward
*/
......@@ -89,24 +94,25 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
* write back
*/
val wbValid = stateQueue(writebackIdx) === s_wb
val wbEntry = brQueue(writebackIdx)
val wbIsMisPred = wbEntry.exuOut.redirect.target =/= wbEntry.exuOut.brUpdate.pnpc
val wbEntry = Wire(new ExuOutput)
val wbIsMisPred = wbEntry.redirect.target =/= wbEntry.brUpdate.pnpc
io.redirectOut.valid := wbValid && wbIsMisPred
io.redirectOut.bits := wbEntry.exuOut.redirect
io.redirectOut.bits.brTag := BrqPtr(wbEntry.ptrFlag, writebackIdx)
io.redirectOut.bits := wbEntry.redirect
io.redirectOut.bits.brTag := BrqPtr(ptrFlagVec(writebackIdx), writebackIdx)
io.out.valid := wbValid
io.out.bits := wbEntry.exuOut
io.out.bits := wbEntry
when (wbValid) {
stateQueue(writebackIdx) := s_idle
writebackPtr := writebackPtr + 1.U
writebackPtr_next := writebackPtr + 1.U
}
val brTagRead = RegNext(Mux(io.redirect.bits.flushItself(), io.redirect.bits.brTag - 1.U, io.redirect.bits.brTag))
val brUpdateReadIdx = Mux(io.redirect.bits.flushItself(), io.redirect.bits.brTag - 1.U, io.redirect.bits.brTag)
val brUpdateReadEntry = Wire(new ExuOutput)
io.cfiInfo.valid := RegNext(io.redirect.valid || wbValid)
io.cfiInfo.bits := brQueue(brTagRead.value).exuOut.brUpdate
io.cfiInfo.bits.brTag := brTagRead
io.cfiInfo.bits := brUpdateReadEntry.brUpdate
io.cfiInfo.bits.brTag := RegNext(brUpdateReadIdx)
io.cfiInfo.bits.isReplay := RegNext(io.redirect.bits.flushItself())
io.cfiInfo.bits.isMisPred := RegNext(wbIsMisPred)
......@@ -121,19 +127,15 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
// thus, brq should not allow enqueue in the next cycle after redirect
val lastCycleRedirect = RegNext(io.redirect.valid)
val validEntries = distanceBetween(tailPtr, headPtr)
for(i <- 0 until DecodeWidth){
val offset = if (i == 0) 0.U else PopCount(io.enq.needAlloc.take(i))
val brTag = tailPtr + offset
val idx = brTag.value
val enqBrTag = VecInit((0 until DecodeWidth).map(i => tailPtr + PopCount(io.enq.needAlloc.take(i))))
io.enq.resp := enqBrTag
for (i <- 0 until DecodeWidth) {
val idx = enqBrTag(i).value
io.enq.req(i).ready := validEntries <= (BrqSize - (i + 1)).U && !lastCycleRedirect
io.enq.resp(i) := brTag
when (io.enq.req(i).fire()) {
brQueue(idx).ptrFlag := brTag.flag
brQueue(idx).exuOut.brUpdate.pc := io.enq.req(i).bits.pc
brQueue(idx).exuOut.brUpdate.pnpc := io.enq.req(i).bits.brUpdate.pnpc
brQueue(idx).exuOut.brUpdate.fetchIdx := io.enq.req(i).bits.brUpdate.fetchIdx
brQueue(idx).exuOut.brUpdate.pd := io.enq.req(i).bits.brUpdate.pd
brQueue(idx).exuOut.brUpdate.bpuMeta := io.enq.req(i).bits.brUpdate.bpuMeta
ptrFlagVec(idx) := enqBrTag(i).flag
stateQueue(idx) := s_idle
}
}
......@@ -149,21 +151,12 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
XSInfo(
p"exu write back: brTag:${exuWb.bits.redirect.brTag}" +
p" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)} " +
p"pnpc=${Hexadecimal(brQueue(wbIdx).exuOut.brUpdate.pnpc)} " +
// p"pnpc=${Hexadecimal(brQueue(wbIdx).exuOut.brUpdate.pnpc)} " +
p"target=${Hexadecimal(exuWb.bits.redirect.target)}\n"
)
assert(stateQueue(wbIdx) === s_idle)
stateQueue(wbIdx) := s_wb
// only writeback necessary information
brQueue(wbIdx).exuOut.uop := exuWb.bits.uop
brQueue(wbIdx).exuOut.data := exuWb.bits.data
brQueue(wbIdx).exuOut.fflags := exuWb.bits.fflags
brQueue(wbIdx).exuOut.redirectValid := exuWb.bits.redirectValid
brQueue(wbIdx).exuOut.redirect := exuWb.bits.redirect
brQueue(wbIdx).exuOut.debug := exuWb.bits.debug
brQueue(wbIdx).exuOut.brUpdate.target := exuWb.bits.brUpdate.target
brQueue(wbIdx).exuOut.brUpdate.brTarget := exuWb.bits.brUpdate.brTarget
brQueue(wbIdx).exuOut.brUpdate.taken := exuWb.bits.brUpdate.taken
}
}
......@@ -174,22 +167,58 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
stateQueue.foreach(_ := s_idle)
headPtr := BrqPtr(false.B, 0.U)
tailPtr := BrqPtr(false.B, 0.U)
writebackPtr := BrqPtr(false.B, 0.U)
writebackPtr_next := BrqPtr(false.B, 0.U)
}.otherwise {
// conditional check: branch mis-prediction and memory dependence violation
stateQueue.zipWithIndex.foreach({ case(s, i) =>
val ptr = BrqPtr(brQueue(i).ptrFlag, i.U)
val ptr = BrqPtr(ptrFlagVec(i), i.U)
when (ptr.needBrFlush(io.redirect)) {
s := s_idle
}
})
tailPtr := io.redirect.bits.brTag + Mux(io.redirect.bits.flushItself(), 0.U, 1.U)
when (io.redirect.bits.flushItself() && writebackPtr.needBrFlush(io.redirect)) {
writebackPtr := io.redirect.bits.brTag
writebackPtr_next := io.redirect.bits.brTag
}
}
}
def mergeDecodeWbData(dec: ExuOutput, wb: ExuOutput) : ExuOutput = {
val mergeData = Wire(new ExuOutput)
mergeData := dec
// only writeback necessary information
mergeData.uop := wb.uop
mergeData.data := wb.data
mergeData.fflags := wb.fflags
mergeData.redirectValid := wb.redirectValid
mergeData.redirect := wb.redirect
mergeData.debug := wb.debug
mergeData.brUpdate.target := wb.brUpdate.target
mergeData.brUpdate.brTarget := wb.brUpdate.brTarget
mergeData.brUpdate.taken := wb.brUpdate.taken
mergeData
}
decodeData.io.raddr(0) := writebackPtr_next.value
decodeData.io.raddr(1) := brUpdateReadIdx.value
decodeData.io.wen := VecInit(io.enq.req.map(_.fire()))
decodeData.io.waddr := VecInit(enqBrTag.map(_.value))
decodeData.io.wdata.zip(io.enq.req).map{ case (wdata, req) => {
wdata := DontCare
wdata.brUpdate := req.bits.brUpdate
wdata.brUpdate.pc := req.bits.pc
}}
writebackData.io.raddr(0) := writebackPtr_next.value
writebackData.io.raddr(1) := brUpdateReadIdx.value
writebackData.io.wen := VecInit(io.exuRedirectWb.map(_.valid))
writebackData.io.waddr := VecInit(io.exuRedirectWb.map(_.bits.redirect.brTag.value))
writebackData.io.wdata := VecInit(io.exuRedirectWb.map(_.bits))
wbEntry := mergeDecodeWbData(decodeData.io.rdata(0), writebackData.io.rdata(0))
brUpdateReadEntry := mergeDecodeWbData(decodeData.io.rdata(1), writebackData.io.rdata(1))
// Debug info
val debug_roq_redirect = io.redirect.valid && io.redirect.bits.isUnconditional()
val debug_brq_redirect = io.redirectOut.valid
......@@ -219,14 +248,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val fire = io.out.fire()
val predRight = fire && !wbIsMisPred
val predWrong = fire && wbIsMisPred
// val isBType = wbEntry.exuOut.brUpdate.btbType===BTBtype.B
val isBType = wbEntry.exuOut.brUpdate.pd.isBr
// val isJType = wbEntry.exuOut.brUpdate.btbType===BTBtype.J
val isJType = wbEntry.exuOut.brUpdate.pd.isJal
// val isIType = wbEntry.exuOut.brUpdate.btbType===BTBtype.I
val isIType = wbEntry.exuOut.brUpdate.pd.isJalr
// val isRType = wbEntry.exuOut.brUpdate.btbType===BTBtype.R
val isRType = wbEntry.exuOut.brUpdate.pd.isRet
// val isBType = wbEntry.brUpdate.btbType===BTBtype.B
val isBType = wbEntry.brUpdate.pd.isBr
// val isJType = wbEntry.brUpdate.btbType===BTBtype.J
val isJType = wbEntry.brUpdate.pd.isJal
// val isIType = wbEntry.brUpdate.btbType===BTBtype.I
val isIType = wbEntry.brUpdate.pd.isJalr
// val isRType = wbEntry.brUpdate.btbType===BTBtype.R
val isRType = wbEntry.brUpdate.pd.isRet
val mbpInstr = fire
val mbpRight = predRight
val mbpWrong = predWrong
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册