blob: 826444f49691fd123637b9b0de67f6a0bc86f16c [file] [log] [blame]
package dma
import spinal.core._
import spinal.core.sim._
import spinal.lib._
import spinal.lib.bus.amba4.axi._
// import spinal.lib.bus.amba4.axi.sim._
import spinal.lib.sim._
import scala.collection.mutable
object DmaControllerSim extends App {
val dmaConfig = DmaConfig(
addressWidth = 32,
burstLen = 8,
bufDepth = 32,
dataWidth = 32,
xySizeMax = 256
)
def runDma(
dut: DmaController,
axiMem: AxiMemorySim,
sar: Int,
dar: Int,
xsize: Int,
ysize: Int,
srcystep: Int,
dstystep: Int
): Unit = {
val queue = mutable.Queue[Int]()
dut.io.ctrl.start #= false
dut.io.ctrl.halt #= false
dut.io.param.sar #= sar
dut.io.param.dar #= dar
dut.io.param.xsize #= xsize // At least bus byte size
dut.io.param.ysize #= ysize
dut.io.param.srcystep #= srcystep
dut.io.param.dstystep #= dstystep
dut.io.param.llr #= 0
dut.io.param.bf #= true
dut.io.param.cf #= true
sleep(0) // Make io.param assignment effective
// val axiMem = AxiMemorySim(
// dut.io.axi,
// dut.clockDomain,
// AxiMemorySimConfig(writeResponseDelay = 0)
// )
// Prepare memory data
val srcBeginAddr = dut.io.param.sar.toLong
val srcRowGap = dut.io.param.xsize.toInt + dut.io.param.srcystep.toInt
val rowSize = dut.io.param.xsize.toInt
for (y <- 0 until dut.io.param.ysize.toInt) {
for (x <- 0 until dut.io.param.xsize.toInt) {
val inc = y * srcRowGap + x
val d = (y * rowSize + x) % 128
val addr = srcBeginAddr + inc
axiMem.memory.write(addr, d.toByte)
println(f"prepare: addr=$addr, data=${d}=${d}%x")
queue.enqueue(d)
}
}
dut.clockDomain.waitSampling(10)
dut.io.ctrl.start #= true
axiMem.start()
dut.clockDomain.waitSampling()
dut.io.ctrl.start #= false
waitUntil(dut.io.ctrl.done.toBoolean)
dut.clockDomain.waitSampling(2)
val dstBeginAddr = dut.io.param.dar.toLong
val dstRowGap = dut.io.param.xsize.toInt + dut.io.param.dstystep.toInt
for (y <- 0 until dut.io.param.ysize.toInt) {
for (x <- 0 until dut.io.param.xsize.toInt) {
val inc = y * dstRowGap + x
val addr = dstBeginAddr + inc
val b = axiMem.memory.read(addr)
println(f"check: addr=$addr, data=${b.toInt}=${b.toInt}%x")
val t = queue.dequeue()
assert(b.toInt == t, s"${b.toInt}==${t} assert failed")
}
}
}
SimConfig.withWave
.compile(new DmaController(dmaConfig))
.doSim { dut =>
val axiMem = AxiMemorySim(
dut.io.axi,
dut.clockDomain,
AxiMemorySimConfig(writeResponseDelay = 0)
)
dut.clockDomain.forkStimulus(5)
val sar = 4091
val dar = 8183
val xsize = 57 // At least twice bus byte size, minimum burst length is 2
val ysize = 2
val srcystep = 5
val dstystep = 9
runDma(
dut,
axiMem,
sar,
dar,
xsize,
ysize,
srcystep,
dstystep
)
// dut.clockDomain.waitSampling(2)
// sar = 8183
// dar = 4091
// // xsize = 57 // At least bus byte size
// // ysize = 2
// // srcystep = 5
// // dstystep = 9
// runDma(
// dut,
// axiMem,
// sar,
// dar,
// xsize,
// ysize,
// srcystep,
// dstystep
// )
}
}