116 lines
3.9 KiB
Scala
116 lines
3.9 KiB
Scala
package groundtest
|
|
|
|
import Chisel._
|
|
import uncore.tilelink._
|
|
import uncore.agents._
|
|
import uncore.coherence.{InnerTLId, OuterTLId}
|
|
import uncore.util._
|
|
import junctions.HasAddrMapParameters
|
|
import cde.Parameters
|
|
|
|
/**
|
|
* An example bus mastering devices that writes some preset data to memory.
|
|
* When it receives an MMIO put request, it starts writing out the data.
|
|
* When it receives an MMIO get request, it responds with the progress of
|
|
* the write. A grant data of 1 means it is still writing, grant data 0
|
|
* means it has finished.
|
|
*/
|
|
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:pbus: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")
|
|
}
|