[unittest] Parallelize UnitTestSuite (#319)
* [unittest] Parallelize UnitTestSuite so all tests have their own timer, runs until all finish or any timeout. Adds SimpleTimer. * [util] Timer spacing cleanup * [unittest] Remove Config reference to UnitTestTimeout
This commit is contained in:
parent
12d0c00822
commit
335e866176
@ -6,7 +6,7 @@ import uncore.devices.NTiles
|
||||
import uncore.constants._
|
||||
import junctions._
|
||||
import rocket._
|
||||
import util.Timer
|
||||
import util.SimpleTimer
|
||||
import scala.util.Random
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
@ -59,7 +59,7 @@ class UncachedTileLinkGenerator(id: Int)
|
||||
when (io.mem.grant.fire()) { sending := Bool(true) }
|
||||
when (req_wrap) { state := Mux(state === s_put, s_get, s_finished) }
|
||||
|
||||
val timeout = Timer(genTimeout, io.mem.acquire.fire(), io.mem.grant.fire())
|
||||
val timeout = SimpleTimer(genTimeout, io.mem.acquire.fire(), io.mem.grant.fire())
|
||||
assert(!timeout, s"Uncached generator ${id} timed out waiting for grant")
|
||||
|
||||
io.status.finished := (state === s_finished)
|
||||
@ -132,7 +132,7 @@ class HellaCacheGenerator(id: Int)
|
||||
val status = new GroundTestStatus
|
||||
}
|
||||
|
||||
val timeout = Timer(genTimeout, io.mem.req.fire(), io.mem.resp.valid)
|
||||
val timeout = SimpleTimer(genTimeout, io.mem.req.fire(), io.mem.resp.valid)
|
||||
assert(!timeout, s"Cached generator ${id} timed out waiting for response")
|
||||
io.status.timeout.valid := timeout
|
||||
io.status.timeout.bits := UInt(id)
|
||||
|
@ -6,7 +6,7 @@ import uncore.constants._
|
||||
import uncore.agents._
|
||||
import uncore.util._
|
||||
import junctions.HasAddrMapParameters
|
||||
import util.{ParameterizedBundle, Timer}
|
||||
import util.{ParameterizedBundle, SimpleTimer}
|
||||
import rocket.HellaCacheIO
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
@ -760,7 +760,7 @@ class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
|
||||
}
|
||||
when (start) { start := Bool(false) }
|
||||
|
||||
val timeout = Timer(5000, start, cur_finished)
|
||||
val timeout = SimpleTimer(5000, start, cur_finished)
|
||||
assert(!timeout, "Regression timed out")
|
||||
|
||||
io.status.finished := all_done
|
||||
|
@ -81,7 +81,6 @@ class ROMSlave(contents: Seq[Byte])(implicit val p: Parameters) extends Module
|
||||
}
|
||||
|
||||
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
|
||||
implicit val testName = "ROMSlaveTest"
|
||||
val romdata = Seq(
|
||||
BigInt("01234567deadbeef", 16),
|
||||
BigInt("ab32fee8d00dfeed", 16))
|
||||
|
@ -254,7 +254,7 @@ class TLFuzzRAM extends LazyModule
|
||||
}
|
||||
}
|
||||
|
||||
class TLFuzzRAMTest extends UnitTest {
|
||||
class TLFuzzRAMTest extends UnitTest(500000) {
|
||||
val dut = Module(LazyModule(new TLFuzzRAM).module)
|
||||
io.finished := dut.io.finished
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ class WithJunctionsUnitTests extends Config(
|
||||
Module(new junctions.NastiMemoryDemuxTest()(p)),
|
||||
Module(new junctions.HastiTest()(p)))
|
||||
}
|
||||
case UnitTestTimeout => 50000
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
@ -37,7 +36,6 @@ class WithUncoreUnitTests extends Config(
|
||||
Module(new uncore.devices.TileLinkRAMTest()(p)),
|
||||
Module(new uncore.tilelink2.TLFuzzRAMTest))
|
||||
}
|
||||
case UnitTestTimeout => 500000
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
|
@ -2,7 +2,7 @@ package unittest
|
||||
|
||||
import Chisel._
|
||||
import cde.{Field, Parameters}
|
||||
import util.Timer
|
||||
import util.SimpleTimer
|
||||
|
||||
trait HasUnitTestIO {
|
||||
val io = new Bundle {
|
||||
@ -11,14 +11,16 @@ trait HasUnitTestIO {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class UnitTest extends Module with HasUnitTestIO {
|
||||
when (io.start) {
|
||||
printf(s"Started UnitTest ${this.getClass.getSimpleName}\n")
|
||||
}
|
||||
abstract class UnitTest(val timeout: Int = 4096) extends Module with HasUnitTestIO {
|
||||
val testName = this.getClass.getSimpleName
|
||||
|
||||
when (io.start) { printf(s"Started UnitTest $testName\n") }
|
||||
|
||||
val timed_out = SimpleTimer(timeout, io.start, io.finished)
|
||||
assert(!timed_out, s"UnitTest $testName timed out")
|
||||
}
|
||||
|
||||
case object UnitTests extends Field[Parameters => Seq[UnitTest]]
|
||||
case object UnitTestTimeout extends Field[Int]
|
||||
|
||||
class UnitTestSuite(implicit p: Parameters) extends Module {
|
||||
val io = new Bundle {
|
||||
@ -27,33 +29,14 @@ class UnitTestSuite(implicit p: Parameters) extends Module {
|
||||
|
||||
val tests = p(UnitTests)(p)
|
||||
|
||||
val s_idle :: s_start :: s_wait :: s_done :: Nil = Enum(Bits(), 4)
|
||||
val s_idle :: s_start :: s_busy :: s_done :: Nil = Enum(Bits(), 4)
|
||||
val state = Reg(init = s_idle)
|
||||
val test_idx = Reg(init = UInt(0, log2Up(tests.size)))
|
||||
val test_finished = Vec(tests.map(_.io.finished))
|
||||
val tests_finished = Vec(tests.map(_.io.finished)).reduce(_&&_)
|
||||
|
||||
when (state === s_idle) { state := s_start }
|
||||
when (state === s_start) { state := s_wait }
|
||||
when (state === s_wait && test_finished(test_idx)) {
|
||||
state := s_start
|
||||
test_idx := test_idx + UInt(1)
|
||||
state := Mux(test_idx === UInt(tests.size - 1), s_done, s_start)
|
||||
}
|
||||
|
||||
val timer = Module(new Timer(p(UnitTestTimeout), tests.size))
|
||||
timer.io.start.valid := Bool(false)
|
||||
timer.io.stop.valid := Bool(false)
|
||||
|
||||
tests.zipWithIndex.foreach { case (mod, i) =>
|
||||
mod.io.start := (state === s_start) && test_idx === UInt(i)
|
||||
when (test_idx === UInt(i)) {
|
||||
timer.io.start.valid := mod.io.start
|
||||
timer.io.start.bits := UInt(i)
|
||||
timer.io.stop.valid := mod.io.finished
|
||||
timer.io.stop.bits := UInt(i)
|
||||
}
|
||||
}
|
||||
tests.foreach { _.io.start := (state === s_start) }
|
||||
io.finished := (state === s_done)
|
||||
|
||||
assert(!timer.io.timeout.valid, "UnitTest timed out")
|
||||
when (state === s_idle) { state := s_start }
|
||||
when (state === s_start) { state := s_busy }
|
||||
when (state === s_busy && tests_finished) { state := s_done }
|
||||
}
|
||||
|
@ -18,17 +18,14 @@ class Timer(initCount: Int, maxInflight: Int) extends Module {
|
||||
val countdown = Reg(UInt(width = log2Up(initCount)))
|
||||
val active = inflight.reduce(_ || _)
|
||||
|
||||
when (active) {
|
||||
countdown := countdown - UInt(1)
|
||||
}
|
||||
when (active) { countdown := countdown - UInt(1) }
|
||||
|
||||
when (io.start.valid) {
|
||||
inflight(io.start.bits) := Bool(true)
|
||||
countdown := UInt(initCount - 1)
|
||||
}
|
||||
when (io.stop.valid) {
|
||||
inflight(io.stop.bits) := Bool(false)
|
||||
}
|
||||
|
||||
when (io.stop.valid) { inflight(io.stop.bits) := Bool(false) }
|
||||
|
||||
io.timeout.valid := countdown === UInt(0) && active
|
||||
io.timeout.bits := PriorityEncoder(inflight)
|
||||
@ -37,18 +34,41 @@ class Timer(initCount: Int, maxInflight: Int) extends Module {
|
||||
"Timer stop for transaction that's not inflight")
|
||||
}
|
||||
|
||||
object Timer {
|
||||
/** Simplified Timer with a statically-specified period.
|
||||
* Can be stopped repeatedly, even when not active.
|
||||
*/
|
||||
class SimpleTimer(initCount: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Bool(INPUT)
|
||||
val stop = Bool(INPUT)
|
||||
val timeout = Bool(OUTPUT)
|
||||
}
|
||||
|
||||
val countdown = Reg(UInt(width = log2Up(initCount)))
|
||||
val active = Reg(Bool())
|
||||
|
||||
when (active) { countdown := countdown - UInt(1) }
|
||||
|
||||
when (io.start) {
|
||||
active := Bool(true)
|
||||
countdown := UInt(initCount - 1)
|
||||
}
|
||||
|
||||
when (io.stop) { active := Bool(false) }
|
||||
|
||||
io.timeout := countdown === UInt(0) && active
|
||||
}
|
||||
|
||||
object SimpleTimer {
|
||||
def apply(initCount: Int, start: Bool, stop: Bool): Bool = {
|
||||
val timer = Module(new Timer(initCount, 1))
|
||||
timer.io.start.valid := start
|
||||
timer.io.start.bits := UInt(0)
|
||||
timer.io.stop.valid := stop
|
||||
timer.io.stop.bits := UInt(0)
|
||||
timer.io.timeout.valid
|
||||
val timer = Module(new SimpleTimer(initCount))
|
||||
timer.io.start := start
|
||||
timer.io.stop := stop
|
||||
timer.io.timeout
|
||||
}
|
||||
}
|
||||
|
||||
/** Timer with a statically-specified period. */
|
||||
/** Timer with a dynamically-specified period. */
|
||||
class DynamicTimer(w: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Bool(INPUT)
|
||||
@ -71,4 +91,3 @@ class DynamicTimer(w: Int) extends Module {
|
||||
|
||||
io.timeout := countdown === UInt(0) && active
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user