test DMA streaming
This commit is contained in:
parent
b8d0376d3f
commit
80d97d5f9e
@ -2,9 +2,11 @@ package groundtest
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import uncore._
|
import uncore._
|
||||||
|
import uncore.DmaRequest._
|
||||||
import rocket._
|
import rocket._
|
||||||
import junctions.PAddrBits
|
import junctions.PAddrBits
|
||||||
import cde.{Parameters, Field}
|
import cde.{Parameters, Field}
|
||||||
|
import scala.math.max
|
||||||
|
|
||||||
case class DmaTestCase(source: Int, dest: Int, length: Int)
|
case class DmaTestCase(source: Int, dest: Int, length: Int)
|
||||||
|
|
||||||
@ -16,10 +18,84 @@ object DmaTestCases {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class DmaStreamTestConfig(
|
||||||
|
source: Int, dest: Int, len: Int, size: Int)
|
||||||
|
|
||||||
case object DmaTestSet extends Field[Seq[DmaTestCase]]
|
case object DmaTestSet extends Field[Seq[DmaTestCase]]
|
||||||
case object DmaTestDataStart extends Field[Int]
|
case object DmaTestDataStart extends Field[Int]
|
||||||
case object DmaTestDataStride extends Field[Int]
|
case object DmaTestDataStride extends Field[Int]
|
||||||
|
|
||||||
|
case object DmaStreamLoopbackAddr extends Field[BigInt]
|
||||||
|
case object DmaStreamTestSettings extends Field[DmaStreamTestConfig]
|
||||||
|
|
||||||
|
class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p)
|
||||||
|
with HasDmaParameters with HasCoreParameters {
|
||||||
|
disablePorts(cache = false, dma = 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)
|
||||||
|
val state = Reg(init = s_start)
|
||||||
|
val lo_base = p(DmaStreamLoopbackAddr)
|
||||||
|
val conf = p(DmaStreamTestSettings)
|
||||||
|
|
||||||
|
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 out_req = ClientDmaRequest(
|
||||||
|
cmd = DMA_CMD_SOUT,
|
||||||
|
src_start = UInt(conf.source),
|
||||||
|
dst_start = UInt(lo_base),
|
||||||
|
segment_size = UInt(conf.len * conf.size),
|
||||||
|
word_size = UInt(log2Up(conf.size)))
|
||||||
|
|
||||||
|
val in_req = ClientDmaRequest(
|
||||||
|
cmd = DMA_CMD_SIN,
|
||||||
|
src_start = UInt(lo_base),
|
||||||
|
dst_start = UInt(conf.dest),
|
||||||
|
segment_size = UInt(conf.len * conf.size),
|
||||||
|
word_size = UInt(log2Up(conf.size)))
|
||||||
|
|
||||||
|
val frontend = Module(new DmaFrontend)
|
||||||
|
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.dma <> frontend.io.dma
|
||||||
|
io.ptw <> frontend.io.ptw
|
||||||
|
|
||||||
|
val cache_addr_base = Mux(state === s_setup_req, UInt(conf.source), UInt(conf.dest))
|
||||||
|
|
||||||
|
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)
|
||||||
|
io.cache.req.bits.kill := Bool(false)
|
||||||
|
io.cache.req.bits.phys := Bool(false)
|
||||||
|
|
||||||
|
when (state === s_start) { state := s_setup_req }
|
||||||
|
when (state === s_setup_req && req_done) { state := s_setup_wait }
|
||||||
|
when (state === s_check_req && req_done) { state := s_check_wait }
|
||||||
|
when (state === s_setup_wait && resp_done) { state := s_stream_out }
|
||||||
|
when (state === s_check_wait && resp_done) { state := s_done }
|
||||||
|
|
||||||
|
when (frontend.io.cpu.req.fire()) {
|
||||||
|
state := Mux(state === s_stream_out, s_stream_in, s_stream_wait)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dma_done = (state === s_stream_wait) && !frontend.io.busy
|
||||||
|
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 ||
|
||||||
|
resp_data === test_data(resp_index),
|
||||||
|
"Result data streamed in does not match data streamed out")
|
||||||
|
|
||||||
|
io.finished := (state === s_done)
|
||||||
|
}
|
||||||
|
|
||||||
class DmaTest(implicit p: Parameters) extends GroundTest()(p)
|
class DmaTest(implicit p: Parameters) extends GroundTest()(p)
|
||||||
with HasDmaParameters with HasCoreParameters {
|
with HasDmaParameters with HasCoreParameters {
|
||||||
|
|
||||||
@ -49,7 +125,7 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p)
|
|||||||
val frontend = Module(new DmaFrontend)
|
val frontend = Module(new DmaFrontend)
|
||||||
frontend.io.cpu.req.valid := (state === s_copy_req)
|
frontend.io.cpu.req.valid := (state === s_copy_req)
|
||||||
frontend.io.cpu.req.bits := ClientDmaRequest(
|
frontend.io.cpu.req.bits := ClientDmaRequest(
|
||||||
cmd = Mux(prefetch, DmaRequest.DMA_CMD_PFR, DmaRequest.DMA_CMD_COPY),
|
cmd = Mux(prefetch, DMA_CMD_PFR, DMA_CMD_COPY),
|
||||||
src_start = sourceAddrs(testIdx),
|
src_start = sourceAddrs(testIdx),
|
||||||
dst_start = destAddrs(testIdx),
|
dst_start = destAddrs(testIdx),
|
||||||
segment_size = transferLengths(testIdx))
|
segment_size = transferLengths(testIdx))
|
||||||
|
Loading…
Reference in New Issue
Block a user