From 4603f7437d53f0f321a0402b83d7f534908fa7e6 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 19 Sep 2024 16:34:34 +0800 Subject: [PATCH 01/13] feat(trace): add trace buffer. --- src/main/scala/xiangshan/Bundle.scala | 1 + src/main/scala/xiangshan/Parameters.scala | 19 ++- .../scala/xiangshan/backend/Backend.scala | 6 + .../scala/xiangshan/backend/Bundles.scala | 2 +- .../scala/xiangshan/backend/CtrlBlock.scala | 46 ++++++- src/main/scala/xiangshan/backend/fu/CSR.scala | 2 + .../xiangshan/backend/fu/NewCSR/NewCSR.scala | 14 +++ .../xiangshan/backend/fu/wrapper/CSR.scala | 3 + .../scala/xiangshan/backend/rob/Rob.scala | 52 +++++++- .../xiangshan/backend/rob/RobBundles.scala | 5 +- .../xiangshan/backend/trace/Interface.scala | 27 ++-- .../scala/xiangshan/backend/trace/Trace.scala | 85 +++++++++++++ .../xiangshan/backend/trace/TraceBuffer.scala | 118 ++++++++++++++++++ 13 files changed, 354 insertions(+), 26 deletions(-) create mode 100644 src/main/scala/xiangshan/backend/trace/Trace.scala create mode 100644 src/main/scala/xiangshan/backend/trace/TraceBuffer.scala diff --git a/src/main/scala/xiangshan/Bundle.scala b/src/main/scala/xiangshan/Bundle.scala index fa473424a2..80e5e247ae 100644 --- a/src/main/scala/xiangshan/Bundle.scala +++ b/src/main/scala/xiangshan/Bundle.scala @@ -46,6 +46,7 @@ import xiangshan.frontend.AllFoldedHistories import xiangshan.frontend.AllAheadFoldedHistoryOldestBits import xiangshan.frontend.RASPtr import xiangshan.backend.rob.RobBundles.RobCommitEntryBundle +import xiangshan.backend.trace._ class ValidUndirectioned[T <: Data](gen: T) extends Bundle { val valid = Bool() diff --git a/src/main/scala/xiangshan/Parameters.scala b/src/main/scala/xiangshan/Parameters.scala index f5d7f53f61..bf4f54d2ed 100644 --- a/src/main/scala/xiangshan/Parameters.scala +++ b/src/main/scala/xiangshan/Parameters.scala @@ -29,6 +29,7 @@ import xiangshan.backend.fu.FuConfig._ import xiangshan.backend.issue.{IntScheduler, IssueBlockParams, MemScheduler, SchdBlockParams, SchedulerType, VfScheduler, FpScheduler} import xiangshan.backend.regfile._ import xiangshan.backend.BackendParams +import xiangshan.backend.trace._ import xiangshan.cache.DCacheParameters import xiangshan.cache.prefetch._ import xiangshan.frontend.{BasePredictor, BranchPredictionResp, FTB, FakePredictor, RAS, Tage, ITTage, Tage_SC, FauFTB} @@ -543,7 +544,11 @@ case class XSCoreParameters // Parameters for trace extension. // Trace parameters is useful for XSTOP. - val TraceGroupNum = 3 // Width to Encoder + val traceParams: TraceParams = new TraceParams( + TraceGroupNum = 3, // Width to Encoder + HasEncoder = true, + TraceEnable = true, + ) } case object DebugOptionsKey extends Field[DebugOptions] @@ -885,5 +890,15 @@ trait HasXSParameter { protected def TriggerChainMaxLength = 2 // Parameters for Trace extension - def TraceGroupNum = coreParams.TraceGroupNum + def TraceGroupNum = coreParams.traceParams.TraceGroupNum + def HasEncoder = coreParams.traceParams.HasEncoder + def TraceEnable = coreParams.traceParams.TraceEnable + def CauseWidth = XLEN + def TvalWidth = XLEN + def PrivWidth = 3 + def IaddrWidth = XLEN + def ItypeWidth = 4 + def IretireWidthInPipe = log2Up(RenameWidth * 2) + def IretireWidthCompressed = log2Up(RenameWidth * CommitWidth * 2) + def IlastsizeWidth = 1 } diff --git a/src/main/scala/xiangshan/backend/Backend.scala b/src/main/scala/xiangshan/backend/Backend.scala index 483b4c4277..e2e0213cbd 100644 --- a/src/main/scala/xiangshan/backend/Backend.scala +++ b/src/main/scala/xiangshan/backend/Backend.scala @@ -46,6 +46,7 @@ import xiangshan.backend.fu.{FenceIO, FenceToSbuffer, FuConfig, FuType, PFEvent, import xiangshan.backend.issue.EntryBundles._ import xiangshan.backend.issue.{CancelNetwork, Scheduler, SchedulerArithImp, SchedulerImpBase, SchedulerMemImp} import xiangshan.backend.rob.{RobCoreTopDownIO, RobDebugRollingIO, RobLsqIO, RobPtr} +import xiangshan.backend.trace.TraceCoreInterface import xiangshan.frontend.{FtqPtr, FtqRead, PreDecodeInfo} import xiangshan.mem.{LqPtr, LsqEnqIO, SqPtr} @@ -255,6 +256,7 @@ 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.wfiEvent := intExuBlock.io.csrio.get.wfi_event ctrlBlock.io.robio.csr.criticalErrorState := intExuBlock.io.csrio.get.criticalErrorState ctrlBlock.io.robio.lsq <> io.mem.robLsqIO @@ -752,6 +754,8 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame io.toTop.cpuHalted := ctrlBlock.io.toTop.cpuHalt + io.traceCoreInterface <> ctrlBlock.io.traceCoreInterface + io.debugTopDown.fromRob := ctrlBlock.io.debugTopDown.fromRob ctrlBlock.io.debugTopDown.fromCore := io.debugTopDown.fromCore @@ -947,6 +951,8 @@ class BackendIO(implicit p: Parameters, params: BackendParams) extends XSBundle val toTop = new BackendToTopBundle + val traceCoreInterface = new TraceCoreInterface + val fenceio = new FenceIO // Todo: merge these bundles into BackendFrontendIO val frontend = Flipped(new FrontendToCtrlIO) diff --git a/src/main/scala/xiangshan/backend/Bundles.scala b/src/main/scala/xiangshan/backend/Bundles.scala index e0f4d921f1..de6051910f 100644 --- a/src/main/scala/xiangshan/backend/Bundles.scala +++ b/src/main/scala/xiangshan/backend/Bundles.scala @@ -220,7 +220,7 @@ object Bundles { val instrSize = UInt(log2Ceil(RenameWidth + 1).W) val dirtyFs = Bool() val dirtyVs = Bool() - val traceBlockInPipe = new TracePipe(log2Up(RenameWidth * 2)) + val traceBlockInPipe = new TracePipe(IretireWidthInPipe) val eliminatedMove = Bool() // Take snapshot at this CFI inst diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index 1c8202315e..3bfc6b6ef6 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -37,6 +37,7 @@ import xiangshan.backend.rob.{Rob, RobCSRIO, RobCoreTopDownIO, RobDebugRollingIO import xiangshan.frontend.{FtqPtr, FtqRead, Ftq_RF_Components} import xiangshan.mem.{LqPtr, LsqEnqIO} import xiangshan.backend.issue.{FpScheduler, IntScheduler, MemScheduler, VfScheduler} +import xiangshan.backend.trace._ class CtrlToFtqIO(implicit p: Parameters) extends XSBundle { val rob_commits = Vec(CommitWidth, Valid(new RobCommitInfo)) @@ -72,7 +73,8 @@ class CtrlBlockImp( "robFlush" -> 1, "load" -> params.LduCnt, "hybrid" -> params.HyuCnt, - "store" -> (if(EnableStorePrefetchSMS) params.StaCnt else 0) + "store" -> (if(EnableStorePrefetchSMS) params.StaCnt else 0), + "trace" -> TraceGroupNum )) private val numPcMemReadForExu = params.numPcReadPort @@ -239,6 +241,46 @@ class CtrlBlockImp( io.memStPcRead.foreach(_.data := 0.U) } + /** + * trace begin + */ + val trace = Module(new Trace) + if(HasEncoder){ + trace.io.fromEncoder.stall := io.traceCoreInterface.fromEncoder.stall + trace.io.fromEncoder.enable := io.traceCoreInterface.fromEncoder.enable + } else if(!HasEncoder && TraceEnable) { + trace.io.fromEncoder.enable := true.B + trace.io.fromEncoder.stall := false.B + } else if(!HasEncoder && !TraceEnable) { + trace.io.fromEncoder.enable := false.B + trace.io.fromEncoder.stall := false.B + } + + trace.io.fromRob := rob.io.trace.traceCommitInfo + rob.io.trace.blockCommit := trace.io.blockRobCommit + + dontTouch(trace.io.toEncoder) + + for ((pcMemIdx, i) <- pcMemRdIndexes("trace").zipWithIndex) { + val traceValid = trace.toPcMem(i).valid + pcMem.io.ren.get(pcMemIdx) := traceValid + pcMem.io.raddr(pcMemIdx) := trace.toPcMem(i).bits.ftqIdx.get.value + 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 + + /** + * trace end + */ + + redirectGen.io.hartId := io.fromTop.hartId redirectGen.io.oldestExuRedirect.valid := GatedValidRegNext(oldestExuRedirect.valid) redirectGen.io.oldestExuRedirect.bits := RegEnable(oldestExuRedirect.bits, oldestExuRedirect.valid) @@ -754,6 +796,8 @@ class CtrlBlockIO()(implicit p: Parameters, params: BackendParams) extends XSBun val ratOldPest = new RatToVecExcpMod }) + val traceCoreInterface = new TraceCoreInterface + val perfInfo = Output(new Bundle{ val ctrlInfo = new Bundle { val robFull = Bool() diff --git a/src/main/scala/xiangshan/backend/fu/CSR.scala b/src/main/scala/xiangshan/backend/fu/CSR.scala index 4554cbddee..96d0cbe783 100644 --- a/src/main/scala/xiangshan/backend/fu/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/CSR.scala @@ -33,6 +33,7 @@ import xiangshan.backend.fu.NewCSR.CSREvents.TargetPCBundle import xiangshan.backend.fu.NewCSR.CSRNamedConstant.ContextStatus import xiangshan.backend.rob.RobPtr import utils.MathUtils.{BigIntGenMask, BigIntNot} +import xiangshan.backend.trace._ class FpuCsrIO extends Bundle { val fflags = Output(Valid(UInt(5.W))) @@ -99,6 +100,7 @@ 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) // 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 feeb3d5ab3..f73ebe1aca 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala @@ -20,6 +20,7 @@ import xiangshan.backend.rob.RobPtr import xiangshan._ import xiangshan.backend.fu.PerfCounterIO import xiangshan.ExceptionNO._ +import xiangshan.backend.trace._ import scala.collection.immutable.SeqMap @@ -188,6 +189,8 @@ class NewCSR(implicit val p: Parameters) extends Module val memTrigger = new MemTdataDistributeIO() // Instruction fetch address translation type val instrAddrTransType = new AddrTransType + // trace + val trapTraceInfo = ValidIO(new TraceTrap) // custom val custom = new CSRCustomState val criticalErrorState = Bool() @@ -1108,6 +1111,17 @@ class NewCSR(implicit val p: Parameters) extends Module * debug_end */ + // 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, + Priv.D, + Mux1H(privState1HForTrace, privStateForTrace) + ) + 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)) + /** * 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 88d59b0a9c..dec76248b7 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala @@ -309,6 +309,9 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) csrOut.debugMode := csrMod.io.status.debugMode + // todo: trace + csrOut.trapTraceInfo := csrMod.io.status.trapTraceInfo + csrOut.customCtrl match { case custom => custom.l1I_pf_enable := csrMod.io.status.custom.l1I_pf_enable diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index 510285e55b..0cb1c6eb35 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -73,6 +73,10 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP val writebackNums = Flipped(Vec(writeback.size - params.StdCnt, ValidIO(UInt(writeback.size.U.getWidth.W)))) val writebackNeedFlush = Input(Vec(params.allExuParams.filter(_.needExceptionGen).length, Bool())) val commits = Output(new RobCommitIO) + val trace = new Bundle { + val blockCommit = Input(Bool()) + val traceCommitInfo = new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthInPipe) + } val rabCommits = Output(new RabCommitIO) val diffCommits = if (backendParams.basicDebugEn) Some(Output(new DiffCommitIO)) else None val isVsetFlushPipe = Output(Bool()) @@ -737,8 +741,9 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP }.elsewhen(deqNeedFlush && io.flushOut.valid && !io.flushOut.bits.flushItself()){ deqHasFlushed := true.B } + val traceBlock = io.trace.blockCommit val blockCommit = misPredBlock || lastCycleFlush || hasWFI || io.redirect.valid || - (deqNeedFlush && !deqHasFlushed) || deqFlushBlock || criticalErrorState + (deqNeedFlush && !deqHasFlushed) || deqFlushBlock || criticalErrorState || traceBlock io.commits.isWalk := state === s_walk io.commits.isCommit := state === s_idle && !blockCommit @@ -1213,6 +1218,51 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP io.toVecExcpMod.logicPhyRegMap := rab.io.toVecExcpMod.logicPhyRegMap io.toVecExcpMod.excpInfo := vecExcpInfo + /** + * trace + */ + val trapTraceInfoFromCsr = io.csr.traceTrapInfo + + // trace output + val traceTrap = io.trace.traceCommitInfo.trap + 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).iretire := Mux(io.commits.isCommit && io.commits.commitValid(i), rawInfo(i).traceBlockInPipe.iretire, 0.U) + traceBlockInPipe(i).ilastsize := rawInfo(i).traceBlockInPipe.ilastsize + } + + for (i <- 0 until CommitWidth) { + val iretire = traceBlocks(i).bits.tracePipe.iretire + val itype = traceBlocks(i).bits.tracePipe.itype + traceValids(i) := iretire =/= 0.U + } + + val t_idle :: t_waiting :: Nil = Enum(2) + val traceState = RegInit(t_idle) + when(traceState === t_idle){ + when(io.exception.valid){ + traceState := t_waiting + } + }.elsewhen(traceState === t_waiting){ + when(trapTraceInfoFromCsr.valid){ + traceState := t_idle + + traceBlocks(0).bits.tracePipe.itype := Mux(io.exception.bits.isInterrupt, + Itype.Interrupt, + Itype.Exception + ) + traceValids(0) := true.B + } + } + /** * debug info */ diff --git a/src/main/scala/xiangshan/backend/rob/RobBundles.scala b/src/main/scala/xiangshan/backend/rob/RobBundles.scala index ac1dc82b76..9ed5d83857 100644 --- a/src/main/scala/xiangshan/backend/rob/RobBundles.scala +++ b/src/main/scala/xiangshan/backend/rob/RobBundles.scala @@ -64,7 +64,7 @@ object RobBundles extends HasCircularQueuePtrHelper { // data end // trace - val traceBlockInPipe = new TracePipe(log2Up(RenameWidth * 2)) + val traceBlockInPipe = new TracePipe(IretireWidthInPipe) // status begin val valid = Bool() val fflags = UInt(5.W) @@ -111,7 +111,7 @@ object RobBundles extends HasCircularQueuePtrHelper { val rfWen = Bool() val needFlush = Bool() // trace - val traceBlockInPipe = new TracePipe(log2Up(RenameWidth * 2)) + val traceBlockInPipe = new TracePipe(IretireWidthInPipe) // debug_begin val debug_pc = OptionWrapper(backendParams.debugEn, UInt(VAddrBits.W)) val debug_instr = OptionWrapper(backendParams.debugEn, UInt(32.W)) @@ -217,6 +217,7 @@ class RobCSRIO(implicit p: Parameters) extends XSBundle { val isXRet = Input(Bool()) val wfiEvent = Input(Bool()) val criticalErrorState = Input(Bool()) + val traceTrapInfo = Flipped(ValidIO(new TraceTrap)) 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 a765ed4d79..b93f1479e1 100644 --- a/src/main/scala/xiangshan/backend/trace/Interface.scala +++ b/src/main/scala/xiangshan/backend/trace/Interface.scala @@ -8,8 +8,8 @@ import xiangshan.HasXSParameter import xiangshan.frontend.{BrType, FtqPtr, PreDecodeInfo} class TraceTrap(implicit val p: Parameters) extends Bundle with HasXSParameter { - val cause = UInt(XLEN.W) - val tval = UInt(XLEN.W) + val cause = UInt(CauseWidth.W) + val tval = UInt(TvalWidth.W) val priv = Priv() } @@ -20,9 +20,9 @@ class TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle wi } class TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { - val iaddr = if (hasIaddr) Some(UInt(XLEN.W)) else None + val iaddr = if (hasIaddr) Some(UInt(IaddrWidth.W)) else None val ftqIdx = if (!hasIaddr) Some(new FtqPtr) else None - val ftqOffset = if (!hasIaddr) Some( UInt(log2Up(PredictWidth).W)) else None + val ftqOffset = if (!hasIaddr) Some(UInt(log2Up(PredictWidth).W)) else None val tracePipe = new TracePipe(iretireWidth) } @@ -37,17 +37,6 @@ class FromEncoder extends Bundle { } class TraceCoreInterface(implicit val p: Parameters) extends Bundle with HasXSParameter { - // parameter - val CauseWidth = XLEN - val TvalWidth = XLEN - val PrivWidth = 3 - val IaddrWidth = XLEN - val ItypeWidth = 4 - val IretireWidthInPipe = log2Up(RenameWidth * 2) - val IretireWidthCompressed = log2Up(RenameWidth * CommitWidth * 2) - val IlastsizeWidth = 1 - val GroupNum = TraceGroupNum - val fromEncoder = Input(new Bundle { val enable = Bool() val stall = Bool() @@ -56,10 +45,10 @@ class TraceCoreInterface(implicit val p: Parameters) extends Bundle with HasXSPa val cause = UInt(CauseWidth.W) val tval = UInt(TvalWidth.W) val priv = UInt(PrivWidth.W) - val iaddr = UInt((GroupNum * IaddrWidth).W) - val itype = UInt((GroupNum * ItypeWidth).W) - val iretire = UInt((GroupNum * IretireWidthCompressed).W) - val ilastsize = UInt((GroupNum * IlastsizeWidth).W) + val iaddr = UInt((TraceGroupNum * IaddrWidth).W) + val itype = UInt((TraceGroupNum * ItypeWidth).W) + val iretire = UInt((TraceGroupNum * IretireWidthCompressed).W) + val ilastsize = UInt((TraceGroupNum * IlastsizeWidth).W) }) } diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala new file mode 100644 index 0000000000..153baa5d11 --- /dev/null +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -0,0 +1,85 @@ +package xiangshan.backend.trace + +import chisel3._ +import chisel3.util.{RegEnable, ValidIO, log2Up} +import org.chipsalliance.cde.config.Parameters +import xiangshan.HasXSParameter + +class TraceParams( + val TraceGroupNum : Int, + val HasEncoder : Boolean, + val TraceEnable : Boolean, +) + +class TraceIO(implicit val p: Parameters) extends Bundle with HasXSParameter { + val fromEncoder = Input(new FromEncoder) + val fromRob = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthInPipe)) + val blockRobCommit = Output(Bool()) + val toPcMem = Vec(TraceGroupNum, ValidIO(new TraceBlock(false, IretireWidthCompressed))) + val fromPcMem = Input(Vec(TraceGroupNum, UInt(IaddrWidth.W))) + val toEncoder = new TraceBundle(hasIaddr = true, TraceGroupNum, IretireWidthCompressed) +} + +class Trace(implicit val p: Parameters) extends Module with HasXSParameter { + val io = IO(new TraceIO) + val (fromEncoder, fromRob, toPcMem, fromPcMem, toEncoder) = (io.fromEncoder, io.fromRob, io.toPcMem, io.fromPcMem, io.toEncoder) + + /** + * stage 0: CommitInfo from rob + */ + val blockCommit = Wire(Bool()) + io.blockRobCommit := blockCommit + + /** + * stage 1: regNext(robCommitInfo) + */ + val s1_in = fromRob + val s1_out = WireInit(0.U.asTypeOf(s1_in)) + + for(i <- 0 until CommitWidth) { + if(i == 0){ + s1_out.trap := RegEnable(s1_in.trap, s1_in.blocks(i).valid) + } + s1_out.blocks(i).valid := RegEnable(s1_in.blocks(i).valid, !blockCommit) + s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, s1_in.blocks(i).valid) + } + + /** + * stage 2: compress, s2_out(deq from traceBuffer) -> pcMem + */ + val s2_in = s1_out + 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 + 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_out_trap = RegNext(s3_in_trap) + val s3_out_block = RegNext(s3_in_block) + + toPcMem := s3_in_block + + io.toEncoder := DontCare + for(i <- 0 until TraceGroupNum) { + toEncoder.trap := s3_out_trap + toEncoder.blocks(i).bits.iaddr.foreach(_ := fromPcMem(i)) + toEncoder.blocks(i).valid := s3_out_block(i).valid + toEncoder.blocks(i).bits.tracePipe := s3_out_block(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 new file mode 100644 index 0000000000..21c3954c78 --- /dev/null +++ b/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala @@ -0,0 +1,118 @@ +package xiangshan.backend.trace + +import chisel3._ +import chisel3.util._ +import org.chipsalliance.cde.config.Parameters +import utility.{CircularQueuePtr, HasCircularQueuePtrHelper} +import xiangshan.{HasXSParameter, XSCoreParamsKey} + +class TraceBuffer(implicit val p: Parameters) extends Module + with HasXSParameter + with HasCircularQueuePtrHelper { + + val io = IO(new Bundle { + val in = new Bundle{ + val fromEncoder = Input(new FromEncoder) + val fromRob = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthCompressed)) + } + + val out = new Bundle { // output groups to pcMem + val blockCommit = Output(Bool()) + val groups = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed) + } + }) + + // buffer: compress info from robCommit + val traceTrap = Reg(new TraceTrap) + val traceEntries = Reg(Vec(CommitWidth, ValidIO(new TraceBlock(false, IretireWidthCompressed)))) + traceTrap := io.in.fromRob.trap + + val blockCommit = RegInit(false.B) // to rob + + /** + * compress, update blocks + */ + val inValidVec = VecInit(io.in.fromRob.blocks.map(_.valid)) + val inTypeIsNotNoneVec = VecInit(io.in.fromRob.blocks.map(block => Itype.isNotNone(block.bits.tracePipe.itype))) + val needPcVec = Wire(Vec(CommitWidth, Bool())) + for(i <- 0 until CommitWidth) { + val rightHasValid = if(i == CommitWidth - 1) false.B else (inValidVec.asUInt(CommitWidth-1, i+1).orR) + needPcVec(i) := inValidVec(i) & (inTypeIsNotNoneVec(i) || !rightHasValid) & !blockCommit + } + + val blocksUpdate = WireInit(io.in.fromRob.blocks) + for(i <- 1 until CommitWidth){ + when(!needPcVec(i-1)){ + blocksUpdate(i).bits.tracePipe.iretire := blocksUpdate(i - 1).bits.tracePipe.iretire + io.in.fromRob.blocks(i).bits.tracePipe.iretire + blocksUpdate(i).bits.ftqOffset.get := blocksUpdate(i - 1).bits.ftqOffset.get + blocksUpdate(i).bits.ftqIdx.get := blocksUpdate(i - 1).bits.ftqIdx.get + } + } + + /** + * enq to traceEntries + */ + val countVec = VecInit((0 until CommitWidth).map(i => PopCount(needPcVec.asUInt(i, 0)))) + val numNeedPc = countVec(CommitWidth-1) + + val enqPtr = RegInit(TracePtr(false.B, 0.U)) + val deqPtr = RegInit(TracePtr(false.B, 0.U)) + val deqPtrPre = RegNext(deqPtr) + val enqPtrNext = WireInit(enqPtr) + val deqPtrNext = WireInit(deqPtr) + enqPtr := enqPtrNext + deqPtr := deqPtrNext + val canNotTraceAll = distanceBetween(enqPtrNext, deqPtrNext) > 0.U + blockCommit := io.in.fromEncoder.enable && (canNotTraceAll || io.in.fromEncoder.stall) + + enqPtrNext := enqPtr + numNeedPc + deqPtrNext := Mux(deqPtr + TraceGroupNum.U > enqPtrNext, enqPtrNext, deqPtr + TraceGroupNum.U) + + val traceIdxVec = VecInit(countVec.map(count => (enqPtr + count - 1.U).value)) + + for(i <- 0 until CommitWidth){ + when(needPcVec(i)){ + traceEntries(traceIdxVec(i)) := blocksUpdate(i) + } + } + + /** + * deq from traceEntries + */ + val blockOut = WireInit(0.U.asTypeOf(io.out.groups)) + blockOut.trap := traceTrap + for(i <- 0 until TraceGroupNum) { + when(deqPtrPre + i.U < enqPtr) { + blockOut.blocks(i) := traceEntries((deqPtrPre + i.U).value) + } .otherwise { + blockOut.blocks(i).valid := false.B + } + } + + if(backendParams.debugEn){ + dontTouch(countVec) + dontTouch(numNeedPc) + dontTouch(traceIdxVec) + } + + io.out.blockCommit := blockCommit + io.out.groups := blockOut + +} + +class TracePtr(entries: Int) extends CircularQueuePtr[TracePtr]( + entries +) with HasCircularQueuePtrHelper { + + def this()(implicit p: Parameters) = this(p(XSCoreParamsKey).CommitWidth) + +} + +object TracePtr { + def apply(f: Bool, v: UInt)(implicit p: Parameters): TracePtr = { + val ptr = Wire(new TracePtr) + ptr.flag := f + ptr.value := v + ptr + } +} \ No newline at end of file From 80dc81eab79d3b384678fcd1fc259df7dc229f71 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 19 Sep 2024 18:29:08 +0800 Subject: [PATCH 02/13] feat(trace): add TraceCoreInterface in top. --- src/main/scala/system/SoC.scala | 10 ++++++++++ src/main/scala/top/Top.scala | 17 +++++++++++++++++ src/main/scala/top/XSNoCTop.scala | 17 +++++++++++++++++ src/main/scala/xiangshan/Parameters.scala | 15 +++++++++------ src/main/scala/xiangshan/XSCore.scala | 3 +++ src/main/scala/xiangshan/XSTile.scala | 3 +++ src/main/scala/xiangshan/XSTileWrap.scala | 3 +++ .../scala/xiangshan/backend/trace/Trace.scala | 9 ++++++--- src/test/scala/top/SimTop.scala | 2 ++ 9 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/main/scala/system/SoC.scala b/src/main/scala/system/SoC.scala index 003e5e7925..d6c5d79991 100644 --- a/src/main/scala/system/SoC.scala +++ b/src/main/scala/system/SoC.scala @@ -98,6 +98,16 @@ trait HasSoCParameter { val NumCores = tiles.size val EnableILA = soc.EnableILA + // Parameters for trace extension + val TraceTraceGroupNum = tiles.head.traceParams.TraceGroupNum + val TraceCauseWidth = tiles.head.XLEN + val TraceTvalWidth = tiles.head.XLEN + val TracePrivWidth = tiles.head.traceParams.PrivWidth + val TraceIaddrWidth = tiles.head.XLEN + val TraceItypeWidth = tiles.head.traceParams.ItypeWidth + val TraceIretireWidthCompressed = log2Up(tiles.head.RenameWidth * tiles.head.CommitWidth * 2) + val TraceIlastsizeWidth = tiles.head.traceParams.IlastsizeWidth + // L3 configurations val L3InnerBusWidth = soc.L3InnerBusWidth val L3BlockSize = soc.L3BlockSize diff --git a/src/main/scala/top/Top.scala b/src/main/scala/top/Top.scala index 176b04e529..c8416d239b 100644 --- a/src/main/scala/top/Top.scala +++ b/src/main/scala/top/Top.scala @@ -256,6 +256,21 @@ class XSTop()(implicit p: Parameters) extends BaseXSSoc() with HasSoCParameter val riscv_halt = Output(Vec(NumCores, Bool())) val riscv_critical_error = Output(Vec(NumCores, Bool())) val riscv_rst_vec = Input(Vec(NumCores, UInt(soc.PAddrBits.W))) + val traceCoreInterface = Vec(NumCores, new Bundle { + val fromEncoder = Input(new Bundle { + val enable = Bool() + val stall = Bool() + }) + val toEncoder = Output(new Bundle { + val cause = UInt(TraceCauseWidth.W) + val tval = UInt(TraceTvalWidth.W) + val priv = UInt(TracePrivWidth.W) + val iaddr = UInt((TraceTraceGroupNum * TraceIaddrWidth).W) + val itype = UInt((TraceTraceGroupNum * TraceItypeWidth).W) + val iretire = UInt((TraceTraceGroupNum * TraceIretireWidthCompressed).W) + val ilastsize = UInt((TraceTraceGroupNum * TraceIlastsizeWidth).W) + }) + }) }) val reset_sync = withClockAndReset(io.clock.asClock, io.reset) { ResetGen() } @@ -294,6 +309,8 @@ class XSTop()(implicit p: Parameters) extends BaseXSSoc() with HasSoCParameter core.module.io.clintTime := misc.module.clintTime io.riscv_halt(i) := core.module.io.cpu_halt io.riscv_critical_error(i) := core.module.io.cpu_crtical_error + io.traceCoreInterface(i).toEncoder := core.module.io.traceCoreInterface.toEncoder + core.module.io.traceCoreInterface.fromEncoder := io.traceCoreInterface(i).fromEncoder core.module.io.reset_vector := io.riscv_rst_vec(i) } diff --git a/src/main/scala/top/XSNoCTop.scala b/src/main/scala/top/XSNoCTop.scala index 0eac365e1c..6e4a0205ed 100644 --- a/src/main/scala/top/XSNoCTop.scala +++ b/src/main/scala/top/XSNoCTop.scala @@ -116,6 +116,21 @@ class XSNoCTop()(implicit p: Parameters) extends BaseXSSoc with HasSoCParameter val chi = new PortIO val nodeID = Input(UInt(soc.NodeIDWidthList(issue).W)) val clintTime = Input(ValidIO(UInt(64.W))) + val traceCoreInterface = new Bundle { + val fromEncoder = Input(new Bundle { + val enable = Bool() + val stall = Bool() + }) + val toEncoder = Output(new Bundle { + val cause = UInt(TraceCauseWidth.W) + val tval = UInt(TraceTvalWidth.W) + val priv = UInt(TracePrivWidth.W) + val iaddr = UInt((TraceTraceGroupNum * TraceIaddrWidth).W) + val itype = UInt((TraceTraceGroupNum * TraceItypeWidth).W) + val iretire = UInt((TraceTraceGroupNum * TraceIretireWidthCompressed).W) + val ilastsize = UInt((TraceTraceGroupNum * TraceIlastsizeWidth).W) + }) + } }) // imsic axi4lite io val imsic_axi4lite = wrapper.u_imsic_bus_top.module.axi4lite.map(x => IO(chiselTypeOf(x))) @@ -150,6 +165,8 @@ class XSNoCTop()(implicit p: Parameters) extends BaseXSSoc with HasSoCParameter io.riscv_critical_error := core_with_l2.module.io.cpu_crtical_error io.hartIsInReset := core_with_l2.module.io.hartIsInReset core_with_l2.module.io.reset_vector := io.riscv_rst_vec + io.traceCoreInterface.toEncoder := core_with_l2.module.io.traceCoreInterface.toEncoder + core_with_l2.module.io.traceCoreInterface.fromEncoder := io.traceCoreInterface.fromEncoder EnableClintAsyncBridge match { case Some(param) => diff --git a/src/main/scala/xiangshan/Parameters.scala b/src/main/scala/xiangshan/Parameters.scala index bf4f54d2ed..cfbcc5a2db 100644 --- a/src/main/scala/xiangshan/Parameters.scala +++ b/src/main/scala/xiangshan/Parameters.scala @@ -545,9 +545,12 @@ case class XSCoreParameters // Parameters for trace extension. // Trace parameters is useful for XSTOP. val traceParams: TraceParams = new TraceParams( - TraceGroupNum = 3, // Width to Encoder - HasEncoder = true, - TraceEnable = true, + HasEncoder = true, + TraceEnable = true, + TraceGroupNum = 3, + PrivWidth = 3, + ItypeWidth = 4, + IlastsizeWidth = 1, ) } @@ -895,10 +898,10 @@ trait HasXSParameter { def TraceEnable = coreParams.traceParams.TraceEnable def CauseWidth = XLEN def TvalWidth = XLEN - def PrivWidth = 3 + def PrivWidth = coreParams.traceParams.PrivWidth def IaddrWidth = XLEN - def ItypeWidth = 4 + def ItypeWidth = coreParams.traceParams.ItypeWidth def IretireWidthInPipe = log2Up(RenameWidth * 2) def IretireWidthCompressed = log2Up(RenameWidth * CommitWidth * 2) - def IlastsizeWidth = 1 + def IlastsizeWidth = coreParams.traceParams.IlastsizeWidth } diff --git a/src/main/scala/xiangshan/XSCore.scala b/src/main/scala/xiangshan/XSCore.scala index b52ba4bcf5..f12c0deb33 100644 --- a/src/main/scala/xiangshan/XSCore.scala +++ b/src/main/scala/xiangshan/XSCore.scala @@ -28,6 +28,7 @@ import utils._ import utility._ import xiangshan.backend._ import xiangshan.backend.fu.PMPRespBundle +import xiangshan.backend.trace.TraceCoreInterface import xiangshan.cache.mmu._ import xiangshan.frontend._ import xiangshan.mem.L1PrefetchFuzzer @@ -84,6 +85,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) val cpu_halt = Output(Bool()) val cpu_critical_error = Output(Bool()) val resetInFrontend = Output(Bool()) + val traceCoreInterface = new TraceCoreInterface val l2_pf_enable = Output(Bool()) val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks + 1, new PerfEvent)) val beu_errors = Output(new XSL1BusErrors()) @@ -240,6 +242,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) io.cpu_halt := memBlock.io.outer_cpu_halt io.cpu_critical_error := memBlock.io.outer_cpu_critical_error + io.traceCoreInterface <> backend.io.traceCoreInterface io.beu_errors.icache <> memBlock.io.outer_beu_errors_icache io.beu_errors.dcache <> memBlock.io.error.bits.toL1BusErrorUnitInfo(memBlock.io.error.valid) io.beu_errors.l2 <> DontCare diff --git a/src/main/scala/xiangshan/XSTile.scala b/src/main/scala/xiangshan/XSTile.scala index 07776dd595..018fa5ec54 100644 --- a/src/main/scala/xiangshan/XSTile.scala +++ b/src/main/scala/xiangshan/XSTile.scala @@ -30,6 +30,7 @@ import top.{BusPerfMonitor, ArgParser, Generator} import utility.{DelayN, ResetGen, TLClientsMerger, TLEdgeBuffer, TLLogger, Constantin, ChiselDB, FileRegisters} import coupledL2.EnableCHI import coupledL2.tl2chi.PortIO +import xiangshan.backend.trace.TraceCoreInterface class XSTile()(implicit p: Parameters) extends LazyModule with HasXSParameter @@ -113,6 +114,7 @@ class XSTile()(implicit p: Parameters) extends LazyModule val cpu_halt = Output(Bool()) val cpu_crtical_error = Output(Bool()) val hartIsInReset = Output(Bool()) + val traceCoreInterface = new TraceCoreInterface val debugTopDown = new Bundle { val robHeadPaddr = Valid(UInt(PAddrBits.W)) val l3MissMatch = Input(Bool()) @@ -141,6 +143,7 @@ class XSTile()(implicit p: Parameters) extends LazyModule l2top.module.io.hartIsInReset.resetInFrontend := core.module.io.resetInFrontend io.hartIsInReset := l2top.module.io.hartIsInReset.toTile + io.traceCoreInterface <> core.module.io.traceCoreInterface l2top.module.io.beu_errors.icache <> core.module.io.beu_errors.icache l2top.module.io.beu_errors.dcache <> core.module.io.beu_errors.dcache diff --git a/src/main/scala/xiangshan/XSTileWrap.scala b/src/main/scala/xiangshan/XSTileWrap.scala index 1a2477279c..3ce65b1ad9 100644 --- a/src/main/scala/xiangshan/XSTileWrap.scala +++ b/src/main/scala/xiangshan/XSTileWrap.scala @@ -26,6 +26,7 @@ import system.HasSoCParameter import device.{IMSICAsync, MsiInfoBundle} import coupledL2.tl2chi.{PortIO, AsyncPortIO, CHIAsyncBridgeSource} import utility.{IntBuffer, ResetGen} +import xiangshan.backend.trace.TraceCoreInterface // This module is used for XSNoCTop for async time domain and divide different // voltage domain. Everything in this module should be in the core clock domain @@ -61,6 +62,7 @@ class XSTileWrap()(implicit p: Parameters) extends LazyModule val cpu_halt = Output(Bool()) val cpu_crtical_error = Output(Bool()) val hartIsInReset = Output(Bool()) + val traceCoreInterface = new TraceCoreInterface val debugTopDown = new Bundle { val robHeadPaddr = Valid(UInt(PAddrBits.W)) val l3MissMatch = Input(Bool()) @@ -93,6 +95,7 @@ class XSTileWrap()(implicit p: Parameters) extends LazyModule io.cpu_halt := tile.module.io.cpu_halt io.cpu_crtical_error := tile.module.io.cpu_crtical_error io.hartIsInReset := tile.module.io.hartIsInReset + io.traceCoreInterface <> tile.module.io.traceCoreInterface io.debugTopDown <> tile.module.io.debugTopDown tile.module.io.nodeID.foreach(_ := io.nodeID.get) diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index 153baa5d11..7b5a88f242 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -6,9 +6,12 @@ import org.chipsalliance.cde.config.Parameters import xiangshan.HasXSParameter class TraceParams( - val TraceGroupNum : Int, - val HasEncoder : Boolean, - val TraceEnable : Boolean, + val HasEncoder : Boolean, + val TraceEnable : Boolean, + val TraceGroupNum : Int, + val PrivWidth : Int, + val ItypeWidth : Int, + val IlastsizeWidth : Int, ) class TraceIO(implicit val p: Parameters) extends Bundle with HasXSParameter { diff --git a/src/test/scala/top/SimTop.scala b/src/test/scala/top/SimTop.scala index ed9343b40b..029a206944 100644 --- a/src/test/scala/top/SimTop.scala +++ b/src/test/scala/top/SimTop.scala @@ -66,6 +66,8 @@ class SimTop(implicit p: Parameters) extends Module { soc.io.cacheable_check := DontCare soc.io.riscv_rst_vec.foreach(_ := 0x10000000L.U) l_soc.nmi.foreach(_.foreach(intr => { intr := false.B; dontTouch(intr) })) + soc.io.traceCoreInterface.foreach(_.fromEncoder.enable := false.B) + soc.io.traceCoreInterface.foreach(_.fromEncoder.stall := false.B) // soc.io.rtc_clock is a div100 of soc.io.clock val rtcClockDiv = 100 From 6035f2ff9f84972df1e839edfb6d9d0269bbae5f Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Fri, 20 Sep 2024 16:00:59 +0800 Subject: [PATCH 03/13] feat(trace): remove useless code & fix trap update in trace. --- src/main/scala/xiangshan/backend/CtrlBlock.scala | 4 +++- src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala | 1 - src/main/scala/xiangshan/backend/trace/Trace.scala | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index 3bfc6b6ef6..415c940dde 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -259,7 +259,9 @@ class CtrlBlockImp( trace.io.fromRob := rob.io.trace.traceCommitInfo rob.io.trace.blockCommit := trace.io.blockRobCommit - dontTouch(trace.io.toEncoder) + if(backendParams.debugEn){ + dontTouch(trace.io.toEncoder) + } for ((pcMemIdx, i) <- pcMemRdIndexes("trace").zipWithIndex) { val traceValid = trace.toPcMem(i).valid diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala index dec76248b7..6d63296f12 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala @@ -309,7 +309,6 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) csrOut.debugMode := csrMod.io.status.debugMode - // todo: trace csrOut.trapTraceInfo := csrMod.io.status.trapTraceInfo csrOut.customCtrl match { diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index 7b5a88f242..2aa538c773 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -40,9 +40,8 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { val s1_out = WireInit(0.U.asTypeOf(s1_in)) for(i <- 0 until CommitWidth) { - if(i == 0){ - s1_out.trap := RegEnable(s1_in.trap, s1_in.blocks(i).valid) - } + // Trap only occor in block(0). + s1_out.trap := RegEnable(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, !blockCommit) s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, s1_in.blocks(i).valid) } From f93a823fd379786821f9b85c295eeb765d7f3b3c Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Mon, 14 Oct 2024 13:29:47 +0800 Subject: [PATCH 04/13] fix(trace): fix signal toEncoder in Trace --- src/main/scala/xiangshan/backend/trace/Trace.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index 2aa538c773..b19d6d547d 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -41,9 +41,9 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { for(i <- 0 until CommitWidth) { // Trap only occor in block(0). - s1_out.trap := RegEnable(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, !blockCommit) - s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, s1_in.blocks(i).valid) + 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) + s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, 0.U.asTypeOf(s1_in.blocks(i).bits), s1_in.blocks(i).valid) } /** @@ -68,11 +68,10 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { toPcMem := s3_in_block - io.toEncoder := DontCare for(i <- 0 until TraceGroupNum) { toEncoder.trap := s3_out_trap - toEncoder.blocks(i).bits.iaddr.foreach(_ := fromPcMem(i)) 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 } if(backendParams.debugEn){ From 07340477a0d2f9930d567c027d44bbf550405990 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Wed, 23 Oct 2024 15:09:26 +0800 Subject: [PATCH 05/13] fix(trace): fix itype for branch & jump inst --- src/main/scala/xiangshan/backend/rob/Rob.scala | 6 +++--- src/main/scala/xiangshan/backend/trace/Interface.scala | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index 0cb1c6eb35..9b27b070d0 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -1040,9 +1040,9 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP when(xret){ robEntries(i).traceBlockInPipe.itype := Itype.ExpIntReturn - }.elsewhen(Itype.isBranchType(robEntries(i).traceBlockInPipe.itype)){ - // BranchType code(itype = 5) must be correctly replaced! - robEntries(i).traceBlockInPipe.itype := Mux(taken, Itype.Taken, Itype.NonTaken) + }.elsewhen(Itype.isBranchType(robEntries(i).traceBlockInPipe.itype) && taken){ + // BranchType code(notaken itype = 4) must be correctly replaced! + robEntries(i).traceBlockInPipe.itype := Itype.Taken } } diff --git a/src/main/scala/xiangshan/backend/trace/Interface.scala b/src/main/scala/xiangshan/backend/trace/Interface.scala index b93f1479e1..72a6ac3b52 100644 --- a/src/main/scala/xiangshan/backend/trace/Interface.scala +++ b/src/main/scala/xiangshan/backend/trace/Interface.scala @@ -70,8 +70,8 @@ object Itype extends NamedUInt(4) { def OtherUninferableJump = 14.U //rename def OtherInferableJump = 15.U //rename - // Assuming the branchType is taken here, it will be correctly modified after writeBack. - def Branch = 5.U + // Assuming the branchType is NonTaken here, it will be correctly modified after writeBack. + def Branch = NonTaken def jumpTypeGen(brType: UInt, rd: OpRegType, rs: OpRegType): UInt = { @@ -144,9 +144,9 @@ object Priv extends NamedUInt(3) { } class OpRegType extends Bundle { - val value = UInt(3.W) + val value = UInt(6.W) def isX0 = this.value === 0.U def isX1 = this.value === 1.U def isX5 = this.value === 5.U - def isLink = Seq(isX1, isX5).map(_ === this.value).reduce(_ || _) + def isLink = Seq(isX1, isX5).reduce(_ || _) } From d9cd468a7d40445aa5315e88c62873d512eedafb Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 24 Oct 2024 13:14:49 +0800 Subject: [PATCH 06/13] fix(trace): fix width of iaddr --- src/main/scala/system/SoC.scala | 4 ++-- src/main/scala/xiangshan/Parameters.scala | 5 +++-- src/main/scala/xiangshan/backend/trace/Trace.scala | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/scala/system/SoC.scala b/src/main/scala/system/SoC.scala index d6c5d79991..729c6dea55 100644 --- a/src/main/scala/system/SoC.scala +++ b/src/main/scala/system/SoC.scala @@ -101,9 +101,9 @@ trait HasSoCParameter { // Parameters for trace extension val TraceTraceGroupNum = tiles.head.traceParams.TraceGroupNum val TraceCauseWidth = tiles.head.XLEN - val TraceTvalWidth = tiles.head.XLEN + val TraceTvalWidth = tiles.head.traceParams.IaddrWidth val TracePrivWidth = tiles.head.traceParams.PrivWidth - val TraceIaddrWidth = tiles.head.XLEN + val TraceIaddrWidth = tiles.head.traceParams.IaddrWidth val TraceItypeWidth = tiles.head.traceParams.ItypeWidth val TraceIretireWidthCompressed = log2Up(tiles.head.RenameWidth * tiles.head.CommitWidth * 2) val TraceIlastsizeWidth = tiles.head.traceParams.IlastsizeWidth diff --git a/src/main/scala/xiangshan/Parameters.scala b/src/main/scala/xiangshan/Parameters.scala index cfbcc5a2db..9635b67f82 100644 --- a/src/main/scala/xiangshan/Parameters.scala +++ b/src/main/scala/xiangshan/Parameters.scala @@ -548,6 +548,7 @@ case class XSCoreParameters HasEncoder = true, TraceEnable = true, TraceGroupNum = 3, + IaddrWidth = GPAddrBitsSv48x4, PrivWidth = 3, ItypeWidth = 4, IlastsizeWidth = 1, @@ -897,9 +898,9 @@ trait HasXSParameter { def HasEncoder = coreParams.traceParams.HasEncoder def TraceEnable = coreParams.traceParams.TraceEnable def CauseWidth = XLEN - def TvalWidth = XLEN + def TvalWidth = coreParams.traceParams.IaddrWidth def PrivWidth = coreParams.traceParams.PrivWidth - def IaddrWidth = XLEN + def IaddrWidth = coreParams.traceParams.IaddrWidth def ItypeWidth = coreParams.traceParams.ItypeWidth def IretireWidthInPipe = log2Up(RenameWidth * 2) def IretireWidthCompressed = log2Up(RenameWidth * CommitWidth * 2) diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index b19d6d547d..02f1edf388 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -9,6 +9,7 @@ class TraceParams( val HasEncoder : Boolean, val TraceEnable : Boolean, val TraceGroupNum : Int, + val IaddrWidth : Int, val PrivWidth : Int, val ItypeWidth : Int, val IlastsizeWidth : Int, From ebb4f62c174fca1b84bcb40473f97060b3a41beb Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Wed, 30 Oct 2024 11:00:44 +0800 Subject: [PATCH 07/13] fix(trace): add traceCoreInterface in memblock --- src/main/scala/xiangshan/L2Top.scala | 6 ++++++ src/main/scala/xiangshan/XSCore.scala | 3 +++ src/main/scala/xiangshan/XSTile.scala | 3 ++- src/main/scala/xiangshan/backend/MemBlock.scala | 6 ++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/scala/xiangshan/L2Top.scala b/src/main/scala/xiangshan/L2Top.scala index 6b037aaacf..f424abbb10 100644 --- a/src/main/scala/xiangshan/L2Top.scala +++ b/src/main/scala/xiangshan/L2Top.scala @@ -33,6 +33,7 @@ import top.BusPerfMonitor import utility._ import xiangshan.cache.mmu.TlbRequestIO import xiangshan.backend.fu.PMPRespBundle +import xiangshan.backend.trace.TraceCoreInterface class L1BusErrorUnitInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter { val ecc_error = Valid(UInt(soc.PAddrBits.W)) @@ -161,6 +162,10 @@ class L2TopInlined()(implicit p: Parameters) extends LazyModule val resetInFrontend = Input(Bool()) val toTile = Output(Bool()) } + val traceCoreInterface = new Bundle{ + val fromCore = Flipped(new TraceCoreInterface) + val toTile = new TraceCoreInterface + } val debugTopDown = new Bundle() { val robTrueCommit = Input(UInt(64.W)) val robHeadPaddr = Flipped(Valid(UInt(36.W))) @@ -183,6 +188,7 @@ class L2TopInlined()(implicit p: Parameters) extends LazyModule io.hartId.toCore := io.hartId.fromTile io.cpu_halt.toTile := io.cpu_halt.fromCore io.cpu_critical_error.toTile := io.cpu_critical_error.fromCore + io.traceCoreInterface.toTile <> io.traceCoreInterface.fromCore dontTouch(io.hartId) dontTouch(io.cpu_halt) dontTouch(io.cpu_critical_error) diff --git a/src/main/scala/xiangshan/XSCore.scala b/src/main/scala/xiangshan/XSCore.scala index f12c0deb33..26fd829d75 100644 --- a/src/main/scala/xiangshan/XSCore.scala +++ b/src/main/scala/xiangshan/XSCore.scala @@ -250,6 +250,9 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) memBlock.io.resetInFrontendBypass.fromFrontend := frontend.io.resetInFrontend io.resetInFrontend := memBlock.io.resetInFrontendBypass.toL2Top + memBlock.io.traceCoreInterfaceBypass.fromBackend <> backend.io.traceCoreInterface + io.traceCoreInterface <> memBlock.io.traceCoreInterfaceBypass.toL2Top + if (debugOpts.ResetGen) { backend.reset := memBlock.io.reset_backend diff --git a/src/main/scala/xiangshan/XSTile.scala b/src/main/scala/xiangshan/XSTile.scala index 018fa5ec54..06a01cd83e 100644 --- a/src/main/scala/xiangshan/XSTile.scala +++ b/src/main/scala/xiangshan/XSTile.scala @@ -143,7 +143,8 @@ class XSTile()(implicit p: Parameters) extends LazyModule l2top.module.io.hartIsInReset.resetInFrontend := core.module.io.resetInFrontend io.hartIsInReset := l2top.module.io.hartIsInReset.toTile - io.traceCoreInterface <> core.module.io.traceCoreInterface + l2top.module.io.traceCoreInterface.fromCore <> core.module.io.traceCoreInterface + io.traceCoreInterface <> l2top.module.io.traceCoreInterface.toTile l2top.module.io.beu_errors.icache <> core.module.io.beu_errors.icache l2top.module.io.beu_errors.dcache <> core.module.io.beu_errors.dcache diff --git a/src/main/scala/xiangshan/backend/MemBlock.scala b/src/main/scala/xiangshan/backend/MemBlock.scala index 1bbe0bd756..c744e6cdd3 100644 --- a/src/main/scala/xiangshan/backend/MemBlock.scala +++ b/src/main/scala/xiangshan/backend/MemBlock.scala @@ -46,6 +46,7 @@ import xiangshan.backend.datapath.NewPipelineConnect import system.SoCParamsKey import xiangshan.backend.fu.NewCSR.TriggerUtil import xiangshan.ExceptionNO._ +import xiangshan.backend.trace.TraceCoreInterface trait HasMemBlockParameters extends HasXSParameter { // number of memory units @@ -328,6 +329,10 @@ class MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer) val fromFrontend = Input(Bool()) val toL2Top = Output(Bool()) } + val traceCoreInterfaceBypass = new Bundle{ + val fromBackend = Flipped(new TraceCoreInterface) + val toL2Top = new TraceCoreInterface + } }) dontTouch(io.inner_hartId) @@ -1892,6 +1897,7 @@ class MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer) io.reset_backend := DontCare } io.resetInFrontendBypass.toL2Top := io.resetInFrontendBypass.fromFrontend + io.traceCoreInterfaceBypass.toL2Top <> io.traceCoreInterfaceBypass.fromBackend io.mem_to_ooo.storeDebugInfo := DontCare // store event difftest information From c60ee15def62e559ec871bddb7f8a2b7b010c1b6 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Wed, 30 Oct 2024 16:07:52 +0800 Subject: [PATCH 08/13] fix(trace): fix `ilastsize` & `iretire` for instruction fusion --- .../backend/rename/CompressUnit.scala | 2 ++ .../xiangshan/backend/rename/Rename.scala | 23 +++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/scala/xiangshan/backend/rename/CompressUnit.scala b/src/main/scala/xiangshan/backend/rename/CompressUnit.scala index c60a5ea78d..b03dea2a8a 100644 --- a/src/main/scala/xiangshan/backend/rename/CompressUnit.scala +++ b/src/main/scala/xiangshan/backend/rename/CompressUnit.scala @@ -42,6 +42,7 @@ class CompressUnit(implicit p: Parameters) extends XSModule{ val needRobFlags = Vec(RenameWidth, Output(Bool())) val instrSizes = Vec(RenameWidth, Output(UInt(log2Ceil(RenameWidth + 1).W))) val masks = Vec(RenameWidth, Output(UInt(RenameWidth.W))) + val canCompressVec = Vec(RenameWidth, Output(Bool())) } }) @@ -89,4 +90,5 @@ class CompressUnit(implicit p: Parameters) extends XSModule{ (io.out.needRobFlags ++ io.out.instrSizes ++ io.out.masks).zip(decoder).foreach { case (sink, source) => sink := source } + io.out.canCompressVec := VecInit(canCompress) } diff --git a/src/main/scala/xiangshan/backend/rename/Rename.scala b/src/main/scala/xiangshan/backend/rename/Rename.scala index e7a86f20d3..335b5bbe15 100644 --- a/src/main/scala/xiangshan/backend/rename/Rename.scala +++ b/src/main/scala/xiangshan/backend/rename/Rename.scala @@ -430,20 +430,25 @@ class Rename(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHe /** * trace begin */ + // note: fusionInst can't robcompress val inVec = io.in.map(_.bits) - val canRobCompressVec = inVec.map(_.canRobCompress) val isRVCVec = inVec.map(_.preDecodeInfo.isRVC) - val halfWordNumVec = (0 until RenameWidth).map{ - i => compressMasksVec(i).asBools.zip(isRVCVec).map{ - case (mask, isRVC) => Mux(mask, Mux(isRVC, 1.U, 2.U), 0.U) - } - } + val isFusionVec = inVec.map(_.commitType).map(ctype => CommitType.isFused(ctype)) + + val canRobCompressVec = compressUnit.io.out.canCompressVec + val iLastSizeVec = isRVCVec.map(isRVC => Mux(isRVC, Ilastsize.HalfWord, Ilastsize.Word)) + val halfWordNumVec = isRVCVec.map(isRVC => Mux(isRVC, 1.U, 2.U)) + val halfWordNumMatrix = (0 until RenameWidth).map( + i => compressMasksVec(i).asBools.map( + mask => Mux(mask, halfWordNumVec(i), 0.U) + ) + ) for (i <- 0 until RenameWidth) { // iretire uops(i).traceBlockInPipe.iretire := Mux(canRobCompressVec(i), - halfWordNumVec(i).reduce(_ +& _), - Mux(isRVCVec(i), 1.U, 2.U) + halfWordNumMatrix(i).reduce(_ +& _), + (if(i < RenameWidth -1) Mux(isFusionVec(i), halfWordNumVec(i+1), 0.U) else 0.U) +& halfWordNumVec(i) ) // ilastsize @@ -457,7 +462,7 @@ class Rename(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHe uops(i).traceBlockInPipe.ilastsize := Mux(canRobCompressVec(i), Mux(lastIsRVC, Ilastsize.HalfWord, Ilastsize.Word), - Mux(isRVCVec(i), Ilastsize.HalfWord, Ilastsize.Word) + (if(i < RenameWidth -1) Mux(isFusionVec(i), iLastSizeVec(i+1), iLastSizeVec(i)) else iLastSizeVec(i)) ) // itype From e8b1646f5f4b94a3786380727da8d010ce329eb8 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Mon, 4 Nov 2024 16:09:17 +0800 Subject: [PATCH 09/13] fix(trace): fix itype for branch after writeback * update itype to DeqGroup when branch instruction commit at next cycle after writeback. --- src/main/scala/xiangshan/backend/rob/Rob.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index 9b27b070d0..2848663238 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -1038,9 +1038,9 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP val taken = branchWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U && writeback.bits.redirect.get.bits.cfiUpdate.taken).reduce(_ || _) val xret = csrWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U && io.csr.isXRet).reduce(_ || _) - when(xret){ + when(robEntries(i).valid && xret){ robEntries(i).traceBlockInPipe.itype := Itype.ExpIntReturn - }.elsewhen(Itype.isBranchType(robEntries(i).traceBlockInPipe.itype) && taken){ + }.elsewhen(robEntries(i).valid && Itype.isBranchType(robEntries(i).traceBlockInPipe.itype) && taken){ // BranchType code(notaken itype = 4) must be correctly replaced! robEntries(i).traceBlockInPipe.itype := Itype.Taken } @@ -1101,6 +1101,16 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP val vxsatCanWbSeq = vxsat_wb.map(writeback => writeback.valid && writeback.bits.robIdx.value === needUpdateRobIdx(i)) val vxsatRes = vxsatCanWbSeq.zip(vxsat_wb).map { case (canWb, wb) => Mux(canWb, wb.bits.vxsat.get, 0.U) }.fold(false.B)(_ | _) needUpdate(i).vxsat := Mux(!robBanksRdata(i).valid && instCanEnqFlag, 0.U, robBanksRdata(i).vxsat | vxsatRes) + + // trace + val taken = branchWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === needUpdateRobIdx(i) && writeback.bits.redirect.get.bits.cfiUpdate.taken).reduce(_ || _) + val xret = csrWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === needUpdateRobIdx(i) && io.csr.isXRet).reduce(_ || _) + when(robBanksRdata(i).valid && xret){ + needUpdate(i).traceBlockInPipe.itype := Itype.ExpIntReturn + }.elsewhen(robBanksRdata(i).valid && Itype.isBranchType(robBanksRdata(i).traceBlockInPipe.itype) && taken){ + // BranchType code(notaken itype = 4) must be correctly replaced! + needUpdate(i).traceBlockInPipe.itype := Itype.Taken + } } robBanksRdataThisLineUpdate := VecInit(needUpdate.take(8)) robBanksRdataNextLineUpdate := VecInit(needUpdate.drop(8)) From ca3b3fc8d2a5f6381fc09bc8f74193166f43ed0d Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Wed, 6 Nov 2024 12:27:47 +0800 Subject: [PATCH 10/13] fix(trace): fix ftqoffset in commitInfo for fuse instruction --- src/main/scala/xiangshan/backend/rob/Rob.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index 2848663238..e500b0a77f 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -249,7 +249,7 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP // Instructions in multiple Ftq entries compressed to one RobEntry do not occur. for (i <- 0 until CommitWidth) { val lastOffset = (rawInfo(i).traceBlockInPipe.iretire - (1.U << rawInfo(i).traceBlockInPipe.ilastsize.asUInt).asUInt) + rawInfo(i).ftqOffset - commitInfo(i).ftqOffset := lastOffset + commitInfo(i).ftqOffset := Mux(CommitType.isFused(rawInfo(i).commitType), rawInfo(i).ftqOffset, lastOffset) } // data for debug From 13140f4e089f99da76117231d2cda2d4fb36ff2d Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 7 Nov 2024 14:10:42 +0800 Subject: [PATCH 11/13] fix(trace): fix `iretire` in rename --- src/main/scala/xiangshan/backend/rename/Rename.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/xiangshan/backend/rename/Rename.scala b/src/main/scala/xiangshan/backend/rename/Rename.scala index 335b5bbe15..009bf0314a 100644 --- a/src/main/scala/xiangshan/backend/rename/Rename.scala +++ b/src/main/scala/xiangshan/backend/rename/Rename.scala @@ -439,9 +439,9 @@ class Rename(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHe val iLastSizeVec = isRVCVec.map(isRVC => Mux(isRVC, Ilastsize.HalfWord, Ilastsize.Word)) val halfWordNumVec = isRVCVec.map(isRVC => Mux(isRVC, 1.U, 2.U)) val halfWordNumMatrix = (0 until RenameWidth).map( - i => compressMasksVec(i).asBools.map( - mask => Mux(mask, halfWordNumVec(i), 0.U) - ) + i => compressMasksVec(i).asBools.zipWithIndex.map{ case(mask, j) => + Mux(mask, halfWordNumVec(j), 0.U) + } ) for (i <- 0 until RenameWidth) { @@ -452,9 +452,9 @@ class Rename(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHe ) // ilastsize - val j = i + val tmp = i val lastIsRVC = WireInit(false.B) - (j until RenameWidth).map { j => + (tmp until RenameWidth).map { j => when(compressMasksVec(i)(j)) { lastIsRVC := io.in(j).bits.preDecodeInfo.isRVC } From e315a64e25c394457b8a94fbc0db40e192a52d45 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 21 Nov 2024 14:38:08 +0800 Subject: [PATCH 12/13] fix(trace): fix `priv` and `traceTrap` --- .../scala/xiangshan/backend/Backend.scala | 3 +- .../scala/xiangshan/backend/CtrlBlock.scala | 14 ++++---- src/main/scala/xiangshan/backend/fu/CSR.scala | 3 +- .../xiangshan/backend/fu/NewCSR/NewCSR.scala | 32 +++++++++++++------ .../xiangshan/backend/fu/wrapper/CSR.scala | 3 +- .../scala/xiangshan/backend/rob/Rob.scala | 16 ++++++---- .../xiangshan/backend/rob/RobBundles.scala | 1 + .../xiangshan/backend/trace/Interface.scala | 9 +++++- .../scala/xiangshan/backend/trace/Trace.scala | 31 +++++++++--------- .../xiangshan/backend/trace/TraceBuffer.scala | 3 ++ 10 files changed, 74 insertions(+), 41 deletions(-) diff --git a/src/main/scala/xiangshan/backend/Backend.scala b/src/main/scala/xiangshan/backend/Backend.scala index e2e0213cbd..7042499859 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 415c940dde..bb7d78cf7a 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 96d0cbe783..31e035e0c4 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 f73ebe1aca..50764b519b 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 6d63296f12..59cd6500c6 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 e500b0a77f..a776129d23 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 9ed5d83857..6c668826cd 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 72a6ac3b52..0d3c47e7b8 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 02f1edf388..c8c6765a18 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 21c3954c78..90bff7d788 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) { From 4b55522988173f1511d4c3d1fa3ad172d364692e Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Thu, 21 Nov 2024 18:10:15 +0800 Subject: [PATCH 13/13] fix(trace): remove traceTrap & tracePriv from trace pipeline --- src/main/scala/xiangshan/Parameters.scala | 4 -- .../scala/xiangshan/backend/Backend.scala | 3 +- .../scala/xiangshan/backend/CtrlBlock.scala | 49 ++++++++----------- src/main/scala/xiangshan/backend/fu/CSR.scala | 4 +- .../xiangshan/backend/fu/NewCSR/NewCSR.scala | 12 ++--- .../xiangshan/backend/fu/wrapper/CSR.scala | 3 +- .../xiangshan/backend/rename/Rename.scala | 1 - .../scala/xiangshan/backend/rob/Rob.scala | 46 +++++------------ .../xiangshan/backend/rob/RobBundles.scala | 2 - .../xiangshan/backend/trace/Interface.scala | 7 +-- .../scala/xiangshan/backend/trace/Trace.scala | 46 ++++++----------- .../xiangshan/backend/trace/TraceBuffer.scala | 16 ++---- 12 files changed, 63 insertions(+), 130 deletions(-) diff --git a/src/main/scala/xiangshan/Parameters.scala b/src/main/scala/xiangshan/Parameters.scala index 9635b67f82..aafeffd1e3 100644 --- a/src/main/scala/xiangshan/Parameters.scala +++ b/src/main/scala/xiangshan/Parameters.scala @@ -545,8 +545,6 @@ case class XSCoreParameters // Parameters for trace extension. // Trace parameters is useful for XSTOP. val traceParams: TraceParams = new TraceParams( - HasEncoder = true, - TraceEnable = true, TraceGroupNum = 3, IaddrWidth = GPAddrBitsSv48x4, PrivWidth = 3, @@ -895,8 +893,6 @@ trait HasXSParameter { // Parameters for Trace extension def TraceGroupNum = coreParams.traceParams.TraceGroupNum - def HasEncoder = coreParams.traceParams.HasEncoder - def TraceEnable = coreParams.traceParams.TraceEnable def CauseWidth = XLEN def TvalWidth = coreParams.traceParams.IaddrWidth def PrivWidth = coreParams.traceParams.PrivWidth diff --git a/src/main/scala/xiangshan/backend/Backend.scala b/src/main/scala/xiangshan/backend/Backend.scala index 7042499859..2d3dd044a0 100644 --- a/src/main/scala/xiangshan/backend/Backend.scala +++ b/src/main/scala/xiangshan/backend/Backend.scala @@ -247,6 +247,7 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame ctrlBlock.io.fromTop.hartId := io.fromTop.hartId ctrlBlock.io.frontend <> io.frontend ctrlBlock.io.fromCSR.toDecode := intExuBlock.io.csrToDecode.get + ctrlBlock.io.fromCSR.traceCSR := intExuBlock.io.csrio.get.traceCSR ctrlBlock.io.fromWB.wbData <> wbDataPath.io.toCtrlBlock.writeback ctrlBlock.io.fromMem.stIn <> io.mem.stIn ctrlBlock.io.fromMem.violation <> io.mem.memoryViolation @@ -256,8 +257,6 @@ 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.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 bb7d78cf7a..71ce25f59f 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -245,38 +245,30 @@ class CtrlBlockImp( * trace begin */ val trace = Module(new Trace) - if(HasEncoder){ - trace.io.fromEncoder.stall := io.traceCoreInterface.fromEncoder.stall - trace.io.fromEncoder.enable := io.traceCoreInterface.fromEncoder.enable - } else if(!HasEncoder && TraceEnable) { - trace.io.fromEncoder.enable := true.B - trace.io.fromEncoder.stall := false.B - } else if(!HasEncoder && !TraceEnable) { - trace.io.fromEncoder.enable := false.B - trace.io.fromEncoder.stall := false.B - } - - trace.io.fromRob := rob.io.trace.traceCommitInfo - rob.io.trace.blockCommit := trace.io.blockRobCommit - - if(backendParams.debugEn){ - dontTouch(trace.io.toEncoder) - } - + trace.io.in.fromEncoder.stall := io.traceCoreInterface.fromEncoder.stall + trace.io.in.fromEncoder.enable := io.traceCoreInterface.fromEncoder.enable + trace.io.in.fromRob := rob.io.trace.traceCommitInfo + rob.io.trace.blockCommit := trace.io.out.blockRobCommit + for ((pcMemIdx, i) <- pcMemRdIndexes("trace").zipWithIndex) { - val traceValid = trace.toPcMem(i).valid + val traceValid = trace.toPcMem.blocks(i).valid pcMem.io.ren.get(pcMemIdx) := traceValid - pcMem.io.raddr(pcMemIdx) := trace.toPcMem(i).bits.ftqIdx.get.value - trace.io.fromPcMem(i) := pcMem.io.rdata(pcMemIdx).getPc(RegEnable(trace.toPcMem(i).bits.ftqOffset.get, traceValid)) + pcMem.io.raddr(pcMemIdx) := trace.toPcMem.blocks(i).bits.ftqIdx.get.value + trace.io.in.fromPcMem(i) := pcMem.io.rdata(pcMemIdx).getPc(RegEnable(trace.toPcMem.blocks(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.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 + // Trap/Xret only occor in block(0). + val tracePriv = Mux(Itype.isTrapOrXret(trace.toEncoder.blocks(0).bits.tracePipe.itype), + io.fromCSR.traceCSR.lastPriv, + io.fromCSR.traceCSR.currentPriv + ) + io.traceCoreInterface.toEncoder.cause := io.fromCSR.traceCSR.cause.asUInt + io.traceCoreInterface.toEncoder.tval := io.fromCSR.traceCSR.tval.asUInt + io.traceCoreInterface.toEncoder.priv := tracePriv + io.traceCoreInterface.toEncoder.iaddr := VecInit(trace.io.out.toEncoder.blocks.map(_.bits.iaddr.get)).asUInt + io.traceCoreInterface.toEncoder.itype := VecInit(trace.io.out.toEncoder.blocks.map(_.bits.tracePipe.itype)).asUInt + io.traceCoreInterface.toEncoder.iretire := VecInit(trace.io.out.toEncoder.blocks.map(_.bits.tracePipe.iretire)).asUInt + io.traceCoreInterface.toEncoder.ilastsize := VecInit(trace.io.out.toEncoder.blocks.map(_.bits.tracePipe.ilastsize)).asUInt /** * trace end @@ -730,6 +722,7 @@ class CtrlBlockIO()(implicit p: Parameters, params: BackendParams) extends XSBun val frontend = Flipped(new FrontendToCtrlIO()) val fromCSR = new Bundle{ val toDecode = Input(new CSRToDecode) + val traceCSR = Input(new TraceCSR) } val toIssueBlock = new Bundle { val flush = ValidIO(new Redirect) diff --git a/src/main/scala/xiangshan/backend/fu/CSR.scala b/src/main/scala/xiangshan/backend/fu/CSR.scala index 31e035e0c4..ac07c2755d 100644 --- a/src/main/scala/xiangshan/backend/fu/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/CSR.scala @@ -100,8 +100,8 @@ class CSRFileIO(implicit p: Parameters) extends XSBundle { val trapTarget = Output(new TargetPCBundle) val interrupt = Output(Bool()) val wfi_event = Output(Bool()) - val traceTrapInfo = ValidIO(new TraceTrap) - val tracePriv = Output(new TracePriv) + //trace + val traceCSR = Output(new TraceCSR) // 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 50764b519b..9e28b615c2 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala @@ -190,8 +190,7 @@ class NewCSR(implicit val p: Parameters) extends Module // Instruction fetch address translation type val instrAddrTransType = new AddrTransType // trace - val traceTrapInfo = ValidIO(new TraceTrap) - val tracePriv = Output(new TracePriv) + val traceCSR = Output(new TraceCSR) // custom val custom = new CSRCustomState val criticalErrorState = Bool() @@ -1124,14 +1123,13 @@ class NewCSR(implicit val p: Parameters) extends Module 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( + io.status.traceCSR.lastPriv := lastPriv + io.status.traceCSR.currentPriv := privForTrace + io.status.traceCSR.cause := Mux1H( Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), Seq(mcause.rdata, scause.rdata, vscause.rdata) ) - io.status.traceTrapInfo.bits.tval := Mux1H( + io.status.traceCSR.tval := Mux1H( Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), Seq(mtval.rdata, stval.rdata, vstval.rdata) ) diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala index 59cd6500c6..eace095bce 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala @@ -309,8 +309,7 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) csrOut.debugMode := csrMod.io.status.debugMode - csrOut.traceTrapInfo := csrMod.io.status.traceTrapInfo - csrOut.tracePriv := csrMod.io.status.tracePriv + csrOut.traceCSR := csrMod.io.status.traceCSR csrOut.customCtrl match { case custom => diff --git a/src/main/scala/xiangshan/backend/rename/Rename.scala b/src/main/scala/xiangshan/backend/rename/Rename.scala index 009bf0314a..02dea7d3de 100644 --- a/src/main/scala/xiangshan/backend/rename/Rename.scala +++ b/src/main/scala/xiangshan/backend/rename/Rename.scala @@ -459,7 +459,6 @@ class Rename(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHe lastIsRVC := io.in(j).bits.preDecodeInfo.isRVC } } - uops(i).traceBlockInPipe.ilastsize := Mux(canRobCompressVec(i), Mux(lastIsRVC, Ilastsize.HalfWord, Ilastsize.Word), (if(i < RenameWidth -1) Mux(isFusionVec(i), iLastSizeVec(i+1), iLastSizeVec(i)) else iLastSizeVec(i)) diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index a776129d23..93d4115775 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -1231,12 +1231,8 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP /** * trace */ - 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) @@ -1245,38 +1241,22 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP 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).iretire := Mux(io.commits.isCommit && io.commits.commitValid(i), rawInfo(i).traceBlockInPipe.iretire, 0.U) + traceBlockInPipe(i).iretire := rawInfo(i).traceBlockInPipe.iretire traceBlockInPipe(i).ilastsize := rawInfo(i).traceBlockInPipe.ilastsize - } - - for (i <- 0 until CommitWidth) { - val iretire = traceBlocks(i).bits.tracePipe.iretire - val itype = traceBlocks(i).bits.tracePipe.itype - traceValids(i) := iretire =/= 0.U - } - - val t_idle :: t_waiting :: Nil = Enum(2) - val traceState = RegInit(t_idle) - when(traceState === t_idle){ - when(io.exception.valid){ - traceState := t_waiting - } - }.elsewhen(traceState === t_waiting){ - when(traceTrapInfoFromCsr.valid){ - traceState := t_idle - traceBlocks(0).bits.tracePipe.itype := Mux(io.exception.bits.isInterrupt, - Itype.Interrupt, - Itype.Exception - ) - traceValids(0) := true.B + traceValids(i) := io.commits.isCommit && io.commits.commitValid(i) + // exception only occor block(0). + if(i == 0) { + when(io.exception.valid){ + traceBlocks(i).bits.tracePipe.itype := Mux(io.exception.bits.isInterrupt, + Itype.Interrupt, + Itype.Exception + ) + traceValids(i) := true.B + traceBlockInPipe(i).iretire := 0.U + } } } - 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 6c668826cd..0ab40176f2 100644 --- a/src/main/scala/xiangshan/backend/rob/RobBundles.scala +++ b/src/main/scala/xiangshan/backend/rob/RobBundles.scala @@ -217,8 +217,6 @@ class RobCSRIO(implicit p: Parameters) extends XSBundle { val isXRet = Input(Bool()) 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 0d3c47e7b8..66336a7850 100644 --- a/src/main/scala/xiangshan/backend/trace/Interface.scala +++ b/src/main/scala/xiangshan/backend/trace/Interface.scala @@ -7,12 +7,9 @@ import utils.NamedUInt import xiangshan.HasXSParameter import xiangshan.frontend.{BrType, FtqPtr, PreDecodeInfo} -class TraceTrap(implicit val p: Parameters) extends Bundle with HasXSParameter { +class TraceCSR(implicit val p: Parameters) extends Bundle with HasXSParameter { val cause = UInt(CauseWidth.W) val tval = UInt(TvalWidth.W) -} - -class TracePriv extends Bundle { val lastPriv = Priv() val currentPriv = Priv() } @@ -31,8 +28,6 @@ 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))) } diff --git a/src/main/scala/xiangshan/backend/trace/Trace.scala b/src/main/scala/xiangshan/backend/trace/Trace.scala index c8c6765a18..6940263289 100644 --- a/src/main/scala/xiangshan/backend/trace/Trace.scala +++ b/src/main/scala/xiangshan/backend/trace/Trace.scala @@ -6,8 +6,6 @@ import org.chipsalliance.cde.config.Parameters import xiangshan.HasXSParameter class TraceParams( - val HasEncoder : Boolean, - val TraceEnable : Boolean, val TraceGroupNum : Int, val IaddrWidth : Int, val PrivWidth : Int, @@ -16,37 +14,34 @@ class TraceParams( ) class TraceIO(implicit val p: Parameters) extends Bundle with HasXSParameter { - val fromEncoder = Input(new FromEncoder) - val fromRob = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthInPipe)) - val blockRobCommit = Output(Bool()) - val toPcMem = Vec(TraceGroupNum, ValidIO(new TraceBlock(false, IretireWidthCompressed))) - val fromPcMem = Input(Vec(TraceGroupNum, UInt(IaddrWidth.W))) - val toEncoder = new TraceBundle(hasIaddr = true, TraceGroupNum, IretireWidthCompressed) + val in = new Bundle { + val fromEncoder = Input(new FromEncoder) + val fromRob = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthInPipe)) + val fromPcMem = Input(Vec(TraceGroupNum, UInt(IaddrWidth.W))) + } + val out = new Bundle { + val toPcMem = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed) + val toEncoder = new TraceBundle(hasIaddr = true, TraceGroupNum, IretireWidthCompressed) + val blockRobCommit = Output(Bool()) + } } class Trace(implicit val p: Parameters) extends Module with HasXSParameter { val io = IO(new TraceIO) - val (fromEncoder, fromRob, toPcMem, fromPcMem, toEncoder) = (io.fromEncoder, io.fromRob, io.toPcMem, io.fromPcMem, io.toEncoder) + val (fromEncoder, fromRob, fromPcMem, toPcMem, toEncoder) = (io.in.fromEncoder, io.in.fromRob, io.in.fromPcMem, io.out.toPcMem, io.out.toEncoder) /** * stage 0: CommitInfo from rob */ val blockCommit = Wire(Bool()) - io.blockRobCommit := blockCommit + io.out.blockRobCommit := blockCommit /** * stage 1: regNext(robCommitInfo) */ val s1_in = fromRob val s1_out = WireInit(0.U.asTypeOf(s1_in)) - for(i <- 0 until CommitWidth) { - // 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) } @@ -66,23 +61,14 @@ class Trace(implicit val p: Parameters) extends Module with HasXSParameter { */ val s3_in_groups = s2_out_groups val s3_out_groups = RegNext(s3_in_groups) - - toPcMem := s3_in_groups.blocks + toPcMem := s3_in_groups for(i <- 0 until TraceGroupNum) { - 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) + if(backendParams.debugEn) { + dontTouch(io.out.toEncoder) } -} - - - - - - +} \ No newline at end of file diff --git a/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala b/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala index 90bff7d788..91137129f4 100644 --- a/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala +++ b/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala @@ -15,7 +15,6 @@ class TraceBuffer(implicit val p: Parameters) extends Module val fromEncoder = Input(new FromEncoder) val fromRob = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthCompressed)) } - val out = new Bundle { // output groups to pcMem val blockCommit = Output(Bool()) val groups = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed) @@ -23,12 +22,7 @@ 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 /** @@ -71,7 +65,6 @@ class TraceBuffer(implicit val p: Parameters) extends Module deqPtrNext := Mux(deqPtr + TraceGroupNum.U > enqPtrNext, enqPtrNext, deqPtr + TraceGroupNum.U) val traceIdxVec = VecInit(countVec.map(count => (enqPtr + count - 1.U).value)) - for(i <- 0 until CommitWidth){ when(needPcVec(i)){ traceEntries(traceIdxVec(i)) := blocksUpdate(i) @@ -82,8 +75,6 @@ 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) { blockOut.blocks(i) := traceEntries((deqPtrPre + i.U).value) @@ -92,15 +83,14 @@ class TraceBuffer(implicit val p: Parameters) extends Module } } + io.out.blockCommit := blockCommit + io.out.groups := blockOut + if(backendParams.debugEn){ dontTouch(countVec) dontTouch(numNeedPc) dontTouch(traceIdxVec) } - - io.out.blockCommit := blockCommit - io.out.groups := blockOut - } class TracePtr(entries: Int) extends CircularQueuePtr[TracePtr](