Add test for external TL clients (bus mastering)
This commit is contained in:
108
groundtest/src/main/scala/BusMasterTest.scala
Normal file
108
groundtest/src/main/scala/BusMasterTest.scala
Normal file
@ -0,0 +1,108 @@
|
||||
package groundtest
|
||||
|
||||
import Chisel._
|
||||
import uncore.tilelink._
|
||||
import uncore.agents._
|
||||
import uncore.coherence.{InnerTLId, OuterTLId}
|
||||
import uncore.Util._
|
||||
import junctions.HasAddrMapParameters
|
||||
import cde.Parameters
|
||||
|
||||
class ExampleBusMaster(implicit val p: Parameters) extends Module
|
||||
with HasAddrMapParameters
|
||||
with HasTileLinkParameters {
|
||||
val mmioParams = p.alterPartial({ case TLId => p(InnerTLId) })
|
||||
val memParams = p.alterPartial({ case TLId => p(OuterTLId) })
|
||||
val memStart = addrMap("mem").start
|
||||
val memStartBlock = memStart >> p(CacheBlockOffsetBits)
|
||||
|
||||
val io = new Bundle {
|
||||
val mmio = new ClientUncachedTileLinkIO()(mmioParams).flip
|
||||
val mem = new ClientUncachedTileLinkIO()(memParams)
|
||||
}
|
||||
|
||||
val s_idle :: s_put :: s_resp :: Nil = Enum(Bits(), 3)
|
||||
val state = Reg(init = s_idle)
|
||||
val send_resp = Reg(init = Bool(false))
|
||||
val r_acq = Reg(new AcquireMetadata)
|
||||
|
||||
io.mmio.acquire.ready := !send_resp
|
||||
io.mmio.grant.valid := send_resp
|
||||
io.mmio.grant.bits := Grant(
|
||||
is_builtin_type = Bool(true),
|
||||
g_type = r_acq.getBuiltInGrantType(),
|
||||
client_xact_id = r_acq.client_xact_id,
|
||||
manager_xact_id = UInt(0),
|
||||
addr_beat = r_acq.addr_beat,
|
||||
data = Mux(state === s_idle, UInt(0), UInt(1)))
|
||||
|
||||
when (io.mmio.acquire.fire()) {
|
||||
send_resp := Bool(true)
|
||||
r_acq := io.mmio.acquire.bits
|
||||
when (state === s_idle && io.mmio.acquire.bits.hasData()) { state := s_put }
|
||||
}
|
||||
when (io.mmio.grant.fire()) { send_resp := Bool(false) }
|
||||
|
||||
val (put_beat, put_done) = Counter(io.mem.acquire.fire(), tlDataBeats)
|
||||
when (put_done) { state := s_resp }
|
||||
when (io.mem.grant.fire()) { state := s_idle }
|
||||
|
||||
io.mem.acquire.valid := state === s_put
|
||||
io.mem.acquire.bits := PutBlock(
|
||||
client_xact_id = UInt(0),
|
||||
addr_block = UInt(memStartBlock),
|
||||
addr_beat = put_beat,
|
||||
data = put_beat)
|
||||
io.mem.grant.ready := state === s_resp
|
||||
}
|
||||
|
||||
class BusMasterTest(implicit p: Parameters) extends GroundTest()(p)
|
||||
with HasTileLinkParameters {
|
||||
val (s_idle :: s_req_start :: s_resp_start :: s_req_poll :: s_resp_poll ::
|
||||
s_req_check :: s_resp_check :: s_done :: Nil) = Enum(Bits(), 8)
|
||||
val state = Reg(init = s_idle)
|
||||
|
||||
val busMasterBlock = addrMap("io:ext:busmaster").start >> p(CacheBlockOffsetBits)
|
||||
val start_acq = Put(
|
||||
client_xact_id = UInt(0),
|
||||
addr_block = UInt(busMasterBlock),
|
||||
addr_beat = UInt(0),
|
||||
data = UInt(1))
|
||||
val poll_acq = Get(
|
||||
client_xact_id = UInt(0),
|
||||
addr_block = UInt(busMasterBlock),
|
||||
addr_beat = UInt(0))
|
||||
val check_acq = GetBlock(
|
||||
client_xact_id = UInt(0),
|
||||
addr_block = UInt(memStartBlock))
|
||||
|
||||
val acq = io.mem.head.acquire
|
||||
val gnt = io.mem.head.grant
|
||||
|
||||
acq.valid := state.isOneOf(s_req_start, s_req_poll, s_req_check)
|
||||
acq.bits := MuxLookup(state, check_acq, Seq(
|
||||
s_req_start -> start_acq,
|
||||
s_req_poll -> poll_acq))
|
||||
gnt.ready := state.isOneOf(s_resp_start, s_resp_poll, s_resp_check)
|
||||
|
||||
val (get_beat, get_done) = Counter(
|
||||
state === s_resp_check && gnt.valid, tlDataBeats)
|
||||
|
||||
when (state === s_idle) { state := s_req_start }
|
||||
when (state === s_req_start && acq.ready) { state := s_resp_start }
|
||||
when (state === s_resp_start && gnt.valid) { state := s_req_poll }
|
||||
when (state === s_req_poll && acq.ready) { state := s_resp_poll }
|
||||
when (state === s_resp_poll && gnt.valid) {
|
||||
when (gnt.bits.data === UInt(0)) {
|
||||
state := s_req_check
|
||||
} .otherwise { state := s_req_poll }
|
||||
}
|
||||
when (state === s_req_check && acq.ready) { state := s_resp_check }
|
||||
when (get_done) { state := s_done }
|
||||
|
||||
io.status.finished := state === s_done
|
||||
|
||||
assert(state =/= s_resp_check || !gnt.valid ||
|
||||
gnt.bits.data === get_beat,
|
||||
"BusMasterTest: data does not match")
|
||||
}
|
Reference in New Issue
Block a user