提交 cde9280d 编写于 作者: L LinJiawei

[WIP] update alu/jump unit

上级 319c63a0
......@@ -178,6 +178,7 @@ class CtrlFlow extends XSBundle {
val exceptionVec = ExceptionVec()
val intrVec = Vec(12, Bool())
val pd = new PreDecodeInfo
val pred_taken = Bool()
val crossPageIPFFix = Bool()
val ftqPtr = new FtqPtr
val ftqOffset = UInt(log2Up(PredictWidth).W)
......
......@@ -18,6 +18,7 @@ class CtrlToIntBlockIO extends XSBundle {
val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN)))
val jumpPc = Output(UInt(VAddrBits.W))
val jalr_target = Output(UInt(VAddrBits.W))
// int block only uses port 0~7
val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) // TODO parameterize 8 here
val redirect = ValidIO(new Redirect)
......@@ -63,10 +64,10 @@ class RedirectGenerator extends XSModule with HasCircularQueuePtrHelper {
redirect (send to frontend)
*/
def selectOlderRedirect(x: Valid[Redirect], y: Valid[Redirect]): Valid[Redirect] = {
Mux(isAfter(x.bits, y.bits) && y.valid, y, x)
Mux(isAfter(x.bits.roqIdx, y.bits.roqIdx) && y.valid, y, x)
}
def selectOlderExuOut(x: Valid[ExuOutput], y: Valid[ExuOutput]): Valid[ExuOutput] = {
Mux(isAfter(x.bits.redirect, y.bits.redirect) && y.valid, y, x)
Mux(isAfter(x.bits.redirect.roqIdx, y.bits.redirect.roqIdx) && y.valid, y, x)
}
val jumpOut = io.exuMispredict.head
val oldestAluOut = ParallelOperation(io.exuMispredict.tail, selectOlderExuOut)
......@@ -128,8 +129,7 @@ class RedirectGenerator extends XSModule with HasCircularQueuePtrHelper {
stage3CfiUpdate.hist := ftqRead.hist
stage3CfiUpdate.predHist := ftqRead.predHist
stage3CfiUpdate.specCnt := ftqRead.specCnt
stage3CfiUpdate.predTaken :=
ftqRead.cfiIndex.valid && s2_redirect_bits_reg.ftqOffset === ftqRead.cfiIndex.bits
stage3CfiUpdate.predTaken := s2_redirect_bits_reg.cfiUpdate.predTaken
stage3CfiUpdate.sawNotTakenBranch := VecInit((0 until PredictWidth).map{ i =>
if(i == 0) false.B else Cat(ftqRead.br_mask.take(i-1)).orR()
})(s2_redirect_bits_reg.ftqOffset)
......@@ -200,6 +200,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val jumpInst = dispatch.io.enqIQCtrl(0).bits
ftq.io.ftqRead(0).ptr := jumpInst.cf.ftqPtr // jump
io.toIntBlock.jumpPc := GetPcByFtq(ftq.io.ftqRead(0).entry.ftqPC, jumpInst.cf.ftqOffset)
io.toIntBlock.jalr_target := ftq.io.ftqRead(0).entry.jalr_target
// pipeline between decode and dispatch
for (i <- 0 until RenameWidth) {
......
......@@ -151,7 +151,10 @@ class IntegerBlock
val src2Value = VecInit((0 until 4).map(i => intRf.io.readPorts(i * 2 + 1).data))
rsData.io.srcRegValue(0) := src1Value(readPortIndex(i))
if (cfg.intSrcCnt > 1) rsData.io.srcRegValue(1) := src2Value(readPortIndex(i))
if (cfg == Exu.jumpExeUnitCfg) rsData.io.jumpPc := io.fromCtrlBlock.jumpPc
if (cfg == Exu.jumpExeUnitCfg) {
rsData.io.jumpPc := io.fromCtrlBlock.jumpPc
rsData.io.jalr_target := io.fromCtrlBlock.jalr_target
}
rsData.io.redirect <> redirect
rsData.io.writeBackedData <> writeBackData
......
......@@ -48,7 +48,7 @@ class Dispatch1 extends XSModule with HasExceptionNO {
val isInt = VecInit(io.fromRename.map(req => FuType.isIntExu(req.bits.ctrl.fuType)))
val isBranch = VecInit(io.fromRename.map(req =>
// cover auipc (a fake branch)
!req.bits.cf.brUpdate.pd.notCFI || FuType.isJumpExu(req.bits.ctrl.fuType)
!req.bits.cf.pd.notCFI || FuType.isJumpExu(req.bits.ctrl.fuType)
))
val isFp = VecInit(io.fromRename.map(req => FuType.isFpExu (req.bits.ctrl.fuType)))
val isLs = VecInit(io.fromRename.map(req => FuType.isMemExu(req.bits.ctrl.fuType)))
......
......@@ -187,7 +187,6 @@ abstract class Exu(val config: ExuConfig) extends XSModule {
}
def assignDontCares(out: ExuOutput) = {
out.brUpdate := DontCare
out.fflags := DontCare
out.debug <> DontCare
out.debug.isMMIO := false.B
......
......@@ -80,6 +80,5 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
}.elsewhen(jmp.io.out.valid){
io.toInt.bits.redirectValid := jmp.redirectOutValid
io.toInt.bits.redirect := jmp.redirectOut
io.toInt.bits.brUpdate := jmp.brUpdate
}
}
......@@ -58,8 +58,8 @@ class Alu extends FunctionUnit with HasRedirectOut {
)
val isBranch = ALUOpType.isBranch(func)
val isRVC = uop.cf.brUpdate.pd.isRVC
val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
val isRVC = uop.cf.pd.isRVC
val taken = isBranch && LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
val target = (pc + offset)(VAddrBits-1,0)
val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
......@@ -69,22 +69,11 @@ class Alu extends FunctionUnit with HasRedirectOut {
redirectOut := DontCare
redirectOut.level := RedirectLevel.flushAfter
redirectOut.roqIdx := uop.roqIdx
// redirectOut.pc := DontCare//uop.cf.pc
// redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target)
// redirectOut.interrupt := DontCare//DontCare
// Only taken really needed, do we need brTag ?
brUpdate := DontCare
brUpdate.taken := isBranch && taken
// brUpdate := uop.cf.brUpdate
// // override brUpdate
// brUpdate.pc := uop.cf.pc
// brUpdate.target := Mux(!taken && isBranch, snpc, target)
// brUpdate.brTarget := target
// brUpdate.taken := isBranch && taken
// brUpdate.brTag := uop.brTag
redirectOut.ftqIdx := uop.cf.ftqPtr
redirectOut.ftqOffset := uop.cf.ftqOffset
redirectOut.cfiUpdate.isMisPred := !uop.cf.pred_taken && taken
redirectOut.cfiUpdate.taken := taken
redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
io.in.ready := io.out.ready
io.out.valid := valid
......
......@@ -12,7 +12,6 @@ import xiangshan.backend.decode.isa._
trait HasRedirectOut { this: RawModule =>
val redirectOutValid = IO(Output(Bool()))
val redirectOut = IO(Output(new Redirect))
val brUpdate = IO(Output(new CfiUpdateInfo))
}
class Jump extends FunctionUnit with HasRedirectOut {
......@@ -24,6 +23,7 @@ class Jump extends FunctionUnit with HasRedirectOut {
SignExt(io.in.bits.uop.cf.pc, AddrBits),
io.in.bits.uop
)
val jalr_target = io.in.bits.src(1)(VAddrBits - 1, 0)
val isJalr = JumpOpType.jumpOpisJalr(func)
val isAuipc = JumpOpType.jumpOpisAuipc(func)
......@@ -36,22 +36,22 @@ class Jump extends FunctionUnit with HasRedirectOut {
val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
val valid = io.in.valid
val isRVC = uop.cf.brUpdate.pd.isRVC
val isRVC = uop.cf.pd.isRVC
val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
redirectOutValid := valid
redirectOut := DontCare
// redirectOut.pc := uop.cf.pc
redirectOut.cfiUpdate.target := target
redirectOut.level := RedirectLevel.flushAfter
// redirectOut.interrupt := DontCare
redirectOut.roqIdx := uop.roqIdx
redirectOut.ftqIdx := uop.cf.ftqPtr
redirectOut.ftqOffset := uop.cf.ftqOffset
redirectOut.cfiUpdate.predTaken := true.B
redirectOut.cfiUpdate.taken := true.B
redirectOut.cfiUpdate.target := target
redirectOut.cfiUpdate.isMisPred := target =/= jalr_target
brUpdate := DontCare //uop.cf.brUpdate
// brUpdate.pc := uop.cf.pc
brUpdate.target := target
brUpdate.taken := true.B
// Output
val res = Mux(JumpOpType.jumpOpisAuipc(func), target, snpc)
......
......@@ -340,6 +340,7 @@ class ReservationStationData
// read src op value
val srcRegValue = Vec(srcNum, Input(UInt((XLEN + 1).W)))
val jumpPc = if(exuCfg == Exu.jumpExeUnitCfg) Input(UInt(VAddrBits.W)) else null
val jalr_target = if(exuCfg == Exu.jumpExeUnitCfg) Input(UInt(VAddrBits.W)) else null
// broadcast selected uop to other issue queues
val selectedUop = ValidIO(new MicroOp)
......@@ -430,6 +431,8 @@ class ReservationStationData
io.srcRegValue(0)
)
dataWrite(enqPtrReg, 0, src1Mux)
// TODO: store imm and jalr target together
dataWrite(enqPtrReg, 1, io.jalr_target)
case Exu.aluExeUnitCfg =>
val src1Mux = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(enqUopReg.cf.pc, XLEN),
......
......@@ -396,9 +396,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val dirty_fs = Mux(io.commits.isWalk, false.B, Cat(fpWen).orR())
// when mispredict branches writeback, stop commit in the next 2 cycles
val misPredWb = VecInit((0 until numWbPorts).map(i =>
val misPredWb = Cat(VecInit((0 until numWbPorts).map(i =>
io.exeWbResults(i).bits.redirect.cfiUpdate.isMisPred && io.exeWbResults(i).valid
)).orR
))).orR()
val misPredBlockCounter = Reg(UInt(2.W))
misPredBlockCounter := Mux(misPredWb,
"b11".U,
......@@ -760,7 +760,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
diffTestDebugLrScValid(i) := uop.diffTestDebugLrScValid
wpc(i) := SignExt(uop.cf.pc, XLEN)
trapVec(i) := io.commits.valid(i) && (state===s_idle) && uop.ctrl.isXSTrap
isRVC(i) := uop.cf.brUpdate.pd.isRVC
isRVC(i) := uop.cf.pd.isRVC
}
val scFailed = !diffTestDebugLrScValid(0) &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册