diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 04dd994efe..0cdc31b233 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -164,7 +164,7 @@ class PTE(implicit p: Parameters) extends CoreBundle()(p) { class L2TLBEntry(nSets: Int)(implicit p: Parameters) extends CoreBundle()(p) with HasCoreParameters { val idxBits = log2Ceil(nSets) - val tagBits = maxSVAddrBits - pgIdxBits - idxBits + (if (usingHypervisor) 1 else 0) + val tagBits = maxSVAddrBits - pgIdxBits - idxBits + (if (usingHypervisor) 1 else 0) + (if (usingASID) asidLen else 0) val tag = UInt(tagBits.W) val ppn = UInt(ppnBits.W) /** dirty bit */ @@ -268,6 +268,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( /** tlb request */ val r_req = Reg(new PTWReq) + val r_req_asid = usingASID.option(Reg(UInt(asidLen.W))) /** current selected way in arbitor */ val r_req_dest = Reg(Bits()) // to respond to L1TLB : l2_hit @@ -350,7 +351,14 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( } else { val plru = new PseudoLRU(coreParams.nPTECacheEntries) val valid = RegInit(0.U(coreParams.nPTECacheEntries.W)) - val tags = Reg(Vec(coreParams.nPTECacheEntries, UInt((if (usingHypervisor) 1 + vaddrBits else paddrBits).W))) + val baseTagWidth = if (s2) { + if (usingHypervisor) 1 + vaddrBits else paddrBits + } else { + 1 + (if (usingHypervisor) vaddrBits else paddrBits) + } + val includeAsid = usingASID && !s2 + val tagWidth = baseTagWidth + (if (includeAsid) asidLen else 0) + val tags = Reg(Vec(coreParams.nPTECacheEntries, UInt(tagWidth.W))) // not include full pte, only ppn val data = Reg(Vec(coreParams.nPTECacheEntries, UInt((if (usingHypervisor && s2) vpnBits else ppnBits).W))) val can_hit = @@ -359,9 +367,12 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val can_refill = if (s2) do_both_stages && !stage2 && !stage2_final else can_hit - val tag = + val tagBase = if (s2) Cat(true.B, stage2_pte_cache_addr.padTo(vaddrBits)) else Cat(r_req.vstage1, pte_addr.padTo(if (usingHypervisor) vaddrBits else paddrBits)) + val tag = + if (includeAsid) Cat(r_req_asid.get, tagBase) + else tagBase val hits = tags.map(_ === tag).asUInt & valid val hit = hits.orR && can_hit @@ -421,7 +432,9 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val g = Reg(Vec(coreParams.nL2TLBWays, UInt(nL2TLBSets.W))) val valid = RegInit(VecInit(Seq.fill(coreParams.nL2TLBWays)(0.U(nL2TLBSets.W)))) // use r_req to construct tag - val (r_tag, r_idx) = Split(Cat(r_req.vstage1, r_req.addr(maxSVAddrBits-pgIdxBits-1, 0)), idxBits) + val l2TagBase = Cat(r_req.vstage1, r_req.addr(maxSVAddrBits-pgIdxBits-1, 0)) + val l2Tag = if (usingASID) Cat(r_req_asid.get, l2TagBase) else l2TagBase + val (r_tag, r_idx) = Split(l2Tag, idxBits) /** the valid vec for the selected set(including n ways) */ val r_valid_vec = valid.map(_(r_idx)).asUInt val r_valid_vec_q = Reg(UInt(coreParams.nL2TLBWays.W)) @@ -458,9 +471,12 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val hg = usingHypervisor.B && io.dpath.sfence.bits.hg for (way <- 0 until coreParams.nL2TLBWays) { valid(way) := - Mux(!hg && io.dpath.sfence.bits.rs1, valid(way) & ~UIntToOH(io.dpath.sfence.bits.addr(idxBits+pgIdxBits-1, pgIdxBits)), - Mux(!hg && io.dpath.sfence.bits.rs2, valid(way) & g(way), - 0.U)) + Mux(!hg && io.dpath.sfence.bits.rs1, + valid(way) & ~UIntToOH(io.dpath.sfence.bits.addr(idxBits+pgIdxBits-1, pgIdxBits)), + Mux(!hg && io.dpath.sfence.bits.rs2, + valid(way) & g(way), + 0.U) + ) } } @@ -589,6 +605,9 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val aux_ppn = Mux(arb.io.out.bits.bits.vstage1, io.dpath.vsatp.ppn, arb.io.out.bits.bits.addr) r_req := arb.io.out.bits.bits + if (usingASID) { + r_req_asid.foreach(_ := Mux(arb.io.out.bits.bits.vstage1, io.dpath.vsatp.asid(asidLen-1, 0), io.dpath.ptbr.asid(asidLen-1, 0))) + } r_req_dest := arb.io.chosen next_state := Mux(arb.io.out.bits.valid, s_req, s_ready) stage2 := arb.io.out.bits.bits.stage2 diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index ec6d82cdf2..e6c731790a 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -58,7 +58,8 @@ case class RocketCoreParams( haveCease: Boolean = true, // non-standard CEASE instruction haveSimTimeout: Boolean = true, // add plusarg for simulation timeout vector: Option[RocketCoreVectorParams] = None, - enableTraceCoreIngress: Boolean = false + enableTraceCoreIngress: Boolean = false, + override val asidLen: Int = 0 ) extends CoreParams { val lgPauseCycles = 5 val haveFSDirty = false @@ -134,7 +135,7 @@ trait HasRocketCoreIO extends HasRocketCoreParameters { implicit val p: Parameters def nTotalRoCCCSRs: Int def traceIngressParams = TraceCoreParams(nGroups = 1, iretireWidth = coreParams.retireWidth, - xlen = coreParams.xLen, iaddrWidth = coreParams.xLen) + xlen = coreParams.xLen, iaddrWidth = vaddrBitsExtended) val io = IO(new CoreBundle()(p) { val hartid = Input(UInt(hartIdLen.W)) val reset_vector = Input(UInt(resetVectorLen.W)) @@ -847,6 +848,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) io.trace_core_ingress.get.group(0) <> trace_ingress.io.out io.trace_core_ingress.get.priv := csr.io.trace(0).priv + io.trace_core_ingress.get.ctx := csr.io.ptbr.asid io.trace_core_ingress.get.tval := csr.io.tval io.trace_core_ingress.get.cause := csr.io.cause io.trace_core_ingress.get.time := csr.io.time diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index 07690edc85..bcc6159b66 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -23,7 +23,6 @@ import freechips.rocketchip.util.UIntIsOneOf import freechips.rocketchip.util.SeqToAugmentedSeq import freechips.rocketchip.util.SeqBoolBitwiseOps -case object ASIdBits extends Field[Int](0) case object VMIdBits extends Field[Int](0) /** =SFENCE= @@ -158,6 +157,8 @@ class TLBEntry(val nSectors: Int, val superpage: Boolean, val superpageOnly: Boo val tag_vpn = UInt(vpnBits.W) /** tag in vitualization mode */ val tag_v = Bool() + /** asid as additional tag */ + val tag_sectored_asid = usingASID.option(Vec(nSectors, UInt(asidLen.W))) /** entry data */ val data = Vec(nSectors, UInt(new TLBEntryData().getWidth.W)) /** valid bit */ @@ -169,11 +170,17 @@ class TLBEntry(val nSectors: Int, val superpage: Boolean, val superpageOnly: Boo /** returns the entry data matched with this vpn*/ def getData(vpn: UInt) = OptimizationBarrier(data(sectorIdx(vpn)).asTypeOf(new TLBEntryData)) /** returns whether a sector hits */ - def sectorHit(vpn: UInt, virtual: Bool) = valid.orR && sectorTagMatch(vpn, virtual) + def sectorHit(vpn: UInt, virtual: Bool, asid: UInt) = { + val idx = sectorIdx(vpn) + valid(idx) && sectorTagMatch(vpn, virtual) && asidMatch(asid, idx, false) + } /** returns whether tag matches vpn */ def sectorTagMatch(vpn: UInt, virtual: Bool) = (((tag_vpn ^ vpn) >> nSectors.log2) === 0.U) && (tag_v === virtual) + /** returns whether current asid matches entry asid */ + def asidMatch(asid: UInt, idx: UInt, ignoreAsid: Boolean) = if (usingASID && !ignoreAsid) (entry_data(idx).g === true.B || tag_sectored_asid.get(idx) === asid) else true.B /** returns hit signal */ - def hit(vpn: UInt, virtual: Bool): Bool = { + // ignoreAsid is used to ignore asid check for sfence. + def hit(vpn: UInt, virtual: Bool, asid: UInt, ignoreAsid: Boolean = false): Bool = { if (superpage && usingVM) { var tagMatch = valid.head && (tag_v === virtual) for (j <- 0 until pgLevels) { @@ -182,10 +189,10 @@ class TLBEntry(val nSectors: Int, val superpage: Boolean, val superpageOnly: Boo val ignore = level < j.U || (superpageOnly && j == pgLevels - 1).B tagMatch = tagMatch && (ignore || (tag_vpn ^ vpn)(base + n - 1, base) === 0.U) } - tagMatch + tagMatch && asidMatch(asid, 0.U, ignoreAsid) } else { val idx = sectorIdx(vpn) - valid(idx) && sectorTagMatch(vpn, virtual) + valid(idx) && sectorTagMatch(vpn, virtual) && asidMatch(asid, idx, ignoreAsid) } } /** returns the ppn of the input TLBEntryData */ @@ -207,7 +214,7 @@ class TLBEntry(val nSectors: Int, val superpage: Boolean, val superpageOnly: Boo * find the target entry with vpn tag * and replace the target entry with the input entry data */ - def insert(vpn: UInt, virtual: Bool, level: UInt, entry: TLBEntryData): Unit = { + def insert(vpn: UInt, virtual: Bool, level: UInt, entry: TLBEntryData, asid: UInt): Unit = { this.tag_vpn := vpn this.tag_v := virtual this.level := level.extract(log2Ceil(pgLevels - superpageOnly.toInt)-1, 0) @@ -215,32 +222,59 @@ class TLBEntry(val nSectors: Int, val superpage: Boolean, val superpageOnly: Boo val idx = sectorIdx(vpn) valid(idx) := true.B data(idx) := entry.asUInt + if (usingASID) { tag_sectored_asid.get(idx) := asid } } - def invalidate(): Unit = { valid.foreach(_ := false.B) } + def invalidate(): Unit = { + valid.foreach(_ := false.B) + if (usingASID) { tag_sectored_asid.get.foreach(_ := 0.U) } + } def invalidate(virtual: Bool): Unit = { - for ((v, e) <- valid zip entry_data) - when (tag_v === virtual) { v := false.B } + for (((v, e), i) <- (valid zip entry_data).zipWithIndex) { + when (tag_v === virtual) { + v := false.B + } + } } def invalidateVPN(vpn: UInt, virtual: Bool): Unit = { if (superpage) { - when (hit(vpn, virtual)) { invalidate() } + when (hit(vpn, virtual, 0.U, ignoreAsid = true)) { invalidate() } } else { when (sectorTagMatch(vpn, virtual)) { - for (((v, e), i) <- (valid zip entry_data).zipWithIndex) - when (tag_v === virtual && i.U === sectorIdx(vpn)) { v := false.B } + for (((v, e), i) <- (valid zip entry_data).zipWithIndex) { + when (tag_v === virtual && i.U === sectorIdx(vpn)) { + v := false.B + } + } } } // For fragmented superpage mappings, we assume the worst (largest) // case, and zap entries whose most-significant VPNs match when (((tag_vpn ^ vpn) >> (pgLevelBits * (pgLevels - 1))) === 0.U) { - for ((v, e) <- valid zip entry_data) - when (tag_v === virtual && e.fragmented_superpage) { v := false.B } + for (((v, e), i) <- (valid zip entry_data).zipWithIndex) { + when (tag_v === virtual && e.fragmented_superpage) { + v := false.B + } + } + } + } + def invalidateAsid(asid: UInt, virtual: Bool): Unit = { + if (usingASID) { + for (i <- 0 until nSectors) { + when (valid(i) && tag_v === virtual && !entry_data(i).g && tag_sectored_asid.get(i) === asid) { + valid(i) := false.B + tag_sectored_asid.get(i) := 0.U + } + } } } def invalidateNonGlobal(virtual: Bool): Unit = { - for ((v, e) <- valid zip entry_data) - when (tag_v === virtual && !e.g) { v := false.B } + for (((v, e), i) <- (valid zip entry_data).zipWithIndex) { + when (tag_v === virtual && !e.g) { + v := false.B + if (usingASID) { tag_sectored_asid.get(i) := 0.U } + } + } } } @@ -352,6 +386,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T val state = RegInit(s_ready) // use vpn as refill_tag val r_refill_tag = Reg(UInt(vpnBits.W)) + val r_refill_asid = usingASID.option(Reg(UInt(asidLen.W))) val r_superpage_repl_addr = Reg(UInt(log2Ceil(superpage_entries.size).W)) val r_sectored_repl_addr = Reg(UInt(log2Ceil(sectored_entries.head.size).W)) val r_sectored_hit = Reg(Valid(UInt(log2Ceil(sectored_entries.head.size).W))) @@ -367,10 +402,18 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T /** privilege mode */ val priv = io.req.bits.prv val priv_v = usingHypervisor.B && io.req.bits.v - val priv_s = priv(0) + // 1 if priv is U or H, 0 if priv is S or M + val priv_s = priv(0) // user mode and supervisor mode val priv_uses_vm = priv <= PRV.S.U val satp = Mux(priv_v, io.ptw.vsatp, io.ptw.ptbr) + val currentAsid = if (usingASID) { + val vsAsid = io.ptw.vsatp.asid(asidLen-1, 0) + val sAsid = io.ptw.ptbr.asid(asidLen-1, 0) + Mux(priv_v, vsAsid, sAsid) + } else { + 0.U + } val stage1_en = usingVM.B && satp.mode(satp.mode.getWidth-1) /** VS-stage translation enable */ val vstage1_en = usingHypervisor.B && priv_v && io.ptw.vsatp.mode(io.ptw.vsatp.mode.getWidth-1) @@ -435,15 +478,16 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T val prot_eff = pma.io.resp.eff // hit check - val sector_hits = sectored_entries(memIdx).map(_.sectorHit(vpn, priv_v)) - val superpage_hits = superpage_entries.map(_.hit(vpn, priv_v)) - val hitsVec = all_entries.map(vm_enabled && _.hit(vpn, priv_v)) + val sector_hits = sectored_entries(memIdx).map(_.sectorHit(vpn, priv_v, currentAsid)) + val superpage_hits = superpage_entries.map(_.hit(vpn, priv_v, currentAsid)) + val hitsVec = all_entries.map(vm_enabled && _.hit(vpn, priv_v, currentAsid)) val real_hits = hitsVec.asUInt val hits = Cat(!vm_enabled, real_hits) // use ptw response to refill // permission bit arrays when (do_refill) { + val refillAsid = if (usingASID) r_refill_asid.get else 0.U val pte = io.ptw.resp.bits.pte val refill_v = r_vstage1_en || r_stage2_en val newEntry = Wire(new TLBEntryData) @@ -472,11 +516,11 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T newEntry.fragmented_superpage := io.ptw.resp.bits.fragmented_superpage // refill special_entry when (special_entry.nonEmpty.B && !io.ptw.resp.bits.homogeneous) { - special_entry.foreach(_.insert(r_refill_tag, refill_v, io.ptw.resp.bits.level, newEntry)) + special_entry.foreach(_.insert(r_refill_tag, refill_v, io.ptw.resp.bits.level, newEntry, refillAsid)) }.elsewhen (io.ptw.resp.bits.level < (pgLevels-1).U) { val waddr = Mux(r_superpage_hit.valid && usingHypervisor.B, r_superpage_hit.bits, r_superpage_repl_addr) for ((e, i) <- superpage_entries.zipWithIndex) when (r_superpage_repl_addr === i.U) { - e.insert(r_refill_tag, refill_v, io.ptw.resp.bits.level, newEntry) + e.insert(r_refill_tag, refill_v, io.ptw.resp.bits.level, newEntry, refillAsid) when (invalidate_refill) { e.invalidate() } } // refill sectored_hit @@ -485,7 +529,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T val waddr = Mux(r_sectored_hit.valid, r_sectored_hit.bits, r_sectored_repl_addr) for ((e, i) <- sectored_entries(r_memIdx).zipWithIndex) when (waddr === i.U) { when (!r_sectored_hit.valid) { e.invalidate() } - e.insert(r_refill_tag, refill_v, 0.U, newEntry) + e.insert(r_refill_tag, refill_v, 0.U, newEntry, refillAsid) when (invalidate_refill) { e.invalidate() } } } @@ -679,6 +723,9 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T when (io.req.fire && tlb_miss) { state := s_request r_refill_tag := vpn + if (usingASID) { + r_refill_asid.foreach(_ := currentAsid) + } r_need_gpa := tlb_hit_if_not_gpa_miss r_vstage1_en := vstage1_en r_stage2_en := stage2_en @@ -717,12 +764,21 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T // SFENCE processing logic. when (sfence) { assert(!io.sfence.bits.rs1 || (io.sfence.bits.addr >> pgIdxBits) === vpn) + val hv = usingHypervisor.B && io.sfence.bits.hv + val hg = usingHypervisor.B && io.sfence.bits.hg + val flushAsid = if (usingASID) io.sfence.bits.asid(asidLen-1, 0) else 0.U for (e <- all_real_entries) { - val hv = usingHypervisor.B && io.sfence.bits.hv - val hg = usingHypervisor.B && io.sfence.bits.hg - when (!hg && io.sfence.bits.rs1) { e.invalidateVPN(vpn, hv) } - .elsewhen (!hg && io.sfence.bits.rs2) { e.invalidateNonGlobal(hv) } - .otherwise { e.invalidate(hv || hg) } + when (!hg && io.sfence.bits.rs1) { + e.invalidateVPN(vpn, hv) + }.elsewhen (!hg && io.sfence.bits.rs2) { + if (usingASID) { + e.invalidateAsid(flushAsid, hv) + } else { + e.invalidateNonGlobal(hv) // not using asid, flush all non-global entries + } + }.otherwise { + e.invalidate(hv || hg) + } } } when(io.req.fire && vsatp_mode_mismatch) { diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index e25ce6f323..dbb23cdc1d 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -12,7 +12,7 @@ import org.chipsalliance.diplomacy.bundlebridge._ import freechips.rocketchip.resources.{PropertyMap, PropertyOption, ResourceReference, DTSTimebase} import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode} -import freechips.rocketchip.rocket.{ICacheParams, DCacheParams, BTBParams, ASIdBits, VMIdBits, TraceAux, BPWatch} +import freechips.rocketchip.rocket.{ICacheParams, DCacheParams, BTBParams, VMIdBits, TraceAux, BPWatch} import freechips.rocketchip.subsystem.{ HierarchicalElementParams, InstantiableHierarchicalElementParams, HierarchicalElementCrossingParamsLike, CacheBlockBytes, SystemBusKey, BaseHierarchicalElement, InsertTimingClosureRegistersOnHartIds, BaseHierarchicalElementModuleImp @@ -81,7 +81,7 @@ trait HasNonDiplomaticTileParameters { require(pgLevels >= res) res } - def asIdBits: Int = p(ASIdBits) + def asIdBits: Int = tileParams.core.asidLen def vmIdBits: Int = p(VMIdBits) lazy val maxPAddrBits: Int = { require(xLen == 32 || xLen == 64, s"Only XLENs of 32 or 64 are supported, but got $xLen") diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 1160247e73..9a2aa57bbd 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -55,6 +55,8 @@ trait CoreParams { val traceHasWdata: Boolean val xLen: Int val pgLevels: Int + + val asidLen: Int = 0 def traceCustom: Option[Data] = None def customIsaExt: Option[String] = None def customCSRs(implicit p: Parameters): CustomCSRs = new CustomCSRs @@ -149,6 +151,8 @@ trait HasCoreParameters extends HasTileParameters { // Requires post-processing due to out-of-order writebacks. val enableCommitLog = false + def asidLen = coreParams.asidLen + def usingASID = asidLen > 0 } abstract class CoreModule(implicit val p: Parameters) extends Module diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index be709854f3..9a05a09fa5 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -92,7 +92,7 @@ class RocketTile private( * and selecting trace sink */ val trace_encoder_controller = rocketParams.traceParams.map { t => - val trace_encoder_controller = LazyModule(new TraceEncoderController(t.encoderBaseAddr, xBytes)) + val trace_encoder_controller = LazyModule(new TraceEncoderController(t.encoderBaseAddr, xBytes, tileId)) connectTLSlave(trace_encoder_controller.node, xBytes) trace_encoder_controller } diff --git a/src/main/scala/trace/TraceCoreIngress.scala b/src/main/scala/trace/TraceCoreIngress.scala index ce4b021fea..214d54ed07 100644 --- a/src/main/scala/trace/TraceCoreIngress.scala +++ b/src/main/scala/trace/TraceCoreIngress.scala @@ -43,7 +43,7 @@ class TraceCoreIngress(val params: TraceCoreParams) extends Module { itype := TraceItype.ITNothing } itype -} + } io.out.iretire := io.in.valid io.out.iaddr := io.in.pc diff --git a/src/main/scala/trace/TraceCoreInterface.scala b/src/main/scala/trace/TraceCoreInterface.scala index 64eb16eb70..bf63d931ef 100644 --- a/src/main/scala/trace/TraceCoreInterface.scala +++ b/src/main/scala/trace/TraceCoreInterface.scala @@ -28,8 +28,8 @@ object TraceItype extends ChiselEnum { case class TraceCoreParams ( nGroups: Int = 1, iretireWidth: Int = 1, - xlen: Int = 32, - iaddrWidth: Int = 32 + xlen: Int = 64, + iaddrWidth: Int = 64 ) @@ -43,6 +43,7 @@ class TraceCoreGroup (val params: TraceCoreParams) extends Bundle { class TraceCoreInterface (val params: TraceCoreParams) extends Bundle { val group = Vec(params.nGroups, new TraceCoreGroup(params)) val priv = UInt(4.W) + val ctx = UInt(params.xlen.W) val tval = UInt(params.xlen.W) val cause = UInt(params.xlen.W) val time = UInt(params.xlen.W) diff --git a/src/main/scala/trace/TraceEncoderController.scala b/src/main/scala/trace/TraceEncoderController.scala index 6a5c2bc7b6..f80f321791 100644 --- a/src/main/scala/trace/TraceEncoderController.scala +++ b/src/main/scala/trace/TraceEncoderController.scala @@ -21,15 +21,14 @@ class TraceEncoderControlInterface() extends Bundle { val target = UInt(TraceSinkTarget.width.W) val bp_mode = UInt(32.W) } -class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule { +class TraceEncoderController(addr: BigInt, beatBytes: Int, hartId: Int)(implicit p: Parameters) extends LazyModule { - val device = new SimpleDevice("trace-encoder-controller", Seq("ucbbar,trace0")) + val device = new SimpleDevice(s"trace-encoder-controller$hartId", Seq("ucbbar,trace")) val node = TLRegisterNode( address = Seq(AddressSet(addr, 0xFF)), device = device, beatBytes = beatBytes ) - override lazy val module = new Impl class Impl extends LazyModuleImp(this) { val io = IO(new Bundle { @@ -73,7 +72,7 @@ class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameter RegFieldDesc("impl", "Trace encoder implementation")) ), 0x20 -> Seq( - RegField(1, trace_sink_target, + RegField(8, trace_sink_target, RegFieldDesc("target", "Trace sink target")) ), 0x24 -> Seq(