From 40188a9ccc7d7b8bd93406b5ec5d8df2bcbd6b7c Mon Sep 17 00:00:00 2001 From: Matthew Weingarten Date: Sun, 24 May 2026 19:55:12 -0400 Subject: [PATCH] Change Events to accomdate events to be UInts instead of just boolean values to support super scalar events without breaking any existing code --- src/main/scala/rocket/Events.scala | 87 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/src/main/scala/rocket/Events.scala b/src/main/scala/rocket/Events.scala index a3504ff497b..920fd2e0f8d 100644 --- a/src/main/scala/rocket/Events.scala +++ b/src/main/scala/rocket/Events.scala @@ -8,20 +8,43 @@ import chisel3.util.log2Ceil import freechips.rocketchip.util._ import freechips.rocketchip.util.property -class EventSet(val gate: (UInt, UInt) => Bool, val events: Seq[(String, () => Bool)]) { - def size = events.size - val hits = WireDefault(VecInit(Seq.fill(size)(false.B))) - def check(mask: UInt) = { - hits := events.map(_._2()) - gate(mask, hits.asUInt) +class EventSet( + val gate: (UInt, UInt) => Bool, + val events: Seq[(String, () => UInt)] +) { + def size: Int = events.size + + // Raw event values. These may have different widths. + def values: Seq[UInt] = events.map { case (_, func) => func() } + + def hits: UInt = { + VecInit(values.map(_.orR)).asUInt + } + + def check(mask: UInt): Bool = { + gate(mask, hits) } + + def count(mask: UInt): UInt = { + values.zipWithIndex + .map { case (value, i) => + Mux(mask(i), value, 0.U) + } + .reduceOption(_ +& _) + .getOrElse(0.U) + } + def dump(): Unit = { - for (((name, _), i) <- events.zipWithIndex) - when (check(1.U << i)) { printf(s"Event $name\n") } + for (((name, _), i) <- events.zipWithIndex) { + when(check(1.U << i)) { + printf(s"Event $name\n") + } + } } + def withCovers: Unit = { - events.zipWithIndex.foreach { - case ((name, func), i) => property.cover(gate((1.U << i), (func() << i)), name) + events.zipWithIndex.foreach { case ((name, func), i) => + property.cover(gate(1.U << i, func().orR.asUInt << i), name) } } } @@ -30,21 +53,25 @@ class EventSets(val eventSets: Seq[EventSet]) { def maskEventSelector(eventSel: UInt): UInt = { // allow full associativity between counters and event sets (for now?) val setMask = (BigInt(1) << eventSetIdBits) - 1 - val maskMask = ((BigInt(1) << eventSets.map(_.size).max) - 1) << maxEventSetIdBits + val maskMask = + ((BigInt(1) << eventSets.map(_.size).max) - 1) << maxEventSetIdBits eventSel & (setMask | maskMask).U } private def decode(counter: UInt): (UInt, UInt) = { require(eventSets.size <= (1 << maxEventSetIdBits)) require(eventSetIdBits > 0) - (counter(eventSetIdBits-1, 0), counter >> maxEventSetIdBits) + (counter(eventSetIdBits - 1, 0), counter >> maxEventSetIdBits) } - def evaluate(eventSel: UInt): Bool = { + def evaluate(eventSel: UInt): UInt = { val (set, mask) = decode(eventSel) val sets = for (e <- eventSets) yield { - require(e.hits.getWidth <= mask.getWidth, s"too many events ${e.hits.getWidth} wider than mask ${mask.getWidth}") - e check mask + require( + e.hits.getWidth <= mask.getWidth, + s"too many events ${e.hits.getWidth} wider than mask ${mask.getWidth}" + ) + e count mask } sets(set) } @@ -56,33 +83,3 @@ class EventSets(val eventSets: Seq[EventSet]) { require(eventSetIdBits <= maxEventSetIdBits) } - -class SuperscalarEventSets(val eventSets: Seq[(Seq[EventSet], (UInt, UInt) => UInt)]) { - def evaluate(eventSel: UInt): UInt = { - val (set, mask) = decode(eventSel) - val sets = for ((sets, reducer) <- eventSets) yield { - sets.map { set => - require(set.hits.getWidth <= mask.getWidth, s"too many events ${set.hits.getWidth} wider than mask ${mask.getWidth}") - set.check(mask) - }.reduce(reducer) - } - val zeroPadded = sets.padTo(1 << eventSetIdBits, 0.U) - zeroPadded(set) - } - - def toScalarEventSets: EventSets = new EventSets(eventSets.map(_._1.head)) - - def cover(): Unit = { eventSets.foreach(_._1.foreach(_.withCovers)) } - - private def decode(counter: UInt): (UInt, UInt) = { - require(eventSets.size <= (1 << maxEventSetIdBits)) - require(eventSetIdBits > 0) - (counter(eventSetIdBits-1, 0), counter >> maxEventSetIdBits) - } - - private def eventSetIdBits = log2Ceil(eventSets.size) - private def maxEventSetIdBits = 8 - - require(eventSets.forall(s => s._1.forall(_.size == s._1.head.size))) - require(eventSetIdBits <= maxEventSetIdBits) -}