1
0

make unit tests local to the packages being tested

This commit is contained in:
Howard Mao
2016-08-01 16:05:24 -07:00
parent 98eede0505
commit b7723f1ff8
18 changed files with 136 additions and 106 deletions

View File

@ -4,7 +4,6 @@ import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.agents._
import groundtest.common._
import cde.{Parameters, Field}
class CacheFillTest(implicit p: Parameters) extends GroundTest()(p)

View File

@ -5,7 +5,6 @@ import uncore.tilelink._
import uncore.constants._
import junctions._
import rocket._
import groundtest.common._
import scala.util.Random
import cde.{Parameters, Field}

View File

@ -6,7 +6,6 @@ import uncore.devices.NTiles
import uncore.constants._
import junctions._
import rocket._
import groundtest.common._
import scala.util.Random
import cde.{Parameters, Field}

View File

@ -4,7 +4,6 @@ import Chisel._
import uncore.tilelink._
import uncore.converters._
import junctions._
import groundtest.common._
import cde.Parameters
class NastiGenerator(id: Int)(implicit val p: Parameters) extends Module

View File

@ -4,9 +4,8 @@ import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.agents._
import junctions.{ParameterizedBundle, HasAddrMapParameters}
import junctions.{ParameterizedBundle, HasAddrMapParameters, Timer}
import rocket.HellaCacheIO
import groundtest.common._
import cde.{Parameters, Field}
class RegressionIO(implicit val p: Parameters) extends ParameterizedBundle()(p) {

View File

@ -1,4 +1,4 @@
package groundtest.common
package groundtest
import Chisel._
import rocket._

View File

@ -22,7 +22,6 @@ import uncore.constants._
import uncore.devices.NTiles
import junctions._
import rocket._
import groundtest.common._
import scala.util.Random
import cde.{Parameters, Field}

View File

@ -1,56 +1,7 @@
package groundtest.common
package groundtest
import Chisel._
// ============
// Static timer
// ============
// Timer with a statically-specified period.
// Can take multiple inflight start-stop events with ID
// Will continue to count down as long as at least one event is inflight
class Timer(initCount: Int, maxInflight: Int) extends Module {
val io = new Bundle {
val start = Valid(UInt(width = log2Up(maxInflight))).flip
val stop = Valid(UInt(width = log2Up(maxInflight))).flip
val timeout = Valid(UInt(width = log2Up(maxInflight)))
}
val inflight = Reg(init = Vec.fill(maxInflight) { Bool(false) })
val countdown = Reg(UInt(width = log2Up(initCount)))
val active = inflight.reduce(_ || _)
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)
}
io.timeout.valid := countdown === UInt(0) && active
io.timeout.bits := PriorityEncoder(inflight)
assert(!io.stop.valid || inflight(io.stop.bits),
"Timer stop for transaction that's not inflight")
}
object Timer {
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
}
}
// =============
// Dynamic timer
// =============

View File

@ -1,423 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import uncore.tilelink._
import uncore.constants._
import cde.Parameters
abstract class Driver(implicit p: Parameters) extends TLModule()(p) {
val io = new Bundle {
val mem = new ClientUncachedTileLinkIO
val start = Bool(INPUT)
val finished = Bool(OUTPUT)
}
}
/**
* Tests that single-beat Gets of decreasing size return subsets of the
* data returned by larger Gets
*/
class GetMultiWidthDriver(implicit p: Parameters) extends Driver()(p) {
val s_start :: s_send :: s_recv :: s_done :: Nil = Enum(Bits(), 4)
val state = Reg(init = s_start)
val size = Reg(UInt(width = MT_SZ))
val ref = Reg(UInt(width = 64))
val bytemask = MuxLookup(size, UInt(0), Seq(
MT_D -> UInt("hff"),
MT_W -> UInt("h0f"),
MT_H -> UInt("h03"),
MT_B -> UInt("h01")))
val bitmask = FillInterleaved(8, bytemask)
io.mem.acquire.valid := (state === s_send)
io.mem.acquire.bits := Get(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0),
addr_byte = UInt(0),
operand_size = size,
alloc = Bool(false))
io.mem.grant.ready := (state === s_recv)
when (state === s_start && io.start) {
size := MT_D
state := s_send
}
when (io.mem.acquire.fire()) { state := s_recv }
when (io.mem.grant.fire()) {
when (size === MT_D) { ref := io.mem.grant.bits.data }
size := size - UInt(1)
state := Mux(size === MT_B, s_done, s_send)
}
io.finished := state === s_done
assert(!io.mem.grant.valid || size === MT_D ||
(io.mem.grant.bits.data & bitmask) === (ref & bitmask),
"GetMultiWidth: smaller get does not match larger get")
}
/**
* Tests that single-beat Gets across a range of memory return
* the expected data.
* @param expected The values of the data expected to be read.
* Each element is the data for one beat.
*/
class GetSweepDriver(expected: Seq[BigInt])
(implicit p: Parameters) extends Driver()(p) {
val s_start :: s_send :: s_recv :: s_done :: Nil = Enum(Bits(), 4)
val state = Reg(init = s_start)
val nReqs = expected.size
val (req_cnt, req_done) = Counter(io.mem.grant.fire(), nReqs)
when (state === s_start && io.start) { state := s_send }
when (io.mem.acquire.fire()) { state := s_recv }
when (io.mem.grant.fire()) { state := s_send }
when (req_done) { state := s_done }
val (addr_block, addr_beat) = if (nReqs > tlDataBeats) {
(req_cnt(log2Up(nReqs) - 1, tlBeatAddrBits),
req_cnt(tlBeatAddrBits - 1, 0))
} else {
(UInt(0), req_cnt)
}
val exp_data = Vec(expected.map(e => UInt(e, tlDataBits)))
io.mem.acquire.valid := (state === s_send)
io.mem.acquire.bits := Get(
client_xact_id = UInt(0),
addr_block = addr_block,
addr_beat = addr_beat)
io.mem.grant.ready := (state === s_recv)
io.finished := state === s_done
assert(!io.mem.grant.valid || io.mem.grant.bits.data === exp_data(req_cnt),
"GetSweep: data does not match expected")
}
/**
* Tests that multi-beat GetBlocks across a range of memory return
* the expected data.
* @param expected The values of the data expected to be read.
* Each element is the data for one beat.
*/
class GetBlockSweepDriver(expected: Seq[BigInt])
(implicit p: Parameters) extends Driver()(p) {
val s_start :: s_send :: s_recv :: s_done :: Nil = Enum(Bits(), 4)
val state = Reg(init = s_start)
val nReqs = ((expected.size - 1) / tlDataBeats + 1) * tlDataBeats
val (req_cnt, req_done) = Counter(io.mem.grant.fire(), nReqs)
val (addr_beat, beats_done) = Counter(io.mem.grant.fire(), tlDataBeats)
val tlBlockOffset = tlByteAddrBits + tlBeatAddrBits
val addr_block =
if (nReqs > tlDataBeats) req_cnt(log2Up(nReqs) - 1, tlBlockOffset)
else UInt(0)
io.mem.acquire.valid := (state === s_send)
io.mem.acquire.bits := GetBlock(
client_xact_id = UInt(0),
addr_block = addr_block)
io.mem.grant.ready := (state === s_recv)
io.finished := state === s_done
when (state === s_start && io.start) { state := s_send }
when (io.mem.acquire.fire()) { state := s_recv }
when (beats_done) { state := s_send }
when (req_done) { state := s_done }
val exp_data = Vec(expected.map(e => UInt(e, tlDataBits)))
assert(!io.mem.grant.valid || req_cnt >= UInt(expected.size) ||
io.mem.grant.bits.data === exp_data(req_cnt),
"GetBlockSweep: data does not match expected")
}
/**
* Tests that single-beat Puts across a range of memory persists correctly.
* @param n the number of beats to put
*/
class PutSweepDriver(val n: Int)(implicit p: Parameters) extends Driver()(p) {
val (s_idle :: s_put_req :: s_put_resp ::
s_get_req :: s_get_resp :: s_done :: Nil) = Enum(Bits(), 6)
val state = Reg(init = s_idle)
val (put_cnt, put_done) = Counter(state === s_put_resp && io.mem.grant.valid, n)
val (get_cnt, get_done) = Counter(state === s_get_resp && io.mem.grant.valid, n)
val (put_block, put_beat) = if (n > tlDataBeats) {
(put_cnt(log2Up(n) - 1, tlBeatAddrBits),
put_cnt(tlBeatAddrBits - 1, 0))
} else {
(UInt(0), put_cnt)
}
val (get_block, get_beat) = if (n > tlDataBeats) {
(get_cnt(log2Up(n) - 1, tlBeatAddrBits),
get_cnt(tlBeatAddrBits - 1, 0))
} else {
(UInt(0), get_cnt)
}
val dataRep = (tlDataBits - 1) / log2Up(n) + 1
val put_data = Fill(dataRep, put_cnt)(tlDataBits - 1, 0)
val get_data = Fill(dataRep, get_cnt)(tlDataBits - 1, 0)
io.mem.acquire.valid := (state === s_put_req) || (state === s_get_req)
io.mem.acquire.bits := Mux(state === s_put_req,
Put(
client_xact_id = UInt(0),
addr_block = put_block,
addr_beat = put_beat,
data = put_data),
Get(
client_xact_id = UInt(0),
addr_block = get_block,
addr_beat = get_beat))
io.mem.grant.ready := (state === s_put_resp) || (state === s_get_resp)
when (state === s_idle && io.start) { state := s_put_req }
when (state === s_put_req && io.mem.acquire.ready) { state := s_put_resp }
when (state === s_put_resp && io.mem.grant.valid) {
state := Mux(put_done, s_get_req, s_put_req)
}
when (state === s_get_req && io.mem.acquire.ready) { state := s_get_resp }
when (state === s_get_resp && io.mem.grant.valid) {
state := Mux(get_done, s_done, s_get_req)
}
io.finished := (state === s_done)
assert(!io.mem.grant.valid || !io.mem.grant.bits.hasData() ||
io.mem.grant.bits.data === get_data,
"PutSweepDriver: data does not match")
}
/**
* Tests that write-masked single-beat puts work correctly by putting
* data with steadily smaller write-masks to the same beat.
* @param minBytes the smallest number of bytes that can be in the writemask
*/
class PutMaskDriver(minBytes: Int = 1)(implicit p: Parameters) extends Driver()(p) {
val (s_idle :: s_put_req :: s_put_resp ::
s_get_req :: s_get_resp :: s_done :: Nil) = Enum(Bits(), 6)
val state = Reg(init = s_idle)
val nbytes = Reg(UInt(width = log2Up(tlWriteMaskBits) + 1))
val wmask = (UInt(1) << nbytes) - UInt(1)
val wdata = Fill(tlDataBits / 8, Wire(UInt(width = 8), init = nbytes))
// TL data bytes down to minBytes logarithmically by 2
val expected = (log2Ceil(tlDataBits / 8) to log2Ceil(minBytes) by -1)
.map(1 << _).foldLeft(UInt(0, tlDataBits)) {
// Change the lower nbytes of the value
(value, nbytes) => {
val mask = UInt((BigInt(1) << (nbytes * 8)) - BigInt(1), tlDataBits)
val wval = Fill(tlDataBits / 8, UInt(nbytes, 8))
(value & ~mask) | (wval & mask)
}
}
when (state === s_idle && io.start) {
state := s_put_req
nbytes := UInt(8)
}
when (state === s_put_req && io.mem.acquire.ready) {
state := s_put_resp
}
when (state === s_put_resp && io.mem.grant.valid) {
nbytes := nbytes >> UInt(1)
state := Mux(nbytes === UInt(minBytes), s_get_req, s_put_req)
}
when (state === s_get_req && io.mem.acquire.ready) {
state := s_get_resp
}
when (state === s_get_resp && io.mem.grant.valid) {
state := s_done
}
io.finished := (state === s_done)
io.mem.acquire.valid := (state === s_put_req) || (state === s_get_req)
io.mem.acquire.bits := Mux(state === s_put_req,
Put(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0),
data = wdata,
wmask = Some(wmask)),
Get(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0)))
io.mem.grant.ready := (state === s_put_resp) || (state === s_get_resp)
assert(!io.mem.grant.valid || state =/= s_get_resp ||
io.mem.grant.bits.data === expected,
"PutMask: data does not match expected")
}
class PutBlockSweepDriver(val n: Int)(implicit p: Parameters)
extends Driver()(p) {
val (s_idle :: s_put_req :: s_put_resp ::
s_get_req :: s_get_resp :: s_done :: Nil) = Enum(Bits(), 6)
val state = Reg(init = s_idle)
val (put_beat, put_beat_done) = Counter(
state === s_put_req && io.mem.acquire.ready, tlDataBeats)
val (put_cnt, put_done) = Counter(
state === s_put_resp && io.mem.grant.valid, n)
val (get_beat, get_beat_done) = Counter(
state === s_get_resp && io.mem.grant.valid, tlDataBeats)
val (get_cnt, get_done) = Counter(get_beat_done, n)
val dataRep = (tlDataBits - 1) / (log2Up(n) + tlBeatAddrBits) + 1
val put_data = Fill(dataRep, Cat(put_cnt, put_beat))(tlDataBits - 1, 0)
val get_data = Fill(dataRep, Cat(get_cnt, get_beat))(tlDataBits - 1, 0)
when (state === s_idle && io.start) { state := s_put_req }
when (put_beat_done) { state := s_put_resp }
when (state === s_put_resp && io.mem.grant.valid) {
state := Mux(put_done, s_get_req, s_put_req)
}
when (state === s_get_req && io.mem.acquire.ready) { state := s_get_resp }
when (get_beat_done) { state := Mux(get_done, s_done, s_get_req) }
val put_acquire = PutBlock(
client_xact_id = UInt(0),
addr_block = put_cnt,
addr_beat = put_beat,
data = put_data)
val get_acquire = GetBlock(
client_xact_id = UInt(0),
addr_block = get_cnt)
io.finished := (state === s_done)
io.mem.acquire.valid := (state === s_put_req) || (state === s_get_req)
io.mem.acquire.bits := Mux(state === s_put_req, put_acquire, get_acquire)
io.mem.grant.ready := (state === s_put_resp) || (state === s_get_resp)
assert(!io.mem.grant.valid || state =/= s_get_resp ||
io.mem.grant.bits.data === get_data,
"PutBlockSweep: data does not match expected")
}
class PutAtomicDriver(implicit p: Parameters) extends Driver()(p) {
val s_idle :: s_put :: s_atomic :: s_get :: s_done :: Nil = Enum(Bits(), 5)
val state = Reg(init = s_idle)
val sending = Reg(init = Bool(false))
val put_acquire = Put(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0),
// Put 15 in bytes 3:2
data = UInt(15 << 16),
wmask = Some(UInt(0x0c)))
val amo_acquire = PutAtomic(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0),
addr_byte = UInt(2),
atomic_opcode = M_XA_ADD,
operand_size = MT_H,
data = UInt(3 << 16))
val get_acquire = Get(
client_xact_id = UInt(0),
addr_block = UInt(0),
addr_beat = UInt(0))
io.finished := (state === s_done)
io.mem.acquire.valid := sending
io.mem.acquire.bits := MuxLookup(state, get_acquire, Seq(
s_put -> put_acquire,
s_atomic -> amo_acquire,
s_get -> get_acquire))
io.mem.grant.ready := !sending
when (io.mem.acquire.fire()) { sending := Bool(false) }
when (state === s_idle && io.start) {
state := s_put
sending := Bool(true)
}
when (io.mem.grant.fire()) {
when (state === s_put) { sending := Bool(true); state := s_atomic }
when (state === s_atomic) { sending := Bool(true); state := s_get }
when (state === s_get) { state := s_done }
}
assert(!io.mem.grant.valid || !io.mem.grant.bits.hasData() ||
io.mem.grant.bits.data(31, 16) === UInt(18))
}
class PrefetchDriver(implicit p: Parameters) extends Driver()(p) {
val s_idle :: s_put_pf :: s_get_pf :: s_done :: Nil = Enum(Bits(), 4)
val state = Reg(init = s_idle)
val sending = Reg(init = Bool(false))
when (state === s_idle) {
sending := Bool(true)
state := s_put_pf
}
when (io.mem.acquire.fire()) { sending := Bool(false) }
when (io.mem.grant.fire()) {
when (state === s_put_pf) { sending := Bool(true); state := s_get_pf }
when (state === s_get_pf) { state := s_done }
}
io.finished := (state === s_done)
io.mem.acquire.valid := sending
io.mem.acquire.bits := Mux(state === s_put_pf,
PutPrefetch(
client_xact_id = UInt(0),
addr_block = UInt(0)),
GetPrefetch(
client_xact_id = UInt(0),
addr_block = UInt(0)))
io.mem.grant.ready := !sending
}
class DriverSet(driverGen: Parameters => Seq[Driver])(implicit p: Parameters)
extends Driver()(p) {
val s_start :: s_run :: s_done :: Nil = Enum(Bits(), 3)
val state = Reg(init = s_start)
val drivers = driverGen(p)
val idx = Reg(init = UInt(0, log2Up(drivers.size)))
val finished = Wire(init = Bool(false))
when (state === s_start && io.start) { state := s_run }
when (state === s_run && finished) {
when (idx === UInt(drivers.size - 1)) { state := s_done }
idx := idx + UInt(1)
}
io.finished := state === s_done
io.mem.acquire.valid := Bool(false)
io.mem.grant.ready := Bool(false)
drivers.zipWithIndex.foreach { case (driv, i) =>
val me = idx === UInt(i)
driv.io.start := me && state === s_run
driv.io.mem.acquire.ready := io.mem.acquire.ready && me
driv.io.mem.grant.valid := io.mem.grant.valid && me
driv.io.mem.grant.bits := io.mem.grant.bits
when (me) {
io.mem.acquire.valid := driv.io.mem.acquire.valid
io.mem.acquire.bits := driv.io.mem.acquire.bits
io.mem.grant.ready := driv.io.mem.grant.ready
finished := driv.io.finished
}
}
}

View File

@ -1,55 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import junctions.NastiConstants._
import uncore.tilelink._
import uncore.converters._
import uncore.constants._
import uncore.devices._
import groundtest.common._
import cde.{Field, Parameters}
abstract class UnitTest extends Module {
val io = new Bundle {
val finished = Bool(OUTPUT)
val start = Bool(INPUT)
}
when (io.start) {
printf(s"Started UnitTest ${this.getClass.getSimpleName}\n")
}
}
case object UnitTests extends Field[Parameters => Seq[UnitTest]]
class UnitTestSuite(implicit p: Parameters) extends GroundTest()(p) {
val tests = p(UnitTests)(p)
val s_idle :: s_start :: s_wait :: 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))
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)
}
io.status.timeout.valid := Bool(false)
tests.zipWithIndex.foreach { case (mod, i) =>
mod.io.start := (state === s_start) && test_idx === UInt(i)
val timeout = Timer(1000, mod.io.start, mod.io.finished)
assert(!timeout, s"UnitTest ${mod.getClass.getSimpleName} timed out")
when (timeout) {
io.status.timeout.valid := Bool(true)
io.status.timeout.bits := UInt(i)
}
}
io.status.finished := (state === s_done)
io.status.error.valid := Bool(false)
}

View File

@ -1,85 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import junctions.NastiConstants._
class MultiWidthFifoTest extends UnitTest {
val big2little = Module(new MultiWidthFifo(16, 8, 8))
val little2big = Module(new MultiWidthFifo(8, 16, 4))
val bl_send = Reg(init = Bool(false))
val lb_send = Reg(init = Bool(false))
val bl_recv = Reg(init = Bool(false))
val lb_recv = Reg(init = Bool(false))
val bl_finished = Reg(init = Bool(false))
val lb_finished = Reg(init = Bool(false))
val bl_data = Vec.tabulate(4){i => UInt((2 * i + 1) * 256 + 2 * i, 16)}
val lb_data = Vec.tabulate(8){i => UInt(i, 8)}
val (bl_send_cnt, bl_send_done) = Counter(big2little.io.in.fire(), 4)
val (lb_send_cnt, lb_send_done) = Counter(little2big.io.in.fire(), 8)
val (bl_recv_cnt, bl_recv_done) = Counter(big2little.io.out.fire(), 8)
val (lb_recv_cnt, lb_recv_done) = Counter(little2big.io.out.fire(), 4)
big2little.io.in.valid := bl_send
big2little.io.in.bits := bl_data(bl_send_cnt)
big2little.io.out.ready := bl_recv
little2big.io.in.valid := lb_send
little2big.io.in.bits := lb_data(lb_send_cnt)
little2big.io.out.ready := lb_recv
val bl_recv_data_idx = bl_recv_cnt >> UInt(1)
val bl_recv_data = Mux(bl_recv_cnt(0),
bl_data(bl_recv_data_idx)(15, 8),
bl_data(bl_recv_data_idx)(7, 0))
val lb_recv_data = Cat(
lb_data(Cat(lb_recv_cnt, UInt(1, 1))),
lb_data(Cat(lb_recv_cnt, UInt(0, 1))))
when (io.start) {
bl_send := Bool(true)
lb_send := Bool(true)
}
when (bl_send_done) {
bl_send := Bool(false)
bl_recv := Bool(true)
}
when (lb_send_done) {
lb_send := Bool(false)
lb_recv := Bool(true)
}
when (bl_recv_done) {
bl_recv := Bool(false)
bl_finished := Bool(true)
}
when (lb_recv_done) {
lb_recv := Bool(false)
lb_finished := Bool(true)
}
io.finished := bl_finished && lb_finished
val bl_start_recv = Reg(next = bl_send_done)
val lb_start_recv = Reg(next = lb_send_done)
assert(!little2big.io.out.valid || little2big.io.out.bits === lb_recv_data,
"Little to Big data mismatch")
assert(!big2little.io.out.valid || big2little.io.out.bits === bl_recv_data,
"Bit to Little data mismatch")
assert(!lb_start_recv || little2big.io.count === UInt(4),
"Little to Big count incorrect")
assert(!bl_start_recv || big2little.io.count === UInt(8),
"Big to Little count incorrect")
}

View File

@ -1,170 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import junctions.NastiConstants._
import groundtest.common._
import cde.Parameters
class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int)
(implicit p: Parameters) extends NastiModule {
val io = new Bundle {
val nasti = new NastiIO
val finished = Bool(OUTPUT)
val start = Bool(INPUT)
}
val dataBytes = dataWidth / 8
val nastiDataBytes = nastiXDataBits / 8
val (write_cnt, write_done) = Counter(io.nasti.w.fire(), burstLen)
val (read_cnt, read_done) = Counter(io.nasti.r.fire(), burstLen)
val (req_cnt, reqs_done) = Counter(read_done, nBursts)
val req_addr = Cat(req_cnt, UInt(0, log2Up(burstLen * dataBytes)))
val write_data = UInt(0x10000000L, dataWidth) | Cat(req_cnt, write_cnt)
val expected_data = UInt(0x10000000L, dataWidth) | Cat(req_cnt, read_cnt)
val (s_idle :: s_write_addr :: s_write_data :: s_write_stall :: s_write_resp ::
s_read_addr :: s_read_data :: s_read_stall :: s_done :: Nil) = Enum(Bits(), 9)
val state = Reg(init = s_idle)
val (stall_cnt, stall_done) = Counter(state === s_read_stall, 2)
io.nasti.aw.valid := (state === s_write_addr)
io.nasti.aw.bits := NastiWriteAddressChannel(
id = UInt(0),
addr = req_addr,
size = UInt(log2Up(dataBytes)),
len = UInt(burstLen - 1))
io.nasti.w.valid := (state === s_write_data)
io.nasti.w.bits := NastiWriteDataChannel(
data = Cat(write_data, write_data),
last = (write_cnt === UInt(burstLen - 1)))
io.nasti.b.ready := (state === s_write_resp)
io.nasti.ar.valid := (state === s_read_addr)
io.nasti.ar.bits := NastiReadAddressChannel(
id = UInt(0),
addr = req_addr,
size = UInt(log2Up(dataBytes)),
len = UInt(burstLen - 1))
io.nasti.r.ready := (state === s_read_data)
io.finished := (state === s_done)
when (state === s_idle && io.start) { state := s_write_addr }
when (io.nasti.aw.fire()) { state := s_write_data }
when (io.nasti.w.fire()) { state := s_write_stall }
when (state === s_write_stall) { state := s_write_data }
when (write_done) { state := s_write_resp }
when (io.nasti.b.fire()) { state := s_read_addr }
when (io.nasti.ar.fire()) { state := s_read_data }
when (io.nasti.r.fire()) { state := s_read_stall }
when (stall_done) { state := s_read_data }
when (read_done) { state := s_write_addr }
when (reqs_done) { state := s_done }
val full_addr = req_addr + (read_cnt << UInt(log2Up(dataBytes)))
val byteshift = full_addr(log2Up(nastiDataBytes) - 1, 0)
val bitshift = Cat(byteshift, UInt(0, 3))
val read_data = (io.nasti.r.bits.data >> bitshift) & Fill(dataWidth, UInt(1, 1))
assert(!io.nasti.r.valid || read_data === expected_data,
s"NastiDriver got wrong data")
val ar_timeout = Timer(1024, io.nasti.ar.fire(), io.nasti.r.fire())
val aw_timeout = Timer(1024, io.nasti.aw.fire(), io.nasti.b.fire())
assert(!ar_timeout && !aw_timeout,
s"NastiDriver for $name timed out")
}
class AtosConverterTestBackend(implicit p: Parameters) extends NastiModule()(p) {
val io = new Bundle {
val nasti = (new NastiIO).flip
val finished = Bool(OUTPUT)
}
val (s_waddr :: s_wdata :: s_wresp ::
s_raddr :: s_rresp :: s_done :: Nil) = Enum(Bits(), 6)
val state = Reg(init = s_waddr)
val n_words = 4
val test_data = Reg(Vec(n_words, UInt(width = nastiXDataBits)))
val req_id = Reg(UInt(width = nastiXIdBits))
val (w_count, w_last) = Counter(io.nasti.w.fire(), n_words)
val (r_count, r_last) = Counter(io.nasti.r.fire(), n_words)
when (io.nasti.aw.fire()) {
req_id := io.nasti.aw.bits.id
state := s_wdata
}
when (io.nasti.w.fire()) {
test_data(w_count) := io.nasti.w.bits.data
when (io.nasti.w.bits.last) { state := s_wresp }
}
when (io.nasti.b.fire()) { state := s_raddr }
when (io.nasti.ar.fire()) {
req_id := io.nasti.ar.bits.id
state := s_rresp
}
when (io.nasti.r.fire() && io.nasti.r.bits.last) { state := s_done }
io.nasti.aw.ready := (state === s_waddr)
io.nasti.w.ready := (state === s_wdata)
io.nasti.ar.ready := (state === s_raddr)
io.nasti.b.valid := (state === s_wresp)
io.nasti.b.bits := NastiWriteResponseChannel(id = req_id)
io.nasti.r.valid := (state === s_rresp)
io.nasti.r.bits := NastiReadDataChannel(
id = req_id,
data = test_data(r_count),
last = r_last)
io.finished := (state === s_done)
}
class AtosConverterTest(implicit val p: Parameters) extends UnitTest
with HasNastiParameters {
val frontend = Module(new NastiDriver(nastiXDataBits, 4, 1))
val backend = Module(new AtosConverterTestBackend)
val serdes = Module(new AtosSerdes(8))
val desser = Module(new AtosDesser(8))
val client_conv = Module(new AtosClientConverter)
val manager_conv = Module(new AtosManagerConverter)
client_conv.io.nasti <> frontend.io.nasti
serdes.io.wide <> client_conv.io.atos
desser.io.narrow <> serdes.io.narrow
manager_conv.io.atos <> desser.io.wide
backend.io.nasti <> manager_conv.io.nasti
frontend.io.start := io.start
io.finished := frontend.io.finished && backend.io.finished
}
class HastiTest(implicit p: Parameters) extends UnitTest {
val sram = Module(new HastiTestSRAM(8))
val bus = Module(new HastiBus(Seq(a => Bool(true))))
val conv = Module(new HastiMasterIONastiIOConverter)
val driver = Module(new NastiDriver(32, 8, 2))
bus.io.slaves(0) <> sram.io
bus.io.master <> conv.io.hasti
conv.io.nasti <> driver.io.nasti
io.finished := driver.io.finished
driver.io.start := io.start
}

View File

@ -1,111 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import junctions.NastiConstants._
import cde.Parameters
class NastiDemuxDriver(n: Int)(implicit p: Parameters) extends Module {
val io = new Bundle {
val start = Bool(INPUT)
val finished = Bool(OUTPUT)
val nasti = new NastiIO
val select = UInt(OUTPUT, log2Up(n))
}
val (s_idle :: s_write_addr :: s_write_data :: s_write_resp ::
s_read_addr :: s_read_resp :: s_done :: Nil) = Enum(Bits(), 7)
val state = Reg(init = s_idle)
val select = Reg(init = UInt(0, log2Up(n)))
when (state === s_idle && io.start) { state := s_write_addr }
when (io.nasti.aw.fire()) { state := s_write_data }
when (io.nasti.w.fire()) { state := s_write_resp }
when (io.nasti.b.fire()) { state := s_read_addr }
when (io.nasti.ar.fire()) { state := s_read_resp }
when (io.nasti.r.fire()) {
when (select === UInt(n - 1)) {
state := s_done
} .otherwise {
select := select + UInt(1)
state := s_write_addr
}
}
io.nasti.aw.valid := (state === s_write_addr)
io.nasti.aw.bits := NastiWriteAddressChannel(
id = UInt(0),
addr = UInt(0),
size = UInt("b011"))
io.nasti.w.valid := (state === s_write_data)
io.nasti.w.bits := NastiWriteDataChannel(data = select)
io.nasti.b.ready := (state === s_write_resp)
io.nasti.ar.valid := (state === s_read_addr)
io.nasti.ar.bits := NastiReadAddressChannel(
id = UInt(0),
addr = UInt(0),
size = UInt("b011"))
io.nasti.r.ready := (state === s_read_resp)
io.finished := (state === s_done)
io.select := select
assert(!io.nasti.r.valid || io.nasti.r.bits.data === select,
"NASTI DeMux test: Read data did not match")
}
class NastiDemuxSlave(implicit p: Parameters) extends NastiModule()(p) {
val io = (new NastiIO).flip
val (s_write_wait :: s_write_data :: s_write_resp ::
s_read_wait :: s_read_resp :: s_done :: Nil) = Enum(Bits(), 6)
val state = Reg(init = s_write_wait)
val value = Reg(UInt(width = 64))
val id = Reg(UInt(width = nastiXIdBits))
when (io.aw.fire()) {
id := io.aw.bits.id
state := s_write_data
}
when (io.w.fire()) {
value := io.w.bits.data
state := s_write_resp
}
when (io.b.fire()) { state := s_read_wait }
when (io.ar.fire()) {
id := io.ar.bits.id
state := s_read_resp
}
when (io.r.fire()) { state := s_done }
io.aw.ready := (state === s_write_wait)
io.w.ready := (state === s_write_data)
io.b.valid := (state === s_write_resp)
io.b.bits := NastiWriteResponseChannel(id = id)
io.ar.ready := (state === s_read_wait)
io.r.valid := (state === s_read_resp)
io.r.bits := NastiReadDataChannel(id = id, data = value)
}
class NastiMemoryDemuxTest(implicit p: Parameters) extends UnitTest {
val nSlaves = 4
val driver = Module(new NastiDemuxDriver(nSlaves))
driver.io.start := io.start
io.finished := driver.io.finished
val demux = Module(new NastiMemoryDemux(nSlaves))
demux.io.master <> driver.io.nasti
demux.io.select := driver.io.select
for (i <- 0 until nSlaves) {
val slave = Module(new NastiDemuxSlave)
slave.io <> demux.io.slaves(i)
}
}

View File

@ -1,78 +0,0 @@
package groundtest.unittests
import Chisel._
import junctions._
import uncore.devices._
import uncore.tilelink._
import uncore.converters._
import groundtest.common._
import cde.Parameters
class SmiConverterTest(implicit val p: Parameters) extends UnitTest
with HasTileLinkParameters {
val outermostParams = p.alterPartial({ case TLId => "Outermost" })
val smiWidth = 32
val smiDepth = 64
val tlDepth = (smiWidth * smiDepth) / tlDataBits
val smimem = Module(new SmiMem(smiWidth, smiDepth))
val conv = Module(new SmiIOTileLinkIOConverter(
smiWidth, log2Up(smiDepth))(outermostParams))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(tlDepth)),
Module(new PutMaskDriver(smiWidth / 8)),
Module(new PutBlockSweepDriver(tlDepth / tlDataBeats)),
Module(new GetMultiWidthDriver))
})(outermostParams))
conv.io.tl <> driver.io.mem
smimem.io <> conv.io.smi
driver.io.start := io.start
io.finished := driver.io.finished
}
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
implicit val testName = "ROMSlaveTest"
val romdata = Seq(
BigInt("01234567deadbeef", 16),
BigInt("ab32fee8d00dfeed", 16))
val rombytes = romdata.map(_.toByteArray.reverse).flatten
val rom = Module(new ROMSlave(rombytes))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new GetMultiWidthDriver),
Module(new GetSweepDriver(romdata)),
Module(new GetBlockSweepDriver(romdata)))
}))
rom.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}
class TileLinkRAMTest(implicit val p: Parameters)
extends UnitTest with HasTileLinkParameters {
val depth = 2 * tlDataBeats
val ram = Module(new TileLinkTestRAM(depth))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(depth)),
Module(new PutMaskDriver),
Module(new PutAtomicDriver),
Module(new PutBlockSweepDriver(depth / tlDataBeats)),
Module(new PrefetchDriver),
Module(new GetMultiWidthDriver))
}))
ram.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}