diff --git a/groundtest/src/main/scala/dmatest.scala b/groundtest/src/main/scala/dmatest.scala index 921490be..49908b9a 100644 --- a/groundtest/src/main/scala/dmatest.scala +++ b/groundtest/src/main/scala/dmatest.scala @@ -27,6 +27,28 @@ case object DmaTestDataStride extends Field[Int] case object DmaStreamTestSettings extends Field[DmaStreamTestConfig] +class DmaStatusReg(implicit val p: Parameters) extends Module + with HasDmaParameters with HasTileLinkParameters { + + val io = new Bundle { + val csr = (new RoCCCSRs).flip + val incr_outstanding = Bool(INPUT) + val xact_outstanding = Bool(OUTPUT) + val resp_status = UInt(OUTPUT, dmaStatusBits) + } + + val status_reg = Reg(UInt(width = dmaStatusBits)) + + val outstanding_cnt = TwoWayCounter( + io.incr_outstanding, io.csr.wen, tlMaxClientXacts) + + when (io.csr.wen) { status_reg := io.csr.wdata } + + io.xact_outstanding := outstanding_cnt > UInt(0) + io.resp_status := status_reg + io.csr.rdata(0) := status_reg +} + class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p) with HasDmaParameters with HasCoreParameters with HasAddrMapParameters { disablePorts(cache = false, mem = false, ptw = false) @@ -64,6 +86,10 @@ class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p) io.ptw <> frontend.io.ptw io.mem <> 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)) io.cache.req.valid := (state === s_setup_req) || (state === s_check_req) @@ -84,7 +110,9 @@ class DmaStreamTest(implicit p: Parameters) extends GroundTest()(p) state := Mux(state === s_stream_out, s_stream_in, s_stream_wait) } - val dma_done = (state === s_stream_wait) && !frontend.io.busy + val dma_done = (state === s_stream_wait) && + !frontend.io.busy && !status_reg.io.xact_outstanding + when (dma_done) { state := s_check_req } val resp_data = io.cache.resp.bits.data(conf.size * 8 - 1, 0) @@ -134,6 +162,12 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p) io.ptw <> frontend.io.ptw io.mem <> 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 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 @@ -162,7 +196,7 @@ class DmaTest(implicit p: Parameters) extends GroundTest()(p) when (frontend.io.cpu.req.fire()) { state := s_copy_wait } - when (state === s_copy_wait && !frontend.io.busy) { + when (state === s_copy_wait && dma_done) { req_addr := destAddrs(testIdx) req_data := UInt(dataStart) bytes_left := transferLengths(testIdx) diff --git a/groundtest/src/main/scala/tile.scala b/groundtest/src/main/scala/tile.scala index b25850e9..d8b862f5 100644 --- a/groundtest/src/main/scala/tile.scala +++ b/groundtest/src/main/scala/tile.scala @@ -9,6 +9,7 @@ import cde.{Parameters, Field} case object BuildGroundTest extends Field[(Int, Parameters) => GroundTest] case object GroundTestMaxXacts extends Field[Int] +case object GroundTestCSRs extends Field[Seq[Int]] /** A "cache" that responds to probe requests with a release indicating * the block is not present */ @@ -81,6 +82,7 @@ class CSRHandler(implicit val p: Parameters) extends Module { val io = new Bundle { val finished = Bool(INPUT) val csr = new SmiIO(csrDataBits, csrAddrBits).flip + val rocc = new RoCCCSRs } val csr_resp_valid = Reg(Bool()) // Don't reset @@ -90,15 +92,31 @@ class CSRHandler(implicit val p: Parameters) extends Module { io.csr.resp.valid := csr_resp_valid io.csr.resp.bits := csr_resp_data + val req = io.csr.req.bits + val csr_list = p(GroundTestCSRs) + val rocc_csr = csr_list.map(num => req.addr === UInt(num)) + .foldLeft(Bool(false))(_ || _) + + val default_csr_rdata = Mux(req.addr === UInt(CSRs.mtohost), io.finished, req.data) + val csr_rdata = csr_list.zipWithIndex.foldLeft(default_csr_rdata) { + (res, pair) => pair match { + case (csrnum, i) => Mux( + req.addr === UInt(csrnum), io.rocc.rdata(i), res) + } + } + when (io.csr.req.fire()) { - val req = io.csr.req.bits csr_resp_valid := Bool(true) - csr_resp_data := Mux(req.addr === UInt(CSRs.mtohost), io.finished, req.data) + csr_resp_data := csr_rdata } when (io.csr.resp.fire()) { csr_resp_valid := Bool(false) } + + io.rocc.waddr := req.addr + io.rocc.wdata := req.data + io.rocc.wen := io.csr.req.valid && req.rw && rocc_csr } class GroundTestIO(implicit p: Parameters) extends ParameterizedBundle()(p) { @@ -106,6 +124,7 @@ class GroundTestIO(implicit p: Parameters) extends ParameterizedBundle()(p) { val mem = new ClientUncachedTileLinkIO val dma = new DmaIO val ptw = new TLBPTWIO + val csr = (new RoCCCSRs).flip val finished = Bool(OUTPUT) } @@ -143,6 +162,9 @@ class GroundTestTile(id: Int, resetSignal: Bool) val csr = Module(new CSRHandler) csr.io.finished := test.io.finished csr.io.csr <> io.host.csr + if (!p(GroundTestCSRs).isEmpty) { + test.io.csr <> csr.io.rocc + } val ptw = Module(new DummyPTW(2)) ptw.io.requestors(0) <> test.io.ptw