diff --git a/src/main/scala/xiangshan/backend/Backend.scala b/src/main/scala/xiangshan/backend/Backend.scala index e2e0213cbd8..70424998597 100644 --- a/src/main/scala/xiangshan/backend/Backend.scala +++ b/src/main/scala/xiangshan/backend/Backend.scala @@ -256,7 +256,8 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame ctrlBlock.io.robio.csr.intrBitSet := intExuBlock.io.csrio.get.interrupt ctrlBlock.io.robio.csr.trapTarget := intExuBlock.io.csrio.get.trapTarget ctrlBlock.io.robio.csr.isXRet := intExuBlock.io.csrio.get.isXRet - ctrlBlock.io.robio.csr.traceTrapInfo := intExuBlock.io.csrio.get.trapTraceInfo + ctrlBlock.io.robio.csr.traceTrapInfo := intExuBlock.io.csrio.get.traceTrapInfo + ctrlBlock.io.robio.csr.tracePriv := intExuBlock.io.csrio.get.tracePriv ctrlBlock.io.robio.csr.wfiEvent := intExuBlock.io.csrio.get.wfi_event ctrlBlock.io.robio.csr.criticalErrorState := intExuBlock.io.csrio.get.criticalErrorState ctrlBlock.io.robio.lsq <> io.mem.robLsqIO diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index 415c940dde5..bb7d78cf7af 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -270,13 +270,13 @@ class CtrlBlockImp( trace.io.fromPcMem(i) := pcMem.io.rdata(pcMemIdx).getPc(RegEnable(trace.toPcMem(i).bits.ftqOffset.get, traceValid)) } - io.traceCoreInterface.toEncoder.cause := trace.io.toEncoder.trap.cause.asUInt - io.traceCoreInterface.toEncoder.tval := trace.io.toEncoder.trap.tval.asUInt - io.traceCoreInterface.toEncoder.priv := trace.io.toEncoder.trap.priv.asUInt - io.traceCoreInterface.toEncoder.iaddr := VecInit(trace.io.toEncoder.blocks.map(_.bits.iaddr.get)).asUInt - io.traceCoreInterface.toEncoder.itype := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.itype)).asUInt - io.traceCoreInterface.toEncoder.iretire := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.iretire)).asUInt - io.traceCoreInterface.toEncoder.ilastsize := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.ilastsize)).asUInt + io.traceCoreInterface.toEncoder.cause := trace.io.toEncoder.trap.cause.asUInt + io.traceCoreInterface.toEncoder.tval := trace.io.toEncoder.trap.tval.asUInt + io.traceCoreInterface.toEncoder.priv := trace.io.toEncoder.priv.asUInt + io.traceCoreInterface.toEncoder.iaddr := VecInit(trace.io.toEncoder.blocks.map(_.bits.iaddr.get)).asUInt + io.traceCoreInterface.toEncoder.itype := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.itype)).asUInt + io.traceCoreInterface.toEncoder.iretire := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.iretire)).asUInt + io.traceCoreInterface.toEncoder.ilastsize := VecInit(trace.io.toEncoder.blocks.map(_.bits.tracePipe.ilastsize)).asUInt /** * trace end diff --git a/src/main/scala/xiangshan/backend/fu/CSR.scala b/src/main/scala/xiangshan/backend/fu/CSR.scala index 96d0cbe783e..31e035e0c46 100644 --- a/src/main/scala/xiangshan/backend/fu/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/CSR.scala @@ -100,7 +100,8 @@ class CSRFileIO(implicit p: Parameters) extends XSBundle { val trapTarget = Output(new TargetPCBundle) val interrupt = Output(Bool()) val wfi_event = Output(Bool()) - val trapTraceInfo = ValidIO(new TraceTrap) + val traceTrapInfo = ValidIO(new TraceTrap) + val tracePriv = Output(new TracePriv) // from LSQ val memExceptionVAddr = Input(UInt(XLEN.W)) val memExceptionGPAddr = Input(UInt(XLEN.W)) diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala index f73ebe1aca9..50764b519bf 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala @@ -190,7 +190,8 @@ class NewCSR(implicit val p: Parameters) extends Module // Instruction fetch address translation type val instrAddrTransType = new AddrTransType // trace - val trapTraceInfo = ValidIO(new TraceTrap) + val traceTrapInfo = ValidIO(new TraceTrap) + val tracePriv = Output(new TracePriv) // custom val custom = new CSRCustomState val criticalErrorState = Bool() @@ -1112,16 +1113,29 @@ class NewCSR(implicit val p: Parameters) extends Module */ // trace - val privState1HForTrace = Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU) - val privStateForTrace = Seq(Priv.M, Priv.HS, Priv.VS, Priv.HU, Priv.VU) - io.status.trapTraceInfo.valid := RegNext(io.fromRob.trap.valid) - io.status.trapTraceInfo.bits.priv := Mux(debugMode, + val privForTrace = Mux(debugMode, Priv.D, - Mux1H(privState1HForTrace, privStateForTrace) + Mux1H( + Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU), + Seq(Priv.M, Priv.HS, Priv.VS, Priv.HU, Priv.VU) + ) ) - io.status.trapTraceInfo.bits.cause := Mux1H(VecInit(privState1HForTrace).asUInt.head(3), Seq(mcause.rdata, scause.rdata, vscause.rdata)) - io.status.trapTraceInfo.bits.tval := Mux1H(VecInit(privState1HForTrace).asUInt.head(3), Seq(mtval.rdata, stval.rdata, vstval.rdata)) - + val xret = legalDret || legalMNret || legalMret || legalSret + val currentPriv = privForTrace + val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid)) + + io.status.tracePriv.lastPriv := lastPriv + io.status.tracePriv.currentPriv := privForTrace + io.status.traceTrapInfo.valid := RegNext(io.fromRob.trap.valid) + io.status.traceTrapInfo.bits.cause := Mux1H( + Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), + Seq(mcause.rdata, scause.rdata, vscause.rdata) + ) + io.status.traceTrapInfo.bits.tval := Mux1H( + Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), + Seq(mtval.rdata, stval.rdata, vstval.rdata) + ) + /** * perf_begin * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5) diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala index 6d63296f123..59cd6500c69 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala @@ -309,7 +309,8 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) csrOut.debugMode := csrMod.io.status.debugMode - csrOut.trapTraceInfo := csrMod.io.status.trapTraceInfo + csrOut.traceTrapInfo := csrMod.io.status.traceTrapInfo + csrOut.tracePriv := csrMod.io.status.tracePriv csrOut.customCtrl match { case custom => diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index e500b0a77f4..a776129d238 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -1231,20 +1231,20 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP /** * trace */ - val trapTraceInfoFromCsr = io.csr.traceTrapInfo + val traceTrapInfoFromCsr = io.csr.traceTrapInfo + val tracePrivInfoFromCsr = io.csr.tracePriv // trace output val traceTrap = io.trace.traceCommitInfo.trap + val tracePriv = io.trace.traceCommitInfo.priv val traceValids = io.trace.traceCommitInfo.blocks.map(_.valid) val traceBlocks = io.trace.traceCommitInfo.blocks val traceBlockInPipe = io.trace.traceCommitInfo.blocks.map(_.bits.tracePipe) - traceTrap := trapTraceInfoFromCsr.bits - for (i <- 0 until CommitWidth) { traceBlocks(i).bits.ftqIdx.foreach(_ := rawInfo(i).ftqIdx) traceBlocks(i).bits.ftqOffset.foreach(_ := rawInfo(i).ftqOffset) - traceBlockInPipe(i).itype := rawInfo(i).traceBlockInPipe.itype + traceBlockInPipe(i).itype := rawInfo(i).traceBlockInPipe.itype traceBlockInPipe(i).iretire := Mux(io.commits.isCommit && io.commits.commitValid(i), rawInfo(i).traceBlockInPipe.iretire, 0.U) traceBlockInPipe(i).ilastsize := rawInfo(i).traceBlockInPipe.ilastsize } @@ -1262,9 +1262,8 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP traceState := t_waiting } }.elsewhen(traceState === t_waiting){ - when(trapTraceInfoFromCsr.valid){ + when(traceTrapInfoFromCsr.valid){ traceState := t_idle - traceBlocks(0).bits.tracePipe.itype := Mux(io.exception.bits.isInterrupt, Itype.Interrupt, Itype.Exception @@ -1272,6 +1271,11 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP traceValids(0) := true.B } } + traceTrap := traceTrapInfoFromCsr.bits + tracePriv := Mux(traceValids(0) && Itype.isTrapOrXret(traceBlocks(0).bits.tracePipe.itype), + tracePrivInfoFromCsr.lastPriv, + tracePrivInfoFromCsr.currentPriv + ) /** * debug info diff --git a/src/main/scala/xiangshan/backend/rob/RobBundles.scala b/src/main/scala/xiangshan/backend/rob/RobBundles.scala index 9ed5d83857d..6c668826cd9 100644 --- a/src/main/scala/xiangshan/backend/rob/RobBundles.scala +++ b/src/main/scala/xiangshan/backend/rob/RobBundles.scala @@ -218,6 +218,7 @@ class RobCSRIO(implicit p: Parameters) extends XSBundle { val wfiEvent = Input(Bool()) val criticalErrorState = Input(Bool()) val traceTrapInfo = Flipped(ValidIO(new TraceTrap)) + val tracePriv = Input(new TracePriv) val fflags = Output(Valid(UInt(5.W))) val vxsat = Output(Valid(Bool())) diff --git a/src/main/scala/xiangshan/backend/trace/Interface.scala b/src/main/scala/xiangshan/backend/trace/Interface.scala index 72a6ac3b522..0d3c47e7b81 100644 --- a/src/main/scala/xiangshan/backend/trace/Interface.scala +++ b/src/main/scala/xiangshan/backend/trace/Interface.scala @@ -10,7 +10,11 @@ import xiangshan.frontend.{BrType, FtqPtr, PreDecodeInfo} class TraceTrap(implicit val p: Parameters) extends Bundle with HasXSParameter { val cause = UInt(CauseWidth.W) val tval = UInt(TvalWidth.W) - val priv = Priv() +} + +class TracePriv extends Bundle { + val lastPriv = Priv() + val currentPriv = Priv() } class TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { @@ -27,6 +31,7 @@ class TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameter } class TraceBundle(hasIaddr: Boolean, blockSize: Int, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { + val priv = Priv() val trap = Output(new TraceTrap) val blocks = Vec(blockSize, ValidIO(new TraceBlock(hasIaddr, iretireWidth))) } @@ -120,6 +125,8 @@ object Itype extends NamedUInt(4) { def isTrap(itype: UInt) = Seq(Exception, Interrupt).map(_ === itype).reduce(_ || _) + def isTrapOrXret(itype: UInt) = Seq(Exception, Interrupt, ExpIntReturn).map(_ === itype).reduce(_ || _) + def isNotNone(itype: UInt) = itype =/= None def isBranchType(itype: UInt) = itype === Branch diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index 02f1edf388f..c8c6765a187 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -41,9 +41,13 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { val s1_out = WireInit(0.U.asTypeOf(s1_in)) for(i <- 0 until CommitWidth) { - // Trap only occor in block(0). - s1_out.trap := RegEnable(s1_in.trap, 0.U.asTypeOf(s1_in.trap), s1_in.blocks(0).valid && Itype.isTrap(s1_in.blocks(0).bits.tracePipe.itype)) - s1_out.blocks(i).valid := RegEnable(s1_in.blocks(i).valid, 0.U.asTypeOf(s1_in.blocks(i).valid), !blockCommit) + // Trap/Xret only occor in block(0). + if(i == 0) { + s1_out.priv := RegEnable(s1_in.priv, s1_in.blocks(0).valid) + s1_out.trap.cause := RegEnable(s1_in.trap.cause, 0.U, s1_in.blocks(0).valid && Itype.isTrap(s1_in.blocks(0).bits.tracePipe.itype)) + s1_out.trap.tval := RegEnable(s1_in.trap.tval, 0.U, s1_in.blocks(0).valid && Itype.isTrap(s1_in.blocks(0).bits.tracePipe.itype)) + } + s1_out.blocks(i).valid := RegEnable(s1_in.blocks(i).valid, false.B, !blockCommit) s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, 0.U.asTypeOf(s1_in.blocks(i).bits), s1_in.blocks(i).valid) } @@ -54,26 +58,23 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { val traceBuffer = Module(new TraceBuffer) traceBuffer.io.in.fromEncoder := fromEncoder traceBuffer.io.in.fromRob := s2_in - val s2_out_trap = traceBuffer.io.out.groups.trap - val s2_out_block = traceBuffer.io.out.groups.blocks + val s2_out_groups = traceBuffer.io.out.groups blockCommit := traceBuffer.io.out.blockCommit /** * stage 3: groups with iaddr from pcMem(ftqidx & ftqOffset -> iaddr) -> encoder */ - val s3_in_trap = s2_out_trap - val s3_in_block = s2_out_block + val s3_in_groups = s2_out_groups + val s3_out_groups = RegNext(s3_in_groups) - val s3_out_trap = RegNext(s3_in_trap) - val s3_out_block = RegNext(s3_in_block) - - toPcMem := s3_in_block + toPcMem := s3_in_groups.blocks for(i <- 0 until TraceGroupNum) { - toEncoder.trap := s3_out_trap - toEncoder.blocks(i).valid := s3_out_block(i).valid - toEncoder.blocks(i).bits.iaddr.foreach(_ := Mux(s3_out_block(i).valid, fromPcMem(i), 0.U)) - toEncoder.blocks(i).bits.tracePipe := s3_out_block(i).bits.tracePipe + toEncoder.priv := s3_out_groups.priv + toEncoder.trap := s3_out_groups.trap + toEncoder.blocks(i).valid := s3_out_groups.blocks(i).valid + toEncoder.blocks(i).bits.iaddr.foreach(_ := Mux(s3_out_groups.blocks(i).valid, fromPcMem(i), 0.U)) + toEncoder.blocks(i).bits.tracePipe := s3_out_groups.blocks(i).bits.tracePipe } if(backendParams.debugEn){ dontTouch(io.toEncoder) diff --git a/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala b/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala index 21c3954c78f..90bff7d788c 100644 --- a/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala +++ b/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala @@ -24,8 +24,10 @@ class TraceBuffer(implicit val p: Parameters) extends Module // buffer: compress info from robCommit val traceTrap = Reg(new TraceTrap) + val tracePriv = Reg(Priv()) val traceEntries = Reg(Vec(CommitWidth, ValidIO(new TraceBlock(false, IretireWidthCompressed)))) traceTrap := io.in.fromRob.trap + tracePriv := io.in.fromRob.priv val blockCommit = RegInit(false.B) // to rob @@ -80,6 +82,7 @@ class TraceBuffer(implicit val p: Parameters) extends Module * deq from traceEntries */ val blockOut = WireInit(0.U.asTypeOf(io.out.groups)) + blockOut.priv := tracePriv blockOut.trap := traceTrap for(i <- 0 until TraceGroupNum) { when(deqPtrPre + i.U < enqPtr) {