From 41d1a627133a43051f82a0218edb3bd5c8b6fb85 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 5 Mar 2018 15:29:14 -0800 Subject: [PATCH 1/2] PLIC: Update RegFieldDesc to reflect the fact that source 0 isn't like all the others --- src/main/scala/devices/tilelink/Plic.scala | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 1a2b2b15..72e72eb3 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -168,8 +168,17 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends harts(hart) := ShiftRegister(Reg(next = maxPri) > Cat(UInt(1), threshold(hart)), params.intStages) } - def priorityRegDesc(i: Int) = RegFieldDesc(s"priority_$i", s"Acting priority of interrupt source $i", reset=if (nPriorities > 0) None else Some(1)) - def pendingRegDesc(i: Int) = RegFieldDesc(s"pending_$i", s"Set to 1 if interrupt source $i is pending, regardless of its enable or priority setting.") + def priorityRegDesc(i: Int) = if (i > 0) { + RegFieldDesc(s"priority_$i", s"Acting priority of interrupt source $i", reset=if (nPriorities > 0) None else Some(1)) + } else { + RegFieldDesc("reserved", "", reset=Some(0), access=RegFieldAccessType.R) + } + def pendingRegDesc(i: Int) = if (i > 0) { + RegFieldDesc(s"pending_$i", s"Set to 1 if interrupt source $i is pending, regardless of its enable or priority setting.") + } else { + RegFieldDesc("reserved", "", reset=Some(0), access=RegFieldAccessType.R) + } + def priorityRegField(x: UInt, i: Int) = if (nPriorities > 0) RegField(32, x, priorityRegDesc(i)) else RegField.r(32, x, priorityRegDesc(i)) val priorityRegFields = Seq(PLICConsts.priorityBase -> RegFieldGroup("priority", Some("Acting priorities of each interrupt source. 32 bits for each interrupt source."), priority.zipWithIndex.map{case (p, i) => priorityRegField(p, i)})) @@ -179,7 +188,11 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends val enableRegFields = enables.zipWithIndex.map { case (e, i) => PLICConsts.enableBase(i) -> RegFieldGroup(s"enables_${i}", Some(s"Enable bits for each interrupt source for target $i. 1 bit for each interrupt source."), - e.zipWithIndex.map{case (b, j) => RegField(1, b, RegFieldDesc(s"enable_${i}_${j}", s"Enable interrupt for source $j for target $i.", reset=None))}) + e.zipWithIndex.map{case (b, j) => if (j > 0) { + RegField(1, b, RegFieldDesc(s"enable_${i}_${j}", s"Enable interrupt for source $j for target $i.", reset=None)) + } else { + RegField(1, b, RegFieldDesc("reserved", "", reset=Some(0), access=RegFieldAccessType.R)) + }}) } // When a hart reads a claim/complete register, then the From 4256d99a9b19e61c066097cccbfecf9aadee7d50 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 5 Mar 2018 16:10:05 -0800 Subject: [PATCH 2/2] PLIC: priority/threshold are really WARL (RWSPECIAL). Explain why. --- src/main/scala/devices/tilelink/Plic.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 72e72eb3..eca0bc1d 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -169,7 +169,8 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends } def priorityRegDesc(i: Int) = if (i > 0) { - RegFieldDesc(s"priority_$i", s"Acting priority of interrupt source $i", reset=if (nPriorities > 0) None else Some(1)) + RegFieldDesc(s"priority_$i", s"Acting priority of interrupt source $i", + reset=if (nPriorities > 0) None else Some(1), access=RegFieldAccessType.RWSPECIAL) } else { RegFieldDesc("reserved", "", reset=Some(0), access=RegFieldAccessType.R) } @@ -180,7 +181,8 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends } def priorityRegField(x: UInt, i: Int) = if (nPriorities > 0) RegField(32, x, priorityRegDesc(i)) else RegField.r(32, x, priorityRegDesc(i)) - val priorityRegFields = Seq(PLICConsts.priorityBase -> RegFieldGroup("priority", Some("Acting priorities of each interrupt source. 32 bits for each interrupt source."), + val priorityRegFields = Seq(PLICConsts.priorityBase -> RegFieldGroup("priority", + Some(s"Acting priorities of each interrupt source. Maximum legal value is ${nPriorities}. 32 bits for each interrupt source."), priority.zipWithIndex.map{case (p, i) => priorityRegField(p, i)})) val pendingRegFields = Seq(PLICConsts.pendingBase -> RegFieldGroup("pending", Some("Pending Bit Array. 1 Bit for each interrupt source."), pending.zipWithIndex.map{case (b, i) => RegField.r(1, b, pendingRegDesc(i))})) @@ -226,7 +228,8 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends g.complete := c } - def thresholdRegDesc(i: Int) = RegFieldDesc(s"threshold_$i", s"Interrupt & claim threshold for target $i", reset=if (nPriorities > 0) None else Some(1)) + def thresholdRegDesc(i: Int) = RegFieldDesc(s"threshold_$i", s"Interrupt & claim threshold for target $i. Maximum value is ${nPriorities}.", + reset=if (nPriorities > 0) None else Some(1), access=RegFieldAccessType.RWSPECIAL) def thresholdRegField(x: UInt, i: Int) = if (nPriorities > 0) RegField(32, x, thresholdRegDesc(i)) else RegField.r(32, x, thresholdRegDesc(i)) val hartRegFields = Seq.tabulate(nHarts) { i =>