提交 ddb65c47 编写于 作者: L Li Qianruo

Trigger: hardwire timing to 1

We have singlestep already so triggers do not need to hit after inst commits
上级 cfd0afdf
......@@ -466,6 +466,7 @@ class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle {
// distribute csr write signal
val distribute_csr = new DistributedCSRIO()
val singlestep = Output(Bool())
val frontend_trigger = new FrontendTdataDistributeIO()
val mem_trigger = new MemTdataDistributeIO()
val trigger_enable = Output(Vec(10, Bool()))
......@@ -528,32 +529,21 @@ xret csr to pc + 4/ + 2
class TriggerCf(implicit p: Parameters) extends XSBundle {
// frontend
val frontendHit = Vec(4, Bool())
val frontendTiming = Vec(4, Bool())
// val frontendTiming = Vec(4, Bool())
// val frontendHitNext = Vec(4, Bool())
val frontendHitNext = Vec(4, Bool())
val frontendException = Bool()
// val frontendException = Bool()
// backend
val backendEn = Vec(2, Bool()) // Hit(6) && chain(4) , Hit(8) && chain(4)
val backendConsiderTiming = Vec(2, Bool())
val backendChainTiming = Vec(2, Bool())
val backendHit = Vec(6, Bool())
val backendTiming = Vec(6, Bool()) // trigger enable fro chain
// val backendTiming = Vec(6, Bool()) // trigger enable fro chain
// Two situations not allowed:
// 1. load data comparison
// 2. store chaining with store
def frontendChain = Seq(false.B, false.B) ++ backendChainTiming
def getTimingFrontend = (frontendHit.zip(frontendTiming).zip(frontendChain).map {
case ((h, t), c) => Mux(h, t, true.B) && !c
}).reduce(_ && _) // unless all 1 the timing is one
def getHitFrontend = frontendHit.reduce(_ || _)
def getTimingBackend = (backendHit.zip(backendTiming).map {
case (h, t) => Mux(h, t, true.B)
}).reduce(_ && _)
def getHitBackend = backendHit.reduce(_ || _)
def hit = getHitFrontend || getHitBackend
}
// these 3 bundles help distribute trigger control signals from CSR
......
......@@ -267,24 +267,21 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
loadUnits(i).io.trigger(j).matchType := tdata(lTriggerMapping(j)).matchType
loadUnits(i).io.trigger(j).tEnable := tEnable(lTriggerMapping(j))
// Just let load triggers that match data unavailable
hit(j) := loadUnits(i).io.trigger(j).addrHit // TODO .&& the select bit Mux(tdata(j + 3).select, loadUnits(i).io.trigger(j).lastDataHit, loadUnits(i).io.trigger(j).addrHit)
hit(j) := loadUnits(i).io.trigger(j).addrHit && tdata(j).select // Mux(tdata(j + 3).select, loadUnits(i).io.trigger(j).lastDataHit, loadUnits(i).io.trigger(j).addrHit)
io.writeback(i).bits.uop.cf.trigger.backendHit(lTriggerMapping(j)) := hit(j)
io.writeback(i).bits.uop.cf.trigger.backendTiming(lTriggerMapping(j)) := tdata(lTriggerMapping(j)).timing
// io.writeback(i).bits.uop.cf.trigger.backendTiming(lTriggerMapping(j)) := tdata(lTriggerMapping(j)).timing
// if (lChainMapping.contains(j)) io.writeback(i).bits.uop.cf.trigger.triggerChainVec(lChainMapping(j)) := hit && tdata(j+3).chain
}
when(tdata(2).chain) {
io.writeback(i).bits.uop.cf.trigger.backendHit(2) := hit(0) && hit(1)
io.writeback(i).bits.uop.cf.trigger.backendHit(3) := hit(0) && hit(1)
}
when(io.writeback(i).bits.uop.cf.trigger.backendEn(1)) {
io.writeback(i).bits.uop.cf.trigger.backendHit(5) := Mux(io.writeback(i).bits.uop.cf.trigger.backendConsiderTiming(1),
tdata(5).timing === io.writeback(i).bits.uop.cf.trigger.backendChainTiming(1), true.B) && hit(2)
} .otherwise{
when(!io.writeback(i).bits.uop.cf.trigger.backendEn(1)) {
io.writeback(i).bits.uop.cf.trigger.backendHit(5) := false.B
}
XSDebug(io.writeback(i).bits.uop.cf.trigger.getHitBackend && io.writeback(i).valid, p"Debug Mode: Load Inst No.${i}" +
p"has trigger hit vec ${io.writeback(i).bits.uop.cf.trigger.backendHit}" +
p"with timing ${io.writeback(i).bits.uop.cf.trigger.backendTiming}\n")
p"has trigger hit vec ${io.writeback(i).bits.uop.cf.trigger.backendHit}\n")
}
......@@ -329,16 +326,13 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
when(!tdata(sTriggerMapping(j)).select) {
hit(j) := TriggerCmp(stOut(i).bits.data, tdata(sTriggerMapping(j)).tdata2, tdata(sTriggerMapping(j)).matchType, tEnable(sTriggerMapping(j)))
stOut(i).bits.uop.cf.trigger.backendHit(sTriggerMapping(j)) := hit(j)
stOut(i).bits.uop.cf.trigger.backendTiming(sTriggerMapping(j)) := tdata(sTriggerMapping(j)).timing
// stOut(i).bits.uop.cf.trigger.backendTiming(sTriggerMapping(j)) := tdata(sTriggerMapping(j)).timing
// if (sChainMapping.contains(j)) stOut(i).bits.uop.cf.trigger.triggerChainVec(sChainMapping(j)) := hit && tdata(j + 3).chain
} .otherwise {
hit := VecInit(Seq.fill(3)(false.B))
}
when(stOut(i).bits.uop.cf.trigger.backendEn(0)) {
stOut(i).bits.uop.cf.trigger.backendHit(4) := Mux(stOut(i).bits.uop.cf.trigger.backendConsiderTiming(0),
tdata(4).timing === io.writeback(i).bits.uop.cf.trigger.backendChainTiming(0), true.B) && hit(2)
} .otherwise{
when(!stOut(i).bits.uop.cf.trigger.backendEn(0)) {
stOut(i).bits.uop.cf.trigger.backendHit(4) := false.B
}
}
......
......@@ -55,7 +55,7 @@ class DecodeStage(implicit p: Parameters) extends XSModule with HasPerfEvents {
fusionDecoder.io.dec := decoders.map(_.io.deq.cf_ctrl.ctrl)
fusionDecoder.io.out.zip(io.out.dropRight(1)).zipWithIndex.foreach{ case ((d, out), i) =>
d.ready := out.ready
when (d.valid) {
when (d.valid && !io.csrCtrl.singlestep) { // TODO && nosinglestep
out.bits.ctrl := d.bits
// TODO: remove this
// Dirty code for ftq update
......
......@@ -99,11 +99,6 @@ class Dispatch(implicit p: Parameters) extends XSModule with HasPerfEvents {
singleStepStatus := true.B
}
XSDebug(singleStepStatus, "Debug Mode: Singlestep status is asserted\n")
val frontendTriggerHitReg = RegInit(false.B)
val frontendTriggerHitWire = WireInit(Fill(log2Up(RenameWidth), true.B))
when(io.redirect.valid) {
frontendTriggerHitReg := false.B
}
val updatedUop = Wire(Vec(RenameWidth, new MicroOp))
val updatedCommitType = Wire(Vec(RenameWidth, CommitType()))
......@@ -114,11 +109,6 @@ class Dispatch(implicit p: Parameters) extends XSModule with HasPerfEvents {
for (i <- 0 until RenameWidth) {
when(io.fromRename(i).fire() && io.fromRename(i).bits.cf.trigger.getHitFrontend && io.fromRename(i).bits.cf.trigger.getTimingFrontend){
frontendTriggerHitWire := i.U
frontendTriggerHitReg := true.B
XSDebug(p"Debug Mode: A frontend trigger with timing 1 has fired. Index is ${i}\n")
}
updatedCommitType(i) := Cat(isLs(i), (isStore(i) && !isAMO(i)) | isBranch(i))
updatedUop(i) := io.fromRename(i).bits
......@@ -145,12 +135,8 @@ class Dispatch(implicit p: Parameters) extends XSModule with HasPerfEvents {
// update singleStep
updatedUop(i).ctrl.singleStep := io.singleStep && (if (i == 0) singleStepStatus else true.B)
// update frontend triggers
updatedUop(i).cf.trigger.frontendException :=
(io.fromRename(i).bits.cf.trigger.getHitFrontend && !io.fromRename(i).bits.cf.trigger.getTimingFrontend) ||
(frontendTriggerHitWire < i.U) || frontendTriggerHitReg
when (io.fromRename(i).fire()) {
XSDebug(updatedUop(i).cf.trigger.frontendException, s"Debug Mode: inst ${i} has frontend trigger exception\n")
XSDebug(updatedUop(i).cf.trigger.getHitFrontend, s"Debug Mode: inst ${i} has frontend trigger exception\n")
XSDebug(updatedUop(i).ctrl.singleStep, s"Debug Mode: inst ${i} has single step exception\n")
}
if (env.EnableDifftest) {
......@@ -231,7 +217,7 @@ class Dispatch(implicit p: Parameters) extends XSModule with HasPerfEvents {
// nextCanOut: next instructions can out (based on blockBackward)
// notBlockedByPrevious: previous instructions can enqueue
val hasException = VecInit(io.fromRename.map(
r => selectFrontend(r.bits.cf.exceptionVec).asUInt.orR || r.bits.ctrl.singleStep || r.bits.cf.trigger.frontendException))
r => selectFrontend(r.bits.cf.exceptionVec).asUInt.orR || r.bits.ctrl.singleStep || r.bits.cf.trigger.getHitFrontend))
val thisIsBlocked = VecInit((0 until RenameWidth).map(i => {
// for i > 0, when Rob is empty but dispatch1 have valid instructions to enqueue, it's blocked
if (i > 0) isNoSpecExec(i) && (!io.enqRob.isEmpty || Cat(io.fromRename.take(i).map(_.valid)).orR)
......
......@@ -253,6 +253,7 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
dcsrNew
}
csrio.singleStep := dcsrData.step
csrio.customCtrl.singlestep := dcsrData.step
// Trigger CSRs
......@@ -265,10 +266,11 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
)
def TypeLookup(select: UInt) = MuxLookup(select, I_Trigger, type_config)
val tdata1Phy = RegInit(VecInit(List.fill(10) {0.U(64.W)}))
val tdata1Phy = RegInit(VecInit(List.fill(10) {(2L << 60L).U(64.W)})) // init ttype 2
val tdata2Phy = Reg(Vec(10, UInt(64.W)))
val tselectPhy = RegInit(0.U(4.W))
val tDummy = WireInit(0.U(64.W))
val tDummy1 = WireInit(0.U(64.W))
val tDummy2 = WireInit(0.U(64.W))
val tdata1Wire = Wire(UInt(64.W))
val tdata2Wire = Wire(UInt(64.W))
val tinfo = RegInit(2.U(64.W))
......@@ -276,12 +278,14 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val triggerAction = RegInit(false.B)
tdata1Wire := tdata1Phy(tselectPhy)
tdata2Wire := tdata2Phy(tselectPhy)
tDummy1 := tdata1Phy(tselectPhy)
tDummy2 := tdata2Phy(tselectPhy)
def ReadTdata1(rdata: UInt) = {
val tdata1 = WireInit(tdata1Wire)
val read_data = tdata1Wire
XSDebug(src2(11, 0) === Tdata1.U && valid, p"\nDebug Mode: tdata1(${tselectPhy})is read, the actual value is ${Binary(tdata1)}\n")
read_data & (triggerAction << 12) // fix action
read_data | (triggerAction << 12) // fix action
}
def WriteTdata1(wdata: UInt) = {
val tdata1 = WireInit(tdata1Wire.asTypeOf(new TdataBundle))
......@@ -289,20 +293,25 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val tdata1_new = WireInit(wdata.asTypeOf(new TdataBundle))
XSDebug(src2(11, 0) === Tdata1.U && valid && func =/= CSROpType.jmp, p"Debug Mode: tdata1(${tselectPhy})is written, the actual value is ${wdata}\n")
// tdata1_new.hit := wdata(20)
tdata1_new.ttype := tdata1.ttype
tdata1_new.dmode := Mux(debugMode, wdata_wire.dmode, tdata1.dmode)
tdata1_new.maskmax := 0.U
tdata1_new.hit := 0.U
tdata1_new.select := (TypeLookup(tselectPhy) === I_Trigger) && wdata_wire.select
when(wdata_wire.action <= 1.U){
triggerAction := tdata1_new.action(0)
} .otherwise{
tdata1_new.action := tdata1.action
}
tdata1_new.timing := false.B // hardwire this because we have singlestep
tdata1_new.zero1 := 0.U
tdata1_new.zero2 := 0.U
tdata1_new.chain := !tselectPhy(0) && wdata_wire.chain
when(wdata_wire.matchType =/= 0.U && wdata_wire.matchType =/= 2.U && wdata_wire.matchType =/= 3.U) {
tdata1_new.matchType := tdata1.matchType
}
tdata1_new.sizehi := Mux(TypeLookup(tselectPhy) === I_Trigger, 0.U, 1.U)
tdata1_new.sizelo:= Mux(TypeLookup(tselectPhy) === I_Trigger, 3.U, 1.U)
tdata1_new.sizehi := Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 0.U, 1.U)
tdata1_new.sizelo:= Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 3.U, 1.U)
tdata1_new.execute := TypeLookup(tselectPhy) === I_Trigger
tdata1_new.store := TypeLookup(tselectPhy) === S_Trigger
tdata1_new.load := TypeLookup(tselectPhy) === L_Trigger
......@@ -679,8 +688,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
//--- Trigger ---
MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect),
MaskedRegMap(Tdata1, tDummy, WritableMask, WriteTdata1, WritableMask, ReadTdata1),
MaskedRegMap(Tdata2, tDummy, WritableMask, WriteTdata2, WritableMask, ReadTdata2),
MaskedRegMap(Tdata1, tDummy1, WritableMask, WriteTdata1, WritableMask, ReadTdata1),
MaskedRegMap(Tdata2, tDummy2, WritableMask, WriteTdata2, WritableMask, ReadTdata2),
MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable),
MaskedRegMap(Tcontrol, tControlPhy, tcontrolWriteMask),
......@@ -804,8 +813,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
tdata1.m && priviledgeMode === ModeM ||
tdata1.s && priviledgeMode === ModeS || tdata1.u && priviledgeMode === ModeU
}
csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && addr === Tdata1.U && TypeLookup(tselectPhy) === I_Trigger)
csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && addr === Tdata1.U && TypeLookup(tselectPhy) =/= I_Trigger)
csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) === I_Trigger)
csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) =/= I_Trigger)
XSDebug(csrio.customCtrl.trigger_enable.asUInt.orR(), p"Debug Mode: At least 1 trigger is enabled, trigger enable is ${Binary(csrio.customCtrl.trigger_enable.asUInt())}\n")
// CSR inst decode
......@@ -949,10 +958,10 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
val hasSingleStep = csrio.exception.bits.uop.ctrl.singleStep && raiseException
val hasTriggerHit = (csrio.exception.bits.uop.cf.trigger.frontendException || csrio.exception.bits.uop.cf.trigger.backendHit.orR) && raiseException
val hasTriggerHit = (csrio.exception.bits.uop.cf.trigger.hit) && raiseException
XSDebug(hasSingleStep, "Debug Mode: single step exception\n")
XSDebug(hasTriggerHit, p"Debug Mode: trigger hit, is frontend? ${csrio.exception.bits.uop.cf.trigger.frontendException} " +
XSDebug(hasTriggerHit, p"Debug Mode: trigger hit, is frontend? ${Binary(csrio.exception.bits.uop.cf.trigger.frontendHit.asUInt)} " +
p"backend hit vec ${Binary(csrio.exception.bits.uop.cf.trigger.backendHit.asUInt)}\n")
val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
......
......@@ -167,9 +167,9 @@ class RobExceptionInfo(implicit p: Parameters) extends XSBundle {
// def trigger_before = !trigger.getTimingBackend && trigger.getHitBackend
// def trigger_after = trigger.getTimingBackend && trigger.getHitBackend
def has_exception = exceptionVec.asUInt.orR || flushPipe || singleStep || replayInst || trigger.getHitBackend || trigger.frontendException
def has_exception = exceptionVec.asUInt.orR || flushPipe || singleStep || replayInst || trigger.hit
// only exceptions are allowed to writeback when enqueue
def can_writeback = exceptionVec.asUInt.orR || singleStep || trigger.getHitBackend || trigger.frontendException
def can_writeback = exceptionVec.asUInt.orR || singleStep || trigger.hit
}
class ExceptionGen(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
......@@ -459,13 +459,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val intrEnable = intrBitSetReg && !hasNoSpecExec && interrupt_safe(deqPtr.value)
val deqHasExceptionOrFlush = exceptionDataRead.valid && exceptionDataRead.bits.robIdx === deqPtr
val deqHasException = deqHasExceptionOrFlush && (exceptionDataRead.bits.exceptionVec.asUInt.orR ||
exceptionDataRead.bits.singleStep || exceptionDataRead.bits.trigger.getHitFrontend || exceptionDataRead.bits.trigger.getHitBackend)
exceptionDataRead.bits.singleStep || exceptionDataRead.bits.trigger.hit)
val deqHasFlushPipe = deqHasExceptionOrFlush && exceptionDataRead.bits.flushPipe
val deqHasReplayInst = deqHasExceptionOrFlush && exceptionDataRead.bits.replayInst
val exceptionEnable = writebacked(deqPtr.value) && deqHasException
XSDebug(deqHasException && exceptionDataRead.bits.singleStep, "Debug Mode: Deq has singlestep exception\n")
XSDebug(deqHasException && exceptionDataRead.bits.trigger.frontendException, "Debug Mode: Deq has frontend trigger exception\n")
XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitFrontend, "Debug Mode: Deq has frontend trigger exception\n")
XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitBackend, "Debug Mode: Deq has backend trigger exception\n")
val isFlushPipe = writebacked(deqPtr.value) && (deqHasFlushPipe || deqHasReplayInst)
......
......@@ -183,17 +183,13 @@ class PreDecode(implicit p: Parameters) extends XSModule with HasPdConst{
io.out.pd(i).isRet := isRet
io.out.pc(i) := currentPC
io.out.crossPageIPF(i) := (io.out.pc(i) === addrAlign(realEndPC, 64, VAddrBits) - 2.U)&& !pageFault(0) && pageFault(1) && !currentIsRVC
// io.out.triggered(i) := TriggerCmp(Mux(currentIsRVC, inst(15,0), inst), tInstData, matchType, triggerEnable) && TriggerCmp(currentPC, tPcData, matchType, triggerEnable)
// io.out.triggered(i).triggerTiming := VecInit(Seq.fill(10)(false.B))
// io.out.triggered(i).triggerHitVec := VecInit(Seq.fill(10)(false.B))
// io.out.triggered(i).triggerChainVec := VecInit(Seq.fill(5)(false.B))
val triggerHitVec = Wire(Vec(4, Bool()))
for (j <- 0 until 4) {
val hit = Mux(tdata(j).select, TriggerCmp(Mux(currentIsRVC, inst(15, 0), inst), tdata(j).tdata2, tdata(j).matchType, triggerEnable(j)),
TriggerCmp(currentPC, tdata(j).tdata2, tdata(j).matchType, triggerEnable(j)))
triggerHitVec(j) := hit
// io.out.triggered(i).frontendHit(triggerMapping(j)) := hit
io.out.triggered(i).frontendTiming(j) := tdata(j).timing
}
// fix chains this could be moved further into the pipeline
io.out.triggered(i).frontendHit := triggerHitVec
......@@ -204,11 +200,10 @@ class PreDecode(implicit p: Parameters) extends XSModule with HasPdConst{
}
for(j <- 0 until 2) {
io.out.triggered(i).backendEn(j) := Mux(tdata(j+2).chain, triggerHitVec(j+2), true.B)
io.out.triggered(i).backendConsiderTiming(j) := tdata(j+2).chain
io.out.triggered(i).backendChainTiming(j) := tdata(j+2).timing
io.out.triggered(i).frontendHit(j+2) := !(tdata(j+2).chain && triggerHitVec(j+2)) // temporary workaround
}
XSDebug(io.out.triggered(i).getHitFrontend, p"Debug Mode: Predecode Inst No. ${i} has trigger hit vec ${io.out.triggered(i).frontendHit}" +
p"with timing ${io.out.triggered(i).frontendTiming} and backend ${io.out.triggered(i).backendEn} + ${io.out.triggered(i).backendConsiderTiming}\n")
p"and backend en ${io.out.triggered(i).backendEn}\n")
io.out.pageFault(i) := hasPageFault || io.out.crossPageIPF(i)
io.out.accessFault(i) := hasAccessFault
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册