From 8a5c491d5833d27eed54dae2dc521b0e1cce9361 Mon Sep 17 00:00:00 2001 From: Porterlu <1258210724@qq.com> Date: Thu, 18 May 2023 06:07:33 -0700 Subject: [PATCH] implement mtimer apply --- src/main/scala/devices/tilelink/MSWI.scala | 32 +++++-------- src/main/scala/devices/tilelink/Mtimer.scala | 47 ++++++++++++-------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/main/scala/devices/tilelink/MSWI.scala b/src/main/scala/devices/tilelink/MSWI.scala index 1179553cc24..37f2d309e01 100644 --- a/src/main/scala/devices/tilelink/MSWI.scala +++ b/src/main/scala/devices/tilelink/MSWI.scala @@ -87,25 +87,17 @@ class MSWI(mswiParams: MSWIParams, mtimerParams: MTIMERParams, isACLINT: Boolean val nTiles = intnode.out.size val ipi = Seq.fill(nTiles) { RegInit(0.U(1.W)) } - val io = IO(new Bundle { - val rtcTick = (!isACLINT).option(Input(Bool())) - }) - - val timecmp = (!isACLINT).option(Seq.fill(nTiles) { Reg(UInt(MTIMERConsts.mtimeWidth.W)) }) - val time = (!isACLINT).option(RegInit(0.U(MTIMERConsts.mtimeWidth.W))) - - io.rtcTick.map { tick => - when (tick) { time.get := time.get + 1.U } - } - val (intnode_out, _) = intnode.out.unzip intnode_out.zipWithIndex.foreach { case (int, i) => int(0) := ShiftRegister(ipi(i)(0), mswiParams.intStages) - if (!isACLINT) { - int(1) := ShiftRegister(time.get.asUInt >= (timecmp.get)(i).asUInt, mtimerParams.intStages) - } } + val io = IO(new Bundle { + val rtcTick = (!isACLINT).option(Input(Bool())) + }) + + val mtimerRegGroup: Option[(Seq[RegField], Seq[RegField])] = (!isACLINT).option(MTIMER(io.rtcTick.get, intnode, 1, mtimerParams.intStages)) + /* aclint: * 0 msip hart 0 * 4 msip hart 1 @@ -120,19 +112,17 @@ class MSWI(mswiParams: MSWIParams, mtimerParams: MTIMERParams, isACLINT: Boolean * bff8 mtime lo * bffc mtime hi */ - val mtimerRegGroup = if(!isACLINT) Seq( - 0x4000 -> timecmp.get.zipWithIndex.flatMap{ case (t, i) => RegFieldGroup(s"mtimecmp_$i", Some(s"MTIMECMP for hart $i"), - RegField.bytes(t, Some(RegFieldDesc(s"mtimecmp_$i", "", reset=None))))}, - 0xbff8 -> RegFieldGroup("mtime", Some("Timer Register"), - RegField.bytes(time.get, Some(RegFieldDesc("mtime", "", reset=Some(0), volatile=true)))) + val mtimerRegMapping = if(!isACLINT) Seq( + 0x4000 -> mtimerRegGroup.get._1, + 0xbff8 -> mtimerRegGroup.get._2 ) else Nil - val mswiRegGroup = Seq( + val mswiRegMapping = Seq( 0 -> RegFieldGroup ("msip", Some("MSIP Bits"), ipi.zipWithIndex.flatMap{ case (r, i) => RegField(1, r, RegFieldDesc(s"msip_$i", s"MSIP bit for Hart $i", reset=Some(0))) :: RegField(MSWIConsts.ipiWidth - 1) :: Nil }) ) - val mapping = mswiRegGroup ++ mtimerRegGroup + val mapping = mswiRegMapping ++ mtimerRegMapping node.regmap(mapping:_*) } } diff --git a/src/main/scala/devices/tilelink/Mtimer.scala b/src/main/scala/devices/tilelink/Mtimer.scala index 7ec31abaa00..0dbb8b80888 100644 --- a/src/main/scala/devices/tilelink/Mtimer.scala +++ b/src/main/scala/devices/tilelink/Mtimer.scala @@ -71,16 +71,7 @@ class MTIMER(params: MTIMERParams, beatBytes: Int)(implicit p: Parameters) exten val rtcTick = Input(Bool()) }) - val time = RegInit(0.U(mtimeWidth.W)) - when (io.rtcTick) { time := time + 1.U } - - val nTiles = intnode.out.size - val timecmp = Seq.fill(nTiles) { Reg(UInt(mtimeWidth.W)) } - - val (intnode_out, _) = intnode.out.unzip - intnode_out.zipWithIndex.foreach { case (int, i) => - int(0) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) - } + val (timecmpRegGroup, timeRegGroup): (Seq[RegField], Seq[RegField]) = MTIMER(io.rtcTick, intnode, 0, params.intStages) /* * Two base addresses: @@ -92,14 +83,32 @@ class MTIMER(params: MTIMERParams, beatBytes: Int)(implicit p: Parameters) exten * 0 mtime lo * 4 mtime hi */ - mtimecmpNode.regmap( - 0 -> timecmp.zipWithIndex.flatMap{ case (t, i) => RegFieldGroup(s"mtimecmp_$i", Some(s"MTIMECMP for hart $i"), - RegField.bytes(t, Some(RegFieldDesc(s"mtimecmp_$i", "", reset=None))))} - ) - - mtimeNode.regmap( - 0 -> RegFieldGroup("mtime", Some("Timer Register"), - RegField.bytes(time, Some(RegFieldDesc("mtime", "", reset=Some(0), volatile=true)))) - ) + mtimecmpNode.regmap(0 -> timecmpRegGroup) + mtimeNode.regmap(0 -> timeRegGroup) + } +} + +object MTIMER { + def apply(rtcTick: Bool, intnode: IntNexusNode, intIndex: Int, intStages: Int) = { + import MTIMERConsts._ + + val time = RegInit(0.U(mtimeWidth.W)) + when(rtcTick) { time := time + 1.U } + + val nTiles = intnode.out.size + val timecmp = Seq.fill(nTiles) { Reg(UInt(mtimeWidth.W)) } + + val (intnode_out, _) = intnode.out.unzip + intnode_out.zipWithIndex.foreach { case (int, i) => + int(intIndex) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, intStages) + } + + val timecmpRegGroup = timecmp.zipWithIndex.flatMap{ case (t, i) => RegFieldGroup(s"mtimecmp_$i", Some(s"MTIMECMP for hart $i"), + RegField.bytes(t, Some(RegFieldDesc(s"mtimecmp_$i", "", reset=None))))} + + val timeRegGroup = RegFieldGroup("mtime", Some("Timer Register"), + RegField.bytes(time, Some(RegFieldDesc("mtime", "", reset=Some(0), volatile=true)))) + + (timecmpRegGroup, timeRegGroup) } } \ No newline at end of file