1
0

fix groundtests to fit new way of parameterizing TileLink clients

This commit is contained in:
Howard Mao 2016-06-13 16:17:11 -07:00
parent a921458758
commit fe8d81958f
8 changed files with 132 additions and 149 deletions

View File

@ -16,15 +16,13 @@ class CacheFillTest(implicit p: Parameters) extends GroundTest()(p)
val xact_pending = Reg(init = UInt(0, tlMaxClientXacts))
val xact_id = PriorityEncoder(~xact_pending)
disablePorts(mem = false)
val (req_block, round_done) = Counter(io.mem.head.acquire.fire(), nblocks)
val (req_block, round_done) = Counter(io.mem.acquire.fire(), nblocks)
io.mem.acquire.valid := active && !xact_pending.andR
io.mem.acquire.bits := Mux(state === s_prefetch,
io.mem.head.acquire.valid := active && !xact_pending.andR
io.mem.head.acquire.bits := Mux(state === s_prefetch,
GetPrefetch(xact_id, UInt(memStartBlock) + req_block),
GetBlock(xact_id, UInt(memStartBlock) + req_block))
io.mem.grant.ready := xact_pending.orR
io.mem.head.grant.ready := xact_pending.orR
def add_pending(acq: DecoupledIO[Acquire]): UInt =
Mux(acq.fire(), UIntToOH(acq.bits.client_xact_id), UInt(0))
@ -36,8 +34,8 @@ class CacheFillTest(implicit p: Parameters) extends GroundTest()(p)
}
xact_pending := (xact_pending |
add_pending(io.mem.acquire)) &
remove_pending(io.mem.grant)
add_pending(io.mem.head.acquire)) &
remove_pending(io.mem.head.grant)
when (state === s_start) { state := s_prefetch }
when (state === s_prefetch && round_done) { state := s_retrieve }

View File

@ -51,8 +51,6 @@ class DmaStatusReg(implicit val p: Parameters) extends Module
class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p)
with HasDmaParameters with HasCoreParameters with HasAddrMapParameters {
disablePorts(cache = false, mem = false, ptw = false)
val (s_start :: s_setup_req :: s_setup_wait ::
s_stream_out :: s_stream_in :: s_stream_wait ::
s_check_req :: s_check_wait :: s_done :: Nil) = Enum(Bits(), 9)
@ -62,8 +60,8 @@ class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p)
val test_data = Vec.tabulate(conf.len) { i => UInt(i * 8, conf.size * 8) }
val (req_index, req_done) = Counter(io.cache.req.fire(), conf.len)
val (resp_index, resp_done) = Counter(io.cache.resp.fire(), conf.len)
val (req_index, req_done) = Counter(io.cache.head.req.fire(), conf.len)
val (resp_index, resp_done) = Counter(io.cache.head.resp.fire(), conf.len)
val out_req = ClientDmaRequest(
cmd = DMA_CMD_SOUT,
@ -83,20 +81,21 @@ class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p)
frontend.io.cpu.req.valid := (state === s_stream_out) || (state === s_stream_in)
frontend.io.cpu.req.bits := Mux(state === s_stream_out, out_req, in_req)
io.ptw <> frontend.io.ptw
io.mem <> frontend.io.mem
io.ptw.head <> frontend.io.ptw
io.mem.head <> frontend.io.mem
val status_reg = Module(new DmaStatusReg)
//status_reg.io.csr <> io.csr
status_reg.io.incr_outstanding := frontend.io.incr_outstanding
val cache_addr_base = Mux(state === s_setup_req, UInt(conf.source), UInt(conf.dest))
val cache_req = io.cache.head.req
io.cache.req.valid := (state === s_setup_req) || (state === s_check_req)
io.cache.req.bits.addr := cache_addr_base + Cat(req_index, UInt(0, log2Up(conf.size)))
io.cache.req.bits.data := test_data(req_index)
io.cache.req.bits.typ := UInt(log2Up(conf.size))
io.cache.req.bits.cmd := Mux(state === s_setup_req, M_XWR, M_XRD)
cache_req.valid := (state === s_setup_req) || (state === s_check_req)
cache_req.bits.addr := cache_addr_base + Cat(req_index, UInt(0, log2Up(conf.size)))
cache_req.bits.data := test_data(req_index)
cache_req.bits.typ := UInt(log2Up(conf.size))
cache_req.bits.cmd := Mux(state === s_setup_req, M_XWR, M_XRD)
when (state === s_start) { state := s_setup_req }
when (state === s_setup_req && req_done) { state := s_setup_wait }
@ -113,8 +112,8 @@ class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p)
when (dma_done) { state := s_check_req }
val resp_data = io.cache.resp.bits.data(conf.size * 8 - 1, 0)
assert(!io.cache.resp.valid || !io.cache.resp.bits.has_data ||
val resp_data = io.cache.head.resp.bits.data(conf.size * 8 - 1, 0)
assert(!io.cache.head.resp.valid || !io.cache.head.resp.bits.has_data ||
resp_data === test_data(resp_index),
"Result data streamed in does not match data streamed out")
assert(!frontend.io.cpu.resp.valid || frontend.io.cpu.resp.bits.status === UInt(0),
@ -133,8 +132,6 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
private val wordBytes = wordBits / 8
private val pAddrBits = p(PAddrBits)
disablePorts(cache = false, mem = false, ptw = false)
val sourceAddrs = Vec(testSet.map(test => UInt(test.source)))
val destAddrs = Vec(testSet.map(test => UInt(test.dest)))
val transferLengths = Vec(testSet.map(test => UInt(test.length)))
@ -157,8 +154,8 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
dst_start = destAddrs(testIdx),
segment_size = transferLengths(testIdx))
io.ptw <> frontend.io.ptw
io.mem <> frontend.io.mem
io.ptw.head <> frontend.io.ptw
io.mem.head <> frontend.io.mem
val status_reg = Module(new DmaStatusReg)
//status_reg.io.csr <> io.csr
@ -166,11 +163,13 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
val dma_done = !frontend.io.busy && !status_reg.io.xact_outstanding
io.cache.req.valid := (state === s_fill_req) || (state === s_check_req)
io.cache.req.bits.addr := req_addr
io.cache.req.bits.data := req_data
io.cache.req.bits.typ := MT_W
io.cache.req.bits.cmd := Mux(state === s_fill_req, M_XWR, M_XRD)
val cache_resp = io.cache.head.resp
val cache_req = io.cache.head.req
cache_req.valid := (state === s_fill_req) || (state === s_check_req)
cache_req.bits.addr := req_addr
cache_req.bits.data := req_data
cache_req.bits.typ := MT_W
cache_req.bits.cmd := Mux(state === s_fill_req, M_XWR, M_XRD)
when (state === s_start) {
req_addr := sourceAddrs(testIdx)
@ -179,13 +178,13 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
state := s_fill_req
}
when (io.cache.req.fire()) {
when (cache_req.fire()) {
req_addr := req_addr + UInt(wordBytes)
bytes_left := bytes_left - UInt(wordBytes)
state := Mux(state === s_fill_req, s_fill_resp, s_check_resp)
}
when (state === s_fill_resp && io.cache.resp.valid) {
when (state === s_fill_resp && cache_resp.valid) {
req_data := req_data + UInt(dataStride)
state := Mux(bytes_left === UInt(0), s_copy_req, s_fill_req)
}
@ -199,7 +198,7 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
state := s_check_req
}
when (state === s_check_resp && io.cache.resp.valid) {
when (state === s_check_resp && cache_resp.valid) {
req_data := req_data + UInt(dataStride)
when (bytes_left > UInt(0)) {
state := s_check_req
@ -219,11 +218,11 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
require(length % wordBytes == 0, "transfer length must be word-aligned")
}
assert(!io.cache.resp.valid || !io.cache.resp.bits.has_data ||
io.cache.resp.bits.data === req_data, "Received data does not match")
assert(!cache_resp.valid || !cache_resp.bits.has_data ||
cache_resp.bits.data === req_data, "Received data does not match")
assert(!frontend.io.cpu.resp.valid || frontend.io.cpu.resp.bits.status === UInt(0),
"Frontend error response")
val cache_timeout = Timer(1000, io.cache.req.fire(), io.cache.resp.valid)
val cache_timeout = Timer(1000, cache_req.fire(), cache_resp.valid)
assert(!cache_timeout, "Memory request timed out")
}

View File

@ -7,17 +7,12 @@ import rocket._
import scala.util.Random
import cde.{Parameters, Field}
case object NGenerators extends Field[Int]
case object GenerateUncached extends Field[Boolean]
case object GenerateCached extends Field[Boolean]
case object MaxGenerateRequests extends Field[Int]
case object GeneratorStartAddress extends Field[BigInt]
trait HasGeneratorParams {
trait HasGeneratorParameters extends HasGroundTestParameters {
implicit val p: Parameters
val nGens = p(NGenerators)
val genUncached = p(GenerateUncached)
val genCached = p(GenerateCached)
val nGens = p(NTiles) * (nUncached + nCached)
val genTimeout = 4096
val maxRequests = p(MaxGenerateRequests)
val startAddress = p(GeneratorStartAddress)
@ -30,7 +25,7 @@ trait HasGeneratorParams {
}
class UncachedTileLinkGenerator(id: Int)
(implicit p: Parameters) extends TLModule()(p) with HasGeneratorParams {
(implicit p: Parameters) extends TLModule()(p) with HasGeneratorParameters {
private val tlBlockOffset = tlBeatAddrBits + tlByteAddrBits
@ -61,22 +56,13 @@ class UncachedTileLinkGenerator(id: Int)
io.finished := (state === s_finished)
val part_of_full_addr =
if (genCached) {
Cat(req_cnt,
UInt(0, width = 1),
UInt(0, wordOffset))
} else {
Cat(req_cnt,
UInt(0, wordOffset))
}
val another_part_of_full_addr =
if (log2Ceil(nGens) > 0) {
Cat(UInt(id, log2Ceil(nGens)),
part_of_full_addr)
UInt(0, wordOffset))
} else {
part_of_full_addr
UInt(0, wordOffset)
}
val full_addr = UInt(startAddress) + another_part_of_full_addr
val full_addr = UInt(startAddress) + Cat(req_cnt, part_of_full_addr)
val addr_block = full_addr >> UInt(tlBlockOffset)
val addr_beat = full_addr(tlBlockOffset - 1, tlByteAddrBits)
@ -124,7 +110,7 @@ class UncachedTileLinkGenerator(id: Int)
}
class HellaCacheGenerator(id: Int)
(implicit p: Parameters) extends L1HellaCacheModule()(p) with HasGeneratorParams {
(implicit p: Parameters) extends L1HellaCacheModule()(p) with HasGeneratorParameters {
val io = new Bundle {
val finished = Bool(OUTPUT)
val mem = new HellaCacheIO
@ -140,23 +126,12 @@ class HellaCacheGenerator(id: Int)
val (req_cnt, req_wrap) = Counter(io.mem.resp.valid, maxRequests)
val part_of_req_addr =
if (log2Ceil(nGens) > 0) {
if (genUncached) {
Cat(UInt(id, log2Ceil(nGens)),
UInt(1, width = 1),
UInt(0, wordOffset))
} else {
Cat(UInt(id, log2Ceil(nGens)),
UInt(0, wordOffset))
}
} else {
if (genUncached) {
Cat(UInt(1, width = 1),
UInt(0, wordOffset))
} else {
UInt(0, wordOffset)
}
}
if (log2Ceil(nGens) > 0) {
Cat(UInt(id, log2Ceil(nGens)),
UInt(0, wordOffset))
} else {
UInt(0, wordOffset)
}
val req_addr = UInt(startAddress) + Cat(req_cnt, part_of_req_addr)
val req_data = Cat(UInt(id, log2Up(nGens)), req_addr)
@ -191,23 +166,23 @@ class HellaCacheGenerator(id: Int)
}
class GeneratorTest(id: Int)(implicit p: Parameters)
extends GroundTest()(p) with HasGeneratorParams {
extends GroundTest()(p) with HasGeneratorParameters {
disablePorts(mem = !genUncached, cache = !genCached)
val totalGens = nUncached + nCached
val gen_finished = Wire(init = Vec.fill(2){Bool(true)})
if (genUncached) {
val uncacheGen = Module(new UncachedTileLinkGenerator(id))
io.mem <> uncacheGen.io.mem
gen_finished(0) := uncacheGen.io.finished
val cached = List.tabulate(nCached) { i =>
val realId = id * totalGens + i
Module(new HellaCacheGenerator(realId))
}
if (genCached) {
val cacheGen = Module(new HellaCacheGenerator(id))
io.cache <> cacheGen.io.mem
gen_finished(1) := cacheGen.io.finished
val uncached = List.tabulate(nUncached) { i =>
val realId = id * totalGens + nCached + i
Module(new UncachedTileLinkGenerator(realId))
}
io.cache <> cached.map(_.io.mem)
io.mem <> uncached.map(_.io.mem)
val gen_finished = cached.map(_.io.finished) ++ uncached.map(_.io.finished)
io.finished := gen_finished.reduce(_ && _)
}

View File

@ -151,8 +151,6 @@ class NastiSequencer(n: Int)(implicit p: Parameters) extends Module {
class NastiConverterTest(implicit p: Parameters) extends GroundTest()(p)
with HasNastiParameters {
disablePorts(mem = false)
val tests = Seq(Module(new NastiBlockTest), Module(new NastiSmallTest))
val sequencer = Module(new NastiSequencer(tests.size))
@ -162,7 +160,7 @@ class NastiConverterTest(implicit p: Parameters) extends GroundTest()(p)
sequencer.io.in <> tests.map(_.io.mem)
sequencer.io.finished := tests.map(_.io.finished)
converter.io.nasti <> sequencer.io.out
TileLinkWidthAdapter(converter.io.tl, io.mem)
TileLinkWidthAdapter(converter.io.tl, io.mem.head)
io.finished := tests.map(_.io.finished).reduce(_ && _)
}

View File

@ -494,8 +494,6 @@ object RegressionTests {
case object GroundTestRegressions extends Field[Parameters => Seq[Regression]]
class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
disablePorts(mem = false, cache = false)
val regressions = p(GroundTestRegressions)(p)
val regressIOs = Vec(regressions.map(_.io))
val regress_idx = Reg(init = UInt(0, log2Up(regressions.size + 1)))
@ -507,12 +505,12 @@ class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
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
regress.cache.resp.bits := io.cache.resp.bits
regress.mem.acquire.ready := io.mem.head.acquire.ready && me
regress.mem.grant.valid := io.mem.head.grant.valid && me
regress.mem.grant.bits := io.mem.head.grant.bits
regress.cache.req.ready := io.cache.head.req.ready && me
regress.cache.resp.valid := io.cache.head.resp.valid && me
regress.cache.resp.bits := io.cache.head.resp.bits
}
val cur_regression = regressIOs(regress_idx)
@ -520,12 +518,12 @@ class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
val cur_grant = cur_regression.mem.grant
val cur_cache = cur_regression.cache
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
io.cache.invalidate_lr := cur_cache.invalidate_lr
io.mem.head.acquire.valid := cur_acquire.valid
io.mem.head.acquire.bits := cur_acquire.bits
io.mem.head.grant.ready := cur_grant.ready
io.cache.head.req.valid := cur_cache.req.valid
io.cache.head.req.bits := cur_cache.req.bits
io.cache.head.invalidate_lr := cur_cache.invalidate_lr
when (cur_regression.finished && !all_done) {
start := Bool(true)
@ -537,5 +535,6 @@ class RegressionTest(implicit p: Parameters) extends GroundTest()(p) {
val timeout = Timer(5000, start, cur_regression.finished)
assert(!timeout, "Regression timed out")
assert(!(all_done && io.mem.grant.valid), "Getting grant after test completion")
assert(!(all_done && io.mem.head.grant.valid),
"Getting grant after test completion")
}

View File

@ -5,6 +5,7 @@ import rocket._
import uncore._
import junctions._
import scala.util.Random
import scala.collection.mutable.ListBuffer
import cde.{Parameters, Field}
case object BuildGroundTest extends Field[(Int, Parameters) => GroundTest]
@ -12,6 +13,19 @@ case object GroundTestMaxXacts extends Field[Int]
case object GroundTestCSRs extends Field[Seq[Int]]
case object TohostAddr extends Field[BigInt]
case object GroundTestCachedClients extends Field[Int]
case object GroundTestUncachedClients extends Field[Int]
case object GroundTestNPTW extends Field[Int]
trait HasGroundTestParameters extends HasAddrMapParameters {
implicit val p: Parameters
val nUncached = p(GroundTestUncachedClients)
val nCached = p(GroundTestCachedClients)
val nPTW = p(GroundTestNPTW)
val memStart = addrMap("mem").start
val memStartBlock = memStart >> p(CacheBlockOffsetBits)
}
/** A "cache" that responds to probe requests with a release indicating
* the block is not present */
class DummyCache(implicit val p: Parameters) extends Module {
@ -27,6 +41,7 @@ class DummyCache(implicit val p: Parameters) extends Module {
io.grant.ready := Bool(true)
io.release.valid := (state === s_release)
io.release.bits := coh.makeRelease(req)
io.finish.valid := Bool(false)
when (io.probe.fire()) {
req := io.probe.bits
@ -76,34 +91,17 @@ class DummyPTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
}
}
class GroundTestIO(implicit p: Parameters) extends ParameterizedBundle()(p) {
val cache = new HellaCacheIO
val mem = new ClientUncachedTileLinkIO
val dma = new DmaIO
val ptw = new TLBPTWIO
class GroundTestIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasGroundTestParameters {
val cache = Vec(nCached, new HellaCacheIO)
val mem = Vec(nUncached, new ClientUncachedTileLinkIO)
val ptw = Vec(nPTW, new TLBPTWIO)
val finished = Bool(OUTPUT)
}
abstract class GroundTest(implicit val p: Parameters) extends Module
with HasAddrMapParameters {
with HasGroundTestParameters {
val io = new GroundTestIO
val memStart = addrMap("mem").start
val memStartBlock = memStart >> p(CacheBlockOffsetBits)
def disablePorts(mem: Boolean = true,
cache: Boolean = true,
ptw: Boolean = true) {
if (mem) {
io.mem.acquire.valid := Bool(false)
io.mem.grant.ready := Bool(false)
}
if (cache) {
io.cache.req.valid := Bool(false)
}
if (ptw) {
io.ptw.req.valid := Bool(false)
}
}
}
class GroundTestFinisher(implicit p: Parameters) extends TLModule()(p) {
@ -134,31 +132,51 @@ class GroundTestFinisher(implicit p: Parameters) extends TLModule()(p) {
}
class GroundTestTile(id: Int, resetSignal: Bool)
(implicit val p: Parameters) extends Tile(resetSignal = resetSignal)(p) {
(implicit val p: Parameters)
extends Tile(resetSignal = resetSignal)(p)
with HasGroundTestParameters {
val test = p(BuildGroundTest)(id, dcacheParams)
val dcache = Module(new HellaCache()(dcacheParams))
val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams))
dcacheIF.io.requestor <> test.io.cache
dcache.io.cpu <> dcacheIF.io.cache
io.cached.head <> dcache.io.mem
val ptwPorts = ListBuffer.empty ++= test.io.ptw
val memPorts = ListBuffer.empty ++= test.io.mem
// SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false
dcache.io.cpu.invalidate_lr := Bool(false)
if (nCached > 0) {
val dcache = Module(new HellaCache()(dcacheParams))
val dcacheArb = Module(new HellaCacheArbiter(nCached)(dcacheParams))
val ptw = Module(new DummyPTW(2))
ptw.io.requestors(0) <> test.io.ptw
ptw.io.requestors(1) <> dcache.io.ptw
dcacheArb.io.requestor.zip(test.io.cache).foreach {
case (requestor, cache) =>
val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams))
dcacheIF.io.requestor <> cache
requestor <> dcacheIF.io.cache
}
dcache.io.cpu <> dcacheArb.io.mem
io.cached.head <> dcache.io.mem
// SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false
dcache.io.cpu.invalidate_lr := Bool(false)
ptwPorts += dcache.io.ptw
} else {
val dcache = Module(new DummyCache)
io.cached.head <> dcache.io
}
// Only Tile 0 needs to write tohost
if (id == 0) {
val finisher = Module(new GroundTestFinisher)
finisher.io.finished := test.io.finished
memPorts += finisher.io.mem
}
val memArb = Module(new ClientUncachedTileLinkIOArbiter(2))
memArb.io.in(0) <> test.io.mem
memArb.io.in(1) <> finisher.io.mem
io.uncached.head <> memArb.io.out
} else { io.uncached.head <> test.io.mem }
if (ptwPorts.size > 0) {
val ptw = Module(new DummyPTW(ptwPorts.size))
ptw.io.requestors <> ptwPorts
}
require(memPorts.size == io.uncached.size)
if (memPorts.size > 0) {
io.uncached <> memPorts
}
}

View File

@ -57,7 +57,7 @@ case object AddressBag extends Field[List[Int]]
trait HasTraceGenParams {
implicit val p: Parameters
val numGens = p(NGenerators)
val numGens = p(NTiles)
val numBitsInId = log2Up(numGens)
val numReqsPerGen = p(MaxGenerateRequests)
val memRespTimeout = 1024
@ -547,10 +547,8 @@ class TraceGenerator(id: Int)
class GroundTestTraceGenerator(id: Int)(implicit p: Parameters)
extends GroundTest()(p) with HasTraceGenParams {
disablePorts(cache = false)
val traceGen = Module(new TraceGenerator(id))
io.cache <> traceGen.io.mem
io.cache.head <> traceGen.io.mem
io.finished := traceGen.io.finished
}

View File

@ -593,8 +593,6 @@ class AtosConverterTest(implicit p: Parameters) extends UnitTest {
}
class UnitTestSuite(implicit p: Parameters) extends GroundTest()(p) {
disablePorts()
val tests = Seq(
Module(new MultiWidthFifoTest),
Module(new NastiIOHostIOConverterTest),