Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 42 additions & 45 deletions src/main/scala/rocket/Events.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand All @@ -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)
}
Expand All @@ -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)
}