add regression tests for catching specific memory bugs
This commit is contained in:
parent
158d1d870c
commit
484e8ce20b
115
groundtest/src/main/scala/regression.scala
Normal file
115
groundtest/src/main/scala/regression.scala
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package groundtest
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import uncore._
|
||||||
|
import junctions.{MMIOBase, ParameterizedBundle}
|
||||||
|
import cde.Parameters
|
||||||
|
|
||||||
|
class RegressionIO(implicit val p: Parameters) extends GroundTestIO()(p) {
|
||||||
|
val start = Bool(INPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Regression(implicit val p: Parameters) extends Module {
|
||||||
|
val io = new RegressionIO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This was a bug in which the TileLinkIONarrower logic screwed up
|
||||||
|
* when a PutBlock request and a narrow Get request are sent to it at the
|
||||||
|
* same time. Repeating this sequence enough times will cause a queue to
|
||||||
|
* get filled up and deadlock the system.
|
||||||
|
*/
|
||||||
|
class IOGetAfterPutBlockRegression(implicit p: Parameters)
|
||||||
|
extends Regression()(p) with HasTileLinkParameters {
|
||||||
|
|
||||||
|
val nRuns = 7
|
||||||
|
val run = Reg(init = UInt(0, log2Up(nRuns + 1)))
|
||||||
|
|
||||||
|
val (put_beat, put_done) = Counter(
|
||||||
|
io.mem.acquire.fire() && io.mem.acquire.bits.hasData(), tlDataBeats)
|
||||||
|
|
||||||
|
val started = Reg(init = Bool(false))
|
||||||
|
val put_sent = Reg(init = Bool(false))
|
||||||
|
val get_sent = Reg(init = Bool(false))
|
||||||
|
val put_acked = Reg(init = Bool(false))
|
||||||
|
val get_acked = Reg(init = Bool(false))
|
||||||
|
val both_acked = put_acked && get_acked
|
||||||
|
|
||||||
|
when (!started && io.start) { started := Bool(true) }
|
||||||
|
|
||||||
|
io.mem.acquire.valid := !put_sent && started
|
||||||
|
io.mem.acquire.bits := PutBlock(
|
||||||
|
client_xact_id = UInt(0),
|
||||||
|
addr_block = UInt(0),
|
||||||
|
addr_beat = put_beat,
|
||||||
|
data = UInt(0))
|
||||||
|
io.mem.grant.ready := Bool(true)
|
||||||
|
|
||||||
|
io.cache.req.valid := !get_sent && started
|
||||||
|
io.cache.req.bits.addr := UInt(p(MMIOBase))
|
||||||
|
io.cache.req.bits.typ := MT_W
|
||||||
|
io.cache.req.bits.cmd := M_XRD
|
||||||
|
io.cache.req.bits.tag := UInt(0)
|
||||||
|
io.cache.req.bits.kill := Bool(false)
|
||||||
|
io.cache.req.bits.phys := Bool(true)
|
||||||
|
|
||||||
|
when (put_done) { put_sent := Bool(true) }
|
||||||
|
when (io.cache.req.fire()) { get_sent := Bool(true) }
|
||||||
|
when (io.mem.grant.fire()) { put_acked := Bool(true) }
|
||||||
|
when (io.cache.resp.valid) { get_acked := Bool(true) }
|
||||||
|
|
||||||
|
when (both_acked) {
|
||||||
|
when (run < UInt(nRuns - 1)) {
|
||||||
|
put_sent := Bool(false)
|
||||||
|
get_sent := Bool(false)
|
||||||
|
}
|
||||||
|
put_acked := Bool(false)
|
||||||
|
get_acked := Bool(false)
|
||||||
|
run := run + UInt(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
io.finished := (run === UInt(nRuns))
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
|
||||||
|
|
||||||
|
val regressions = Seq(
|
||||||
|
Module(new IOGetAfterPutBlockRegression))
|
||||||
|
val regressIOs = Vec(regressions.map(_.io))
|
||||||
|
val regress_idx = Reg(init = UInt(0, log2Up(regressions.size + 1)))
|
||||||
|
val all_done = (regress_idx === UInt(regressions.size))
|
||||||
|
val start = Reg(init = Bool(true))
|
||||||
|
|
||||||
|
when (start) { start := Bool(false) }
|
||||||
|
|
||||||
|
regressIOs.zipWithIndex.foreach { case (regress, i) =>
|
||||||
|
val me = regress_idx === UInt(i)
|
||||||
|
regress.start := me && start
|
||||||
|
regress.mem.acquire.ready := io.mem.acquire.ready && me
|
||||||
|
regress.mem.grant.valid := io.mem.grant.valid && me
|
||||||
|
regress.mem.grant.bits := io.mem.grant.bits
|
||||||
|
regress.cache.req.ready := io.cache.req.ready && me
|
||||||
|
regress.cache.resp.valid := io.cache.resp.valid && me
|
||||||
|
}
|
||||||
|
|
||||||
|
val cur_regression = regressIOs(regress_idx)
|
||||||
|
val cur_acquire = cur_regression.mem.acquire
|
||||||
|
val cur_grant = cur_regression.mem.grant
|
||||||
|
val cur_cache_req = cur_regression.cache.req
|
||||||
|
|
||||||
|
io.mem.acquire.valid := cur_acquire.valid
|
||||||
|
io.mem.acquire.bits := cur_acquire.bits
|
||||||
|
io.mem.grant.ready := cur_grant.ready
|
||||||
|
io.cache.req.valid := cur_cache_req.valid
|
||||||
|
io.cache.req.bits := cur_cache_req.bits
|
||||||
|
|
||||||
|
when (cur_regression.finished && !all_done) {
|
||||||
|
start := Bool(true)
|
||||||
|
regress_idx := regress_idx + UInt(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
io.finished := all_done
|
||||||
|
|
||||||
|
val timeout = Timer(5000, start, cur_regression.finished)
|
||||||
|
assert(!timeout, "Regression timed out")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user